blob: 7637babcd262cbf3eebe14f9ea87d1a929e8f9c2 [file] [log] [blame]
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001/*
Maxim Levitsky11b64d32010-09-06 18:26:11 -03002 * driver for ENE KB3926 B/C/D/E/F CIR (pnp id: ENE0XXX)
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03003 *
4 * Copyright (C) 2010 Maxim Levitsky <maximlevitsky@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 * USA
Maxim Levitsky11b64d32010-09-06 18:26:11 -030020 *
21 * Special thanks to:
22 * Sami R. <maesesami@gmail.com> for lot of help in debugging and therefore
23 * bringing to life support for transmission & learning mode.
24 *
25 * Charlie Andrews <charliethepilot@googlemail.com> for lots of help in
26 * bringing up the support of new firmware buffer that is popular
27 * on latest notebooks
28 *
29 * ENE for partial device documentation
30 *
Maxim Levitsky9ea53b72010-07-31 11:59:25 -030031 */
32
33#include <linux/kernel.h>
34#include <linux/module.h>
35#include <linux/pnp.h>
36#include <linux/io.h>
37#include <linux/interrupt.h>
38#include <linux/sched.h>
Maxim Levitsky931e39a2010-07-31 11:59:26 -030039#include <linux/slab.h>
40#include <linux/input.h>
41#include <media/ir-core.h>
42#include <media/ir-common.h>
43#include "ene_ir.h"
Maxim Levitsky9ea53b72010-07-31 11:59:25 -030044
Maxim Levitsky11b64d32010-09-06 18:26:11 -030045static int sample_period;
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -030046static bool learning_mode_force;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -030047static int debug;
Maxim Levitsky11b64d32010-09-06 18:26:11 -030048static bool txsim;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -030049
Maxim Levitsky11b64d32010-09-06 18:26:11 -030050static void ene_set_reg_addr(struct ene_device *dev, u16 reg)
Maxim Levitsky9ea53b72010-07-31 11:59:25 -030051{
Maxim Levitsky9ea53b72010-07-31 11:59:25 -030052 outb(reg >> 8, dev->hw_io + ENE_ADDR_HI);
53 outb(reg & 0xFF, dev->hw_io + ENE_ADDR_LO);
Maxim Levitsky11b64d32010-09-06 18:26:11 -030054}
Maxim Levitsky9ea53b72010-07-31 11:59:25 -030055
Maxim Levitsky11b64d32010-09-06 18:26:11 -030056/* read a hardware register */
57static u8 ene_read_reg(struct ene_device *dev, u16 reg)
58{
59 u8 retval;
60 ene_set_reg_addr(dev, reg);
61 retval = inb(dev->hw_io + ENE_IO);
62 dbg_regs("reg %04x == %02x", reg, retval);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -030063 return retval;
64}
65
66/* write a hardware register */
Maxim Levitsky11b64d32010-09-06 18:26:11 -030067static void ene_write_reg(struct ene_device *dev, u16 reg, u8 value)
Maxim Levitsky9ea53b72010-07-31 11:59:25 -030068{
Maxim Levitsky11b64d32010-09-06 18:26:11 -030069 dbg_regs("reg %04x <- %02x", reg, value);
70 ene_set_reg_addr(dev, reg);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -030071 outb(value, dev->hw_io + ENE_IO);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -030072}
73
Maxim Levitsky11b64d32010-09-06 18:26:11 -030074/* Set bits in hardware register */
75static void ene_set_reg_mask(struct ene_device *dev, u16 reg, u8 mask)
Maxim Levitsky9ea53b72010-07-31 11:59:25 -030076{
Maxim Levitsky11b64d32010-09-06 18:26:11 -030077 dbg_regs("reg %04x |= %02x", reg, mask);
78 ene_set_reg_addr(dev, reg);
79 outb(inb(dev->hw_io + ENE_IO) | mask, dev->hw_io + ENE_IO);
80}
Maxim Levitsky9ea53b72010-07-31 11:59:25 -030081
Maxim Levitsky11b64d32010-09-06 18:26:11 -030082/* Clear bits in hardware register */
83static void ene_clear_reg_mask(struct ene_device *dev, u16 reg, u8 mask)
84{
85 dbg_regs("reg %04x &= ~%02x ", reg, mask);
86 ene_set_reg_addr(dev, reg);
87 outb(inb(dev->hw_io + ENE_IO) & ~mask, dev->hw_io + ENE_IO);
88}
Maxim Levitsky9ea53b72010-07-31 11:59:25 -030089
Maxim Levitsky11b64d32010-09-06 18:26:11 -030090/* A helper to set/clear a bit in register according to boolean variable */
91static void ene_set_clear_reg_mask(struct ene_device *dev, u16 reg, u8 mask,
92 bool set)
93{
94 if (set)
95 ene_set_reg_mask(dev, reg, mask);
96 else
97 ene_clear_reg_mask(dev, reg, mask);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -030098}
99
100/* detect hardware features */
101static int ene_hw_detect(struct ene_device *dev)
102{
103 u8 chip_major, chip_minor;
104 u8 hw_revision, old_ver;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300105 u8 fw_reg2, fw_reg1;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300106
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300107 ene_clear_reg_mask(dev, ENE_ECSTS, ENE_ECSTS_RSRVD);
108 chip_major = ene_read_reg(dev, ENE_ECVER_MAJOR);
109 chip_minor = ene_read_reg(dev, ENE_ECVER_MINOR);
110 ene_set_reg_mask(dev, ENE_ECSTS, ENE_ECSTS_RSRVD);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300111
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300112 hw_revision = ene_read_reg(dev, ENE_ECHV);
113 old_ver = ene_read_reg(dev, ENE_HW_VER_OLD);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300114
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300115 dev->pll_freq = (ene_read_reg(dev, ENE_PLLFRH) << 4) +
116 (ene_read_reg(dev, ENE_PLLFRL) >> 4);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300117
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300118 if (sample_period != ENE_DEFAULT_SAMPLE_PERIOD)
119 dev->rx_period_adjust =
120 dev->pll_freq == ENE_DEFAULT_PLL_FREQ ? 2 : 4;
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300121
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300122 if (hw_revision == 0xFF) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300123 ene_warn("device seems to be disabled");
124 ene_warn("send a mail to lirc-list@lists.sourceforge.net");
125 ene_warn("please attach output of acpidump and dmidecode");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300126 return -ENODEV;
127 }
128
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300129 ene_notice("chip is 0x%02x%02x - kbver = 0x%02x, rev = 0x%02x",
130 chip_major, chip_minor, old_ver, hw_revision);
131
132 ene_notice("PLL freq = %d", dev->pll_freq);
133
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300134 if (chip_major == 0x33) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300135 ene_warn("chips 0x33xx aren't supported");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300136 return -ENODEV;
137 }
138
139 if (chip_major == 0x39 && chip_minor == 0x26 && hw_revision == 0xC0) {
140 dev->hw_revision = ENE_HW_C;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300141 ene_notice("KB3926C detected");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300142 } else if (old_ver == 0x24 && hw_revision == 0xC0) {
143 dev->hw_revision = ENE_HW_B;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300144 ene_notice("KB3926B detected");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300145 } else {
146 dev->hw_revision = ENE_HW_D;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300147 ene_notice("KB3926D or higher detected");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300148 }
149
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300150 /* detect features hardware supports */
151 if (dev->hw_revision < ENE_HW_C)
152 return 0;
153
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300154 fw_reg1 = ene_read_reg(dev, ENE_FW1);
155 fw_reg2 = ene_read_reg(dev, ENE_FW2);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300156
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300157 ene_notice("Firmware regs: %02x %02x", fw_reg1, fw_reg2);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300158
Maxim Levitskya06423c2010-10-15 13:06:37 -0300159 dev->hw_use_gpio_0a = !!(fw_reg2 & ENE_FW2_GP0A);
160 dev->hw_learning_and_tx_capable = !!(fw_reg2 & ENE_FW2_LEARNING);
161 dev->hw_extra_buffer = !!(fw_reg1 & ENE_FW1_HAS_EXTRA_BUF);
162
163 if (dev->hw_learning_and_tx_capable)
164 dev->hw_fan_input = !!(fw_reg2 & ENE_FW2_FAN_INPUT);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300165
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300166 ene_notice("Hardware features:");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300167
168 if (dev->hw_learning_and_tx_capable) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300169 ene_notice("* Supports transmitting & learning mode");
170 ene_notice(" This feature is rare and therefore,");
171 ene_notice(" you are welcome to test it,");
172 ene_notice(" and/or contact the author via:");
173 ene_notice(" lirc-list@lists.sourceforge.net");
174 ene_notice(" or maximlevitsky@gmail.com");
175
176 ene_notice("* Uses GPIO %s for IR raw input",
177 dev->hw_use_gpio_0a ? "40" : "0A");
178
179 if (dev->hw_fan_input)
180 ene_notice("* Uses unused fan feedback input as source"
181 " of demodulated IR data");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300182 }
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300183
184 if (!dev->hw_fan_input)
185 ene_notice("* Uses GPIO %s for IR demodulated input",
186 dev->hw_use_gpio_0a ? "0A" : "40");
187
188 if (dev->hw_extra_buffer)
189 ene_notice("* Uses new style input buffer");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300190 return 0;
191}
192
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300193/* Read properities of hw sample buffer */
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -0300194static void ene_rx_setup_hw_buffer(struct ene_device *dev)
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300195{
196 u16 tmp;
197
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -0300198 ene_rx_read_hw_pointer(dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300199 dev->r_pointer = dev->w_pointer;
200
201 if (!dev->hw_extra_buffer) {
202 dev->buffer_len = ENE_FW_PACKET_SIZE * 2;
203 return;
204 }
205
206 tmp = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER);
207 tmp |= ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER+1) << 8;
208 dev->extra_buf1_address = tmp;
209
210 dev->extra_buf1_len = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 2);
211
212 tmp = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 3);
213 tmp |= ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 4) << 8;
214 dev->extra_buf2_address = tmp;
215
216 dev->extra_buf2_len = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 5);
217
218 dev->buffer_len = dev->extra_buf1_len + dev->extra_buf2_len + 8;
219
220 ene_notice("Hardware uses 2 extended buffers:");
221 ene_notice(" 0x%04x - len : %d", dev->extra_buf1_address,
222 dev->extra_buf1_len);
223 ene_notice(" 0x%04x - len : %d", dev->extra_buf2_address,
224 dev->extra_buf2_len);
225
226 ene_notice("Total buffer len = %d", dev->buffer_len);
227
228 if (dev->buffer_len > 64 || dev->buffer_len < 16)
229 goto error;
230
231 if (dev->extra_buf1_address > 0xFBFC ||
232 dev->extra_buf1_address < 0xEC00)
233 goto error;
234
235 if (dev->extra_buf2_address > 0xFBFC ||
236 dev->extra_buf2_address < 0xEC00)
237 goto error;
238
239 if (dev->r_pointer > dev->buffer_len)
240 goto error;
241
242 ene_set_reg_mask(dev, ENE_FW1, ENE_FW1_EXTRA_BUF_HND);
243 return;
244error:
245 ene_warn("Error validating extra buffers, device probably won't work");
246 dev->hw_extra_buffer = false;
247 ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_EXTRA_BUF_HND);
248}
249
250
251/* Restore the pointers to extra buffers - to make module reload work*/
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -0300252static void ene_rx_restore_hw_buffer(struct ene_device *dev)
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300253{
254 if (!dev->hw_extra_buffer)
255 return;
256
257 ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 0,
258 dev->extra_buf1_address & 0xFF);
259 ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 1,
260 dev->extra_buf1_address >> 8);
261 ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 2, dev->extra_buf1_len);
262
263 ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 3,
264 dev->extra_buf2_address & 0xFF);
265 ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 4,
266 dev->extra_buf2_address >> 8);
267 ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 5,
268 dev->extra_buf2_len);
269 ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_EXTRA_BUF_HND);
270}
271
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -0300272/* Read hardware write pointer */
273static void ene_rx_read_hw_pointer(struct ene_device *dev)
274{
275 if (dev->hw_extra_buffer)
276 dev->w_pointer = ene_read_reg(dev, ENE_FW_RX_POINTER);
277 else
278 dev->w_pointer = ene_read_reg(dev, ENE_FW2)
279 & ENE_FW2_BUF_WPTR ? 0 : ENE_FW_PACKET_SIZE;
280
281 dbg_verbose("RB: HW write pointer: %02x, driver read pointer: %02x",
282 dev->w_pointer, dev->r_pointer);
283}
284
285/* Gets address of next sample from HW ring buffer */
286static int ene_rx_get_sample_reg(struct ene_device *dev)
287{
288 int r_pointer;
289
290 if (dev->r_pointer == dev->w_pointer) {
291 dbg_verbose("RB: hit end, try update w_pointer");
292 ene_rx_read_hw_pointer(dev);
293 }
294
295 if (dev->r_pointer == dev->w_pointer) {
296 dbg_verbose("RB: end of data at %d", dev->r_pointer);
297 return 0;
298 }
299
300 dbg_verbose("RB: reading at offset %d", dev->r_pointer);
301 r_pointer = dev->r_pointer;
302
303 dev->r_pointer++;
304 if (dev->r_pointer == dev->buffer_len)
305 dev->r_pointer = 0;
306
307 dbg_verbose("RB: next read will be from offset %d", dev->r_pointer);
308
309 if (r_pointer < 8) {
310 dbg_verbose("RB: read at main buffer at %d", r_pointer);
311 return ENE_FW_SAMPLE_BUFFER + r_pointer;
312 }
313
314 r_pointer -= 8;
315
316 if (r_pointer < dev->extra_buf1_len) {
317 dbg_verbose("RB: read at 1st extra buffer at %d", r_pointer);
318 return dev->extra_buf1_address + r_pointer;
319 }
320
321 r_pointer -= dev->extra_buf1_len;
322
323 if (r_pointer < dev->extra_buf2_len) {
324 dbg_verbose("RB: read at 2nd extra buffer at %d", r_pointer);
325 return dev->extra_buf2_address + r_pointer;
326 }
327
328 dbg("attempt to read beyong ring bufer end");
329 return 0;
330}
331
332/* Sense current received carrier */
333void ene_rx_sense_carrier(struct ene_device *dev)
334{
335 DEFINE_IR_RAW_EVENT(ev);
336
337 int carrier, duty_cycle;
338 int period = ene_read_reg(dev, ENE_CIRCAR_PRD);
339 int hperiod = ene_read_reg(dev, ENE_CIRCAR_HPRD);
340
341 if (!(period & ENE_CIRCAR_PRD_VALID))
342 return;
343
344 period &= ~ENE_CIRCAR_PRD_VALID;
345
346 if (!period)
347 return;
348
349 dbg("RX: hardware carrier period = %02x", period);
350 dbg("RX: hardware carrier pulse period = %02x", hperiod);
351
352 carrier = 2000000 / period;
353 duty_cycle = (hperiod * 100) / period;
354 dbg("RX: sensed carrier = %d Hz, duty cycle %d%%",
355 carrier, duty_cycle);
356 if (dev->carrier_detect_enabled) {
357 ev.carrier_report = true;
358 ev.carrier = carrier;
359 ev.duty_cycle = duty_cycle;
360 ir_raw_event_store(dev->idev, &ev);
361 }
362}
363
364/* this enables/disables the CIR RX engine */
365static void ene_rx_enable_cir_engine(struct ene_device *dev, bool enable)
366{
367 ene_set_clear_reg_mask(dev, ENE_CIRCFG,
368 ENE_CIRCFG_RX_EN | ENE_CIRCFG_RX_IRQ, enable);
369}
370
371/* this selects input for CIR engine. Ether GPIO 0A or GPIO40*/
372static void ene_rx_select_input(struct ene_device *dev, bool gpio_0a)
373{
374 ene_set_clear_reg_mask(dev, ENE_CIRCFG2, ENE_CIRCFG2_GPIO0A, gpio_0a);
375}
376
377/*
378 * this enables alternative input via fan tachometer sensor and bypasses
379 * the hw CIR engine
380 */
381static void ene_rx_enable_fan_input(struct ene_device *dev, bool enable)
382{
383 if (!dev->hw_fan_input)
384 return;
385
386 if (!enable)
387 ene_write_reg(dev, ENE_FAN_AS_IN1, 0);
388 else {
389 ene_write_reg(dev, ENE_FAN_AS_IN1, ENE_FAN_AS_IN1_EN);
390 ene_write_reg(dev, ENE_FAN_AS_IN2, ENE_FAN_AS_IN2_EN);
391 }
392}
393
394/* setup the receiver for RX*/
395static void ene_rx_setup(struct ene_device *dev)
396{
397 bool learning_mode = dev->learning_mode_enabled ||
398 dev->carrier_detect_enabled;
399 int sample_period_adjust = 0;
400
401 dbg("RX: setup receiver, learning mode = %d", learning_mode);
402
403
404 /* This selects RLC input and clears CFG2 settings */
405 ene_write_reg(dev, ENE_CIRCFG2, 0x00);
406
407 /* set sample period*/
408 if (sample_period == ENE_DEFAULT_SAMPLE_PERIOD)
409 sample_period_adjust =
410 dev->pll_freq == ENE_DEFAULT_PLL_FREQ ? 1 : 2;
411
412 ene_write_reg(dev, ENE_CIRRLC_CFG,
413 (sample_period + sample_period_adjust) |
414 ENE_CIRRLC_CFG_OVERFLOW);
415 /* revB doesn't support inputs */
416 if (dev->hw_revision < ENE_HW_C)
417 goto select_timeout;
418
419 if (learning_mode) {
420
421 WARN_ON(!dev->hw_learning_and_tx_capable);
422
423 /* Enable the opposite of the normal input
424 That means that if GPIO40 is normally used, use GPIO0A
425 and vice versa.
426 This input will carry non demodulated
427 signal, and we will tell the hw to demodulate it itself */
428 ene_rx_select_input(dev, !dev->hw_use_gpio_0a);
429 dev->rx_fan_input_inuse = false;
430
431 /* Enable carrier demodulation */
432 ene_set_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_CARR_DEMOD);
433
434 /* Enable carrier detection */
435 ene_write_reg(dev, ENE_CIRCAR_PULS, 0x63);
436 ene_set_clear_reg_mask(dev, ENE_CIRCFG2, ENE_CIRCFG2_CARR_DETECT,
437 dev->carrier_detect_enabled || debug);
438 } else {
439 if (dev->hw_fan_input)
440 dev->rx_fan_input_inuse = true;
441 else
442 ene_rx_select_input(dev, dev->hw_use_gpio_0a);
443
444 /* Disable carrier detection & demodulation */
445 ene_clear_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_CARR_DEMOD);
446 ene_clear_reg_mask(dev, ENE_CIRCFG2, ENE_CIRCFG2_CARR_DETECT);
447 }
448
449select_timeout:
450 if (dev->rx_fan_input_inuse) {
451 dev->props->rx_resolution = MS_TO_NS(ENE_FW_SAMPLE_PERIOD_FAN);
452
453 /* Fan input doesn't support timeouts, it just ends the
454 input with a maximum sample */
455 dev->props->min_timeout = dev->props->max_timeout =
456 MS_TO_NS(ENE_FW_SMPL_BUF_FAN_MSK *
457 ENE_FW_SAMPLE_PERIOD_FAN);
458 } else {
459 dev->props->rx_resolution = MS_TO_NS(sample_period);
460
461 /* Theoreticly timeout is unlimited, but we cap it
462 * because it was seen that on one device, it
463 * would stop sending spaces after around 250 msec.
464 * Besides, this is close to 2^32 anyway and timeout is u32.
465 */
466 dev->props->min_timeout = MS_TO_NS(127 * sample_period);
467 dev->props->max_timeout = MS_TO_NS(200000);
468 }
469
470 if (dev->hw_learning_and_tx_capable)
471 dev->props->tx_resolution = MS_TO_NS(sample_period);
472
473 if (dev->props->timeout > dev->props->max_timeout)
474 dev->props->timeout = dev->props->max_timeout;
475 if (dev->props->timeout < dev->props->min_timeout)
476 dev->props->timeout = dev->props->min_timeout;
477}
478
479/* Enable the device for receive */
480static void ene_rx_enable(struct ene_device *dev)
481{
482 u8 reg_value;
483
484 /* Enable system interrupt */
485 if (dev->hw_revision < ENE_HW_C) {
486 ene_write_reg(dev, ENEB_IRQ, dev->irq << 1);
487 ene_write_reg(dev, ENEB_IRQ_UNK1, 0x01);
488 } else {
489 reg_value = ene_read_reg(dev, ENE_IRQ) & 0xF0;
490 reg_value |= ENE_IRQ_UNK_EN;
491 reg_value &= ~ENE_IRQ_STATUS;
492 reg_value |= (dev->irq & ENE_IRQ_MASK);
493 ene_write_reg(dev, ENE_IRQ, reg_value);
494 }
495
496 /* Enable inputs */
497 ene_rx_enable_fan_input(dev, dev->rx_fan_input_inuse);
498 ene_rx_enable_cir_engine(dev, !dev->rx_fan_input_inuse);
499
500 /* ack any pending irqs - just in case */
501 ene_irq_status(dev);
502
503 /* enable firmware bits */
504 ene_set_reg_mask(dev, ENE_FW1, ENE_FW1_ENABLE | ENE_FW1_IRQ);
505
506 /* enter idle mode */
507 ir_raw_event_set_idle(dev->idev, true);
508 dev->rx_enabled = true;
509}
510
511/* Disable the device receiver */
512static void ene_rx_disable(struct ene_device *dev)
513{
514 /* disable inputs */
515 ene_rx_enable_cir_engine(dev, false);
516 ene_rx_enable_fan_input(dev, false);
517
518 /* disable hardware IRQ and firmware flag */
519 ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_ENABLE | ENE_FW1_IRQ);
520
521 ir_raw_event_set_idle(dev->idev, true);
522 dev->rx_enabled = false;
523}
524
525/* This resets the receiver. Usefull to stop stream of spaces at end of
526 * transmission
527 */
528static void ene_rx_reset(struct ene_device *dev)
529{
530 ene_clear_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_RX_EN);
531 ene_set_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_RX_EN);
532}
533
534/* Set up the TX carrier frequency and duty cycle */
535static void ene_tx_set_carrier(struct ene_device *dev)
536{
537 u8 tx_puls_width;
538 unsigned long flags;
539
540 spin_lock_irqsave(&dev->hw_lock, flags);
541
542 ene_set_clear_reg_mask(dev, ENE_CIRCFG,
543 ENE_CIRCFG_TX_CARR, dev->tx_period > 0);
544
545 if (!dev->tx_period)
546 goto unlock;
547
548 BUG_ON(dev->tx_duty_cycle >= 100 || dev->tx_duty_cycle <= 0);
549
550 tx_puls_width = dev->tx_period / (100 / dev->tx_duty_cycle);
551
552 if (!tx_puls_width)
553 tx_puls_width = 1;
554
555 dbg("TX: pulse distance = %d * 500 ns", dev->tx_period);
556 dbg("TX: pulse width = %d * 500 ns", tx_puls_width);
557
558 ene_write_reg(dev, ENE_CIRMOD_PRD, dev->tx_period | ENE_CIRMOD_PRD_POL);
559 ene_write_reg(dev, ENE_CIRMOD_HPRD, tx_puls_width);
560unlock:
561 spin_unlock_irqrestore(&dev->hw_lock, flags);
562}
563
564/* Enable/disable transmitters */
565static void ene_tx_set_transmitters(struct ene_device *dev)
566{
567 unsigned long flags;
568
569 spin_lock_irqsave(&dev->hw_lock, flags);
570 ene_set_clear_reg_mask(dev, ENE_GPIOFS8, ENE_GPIOFS8_GPIO41,
571 !!(dev->transmitter_mask & 0x01));
572 ene_set_clear_reg_mask(dev, ENE_GPIOFS1, ENE_GPIOFS1_GPIO0D,
573 !!(dev->transmitter_mask & 0x02));
574 spin_unlock_irqrestore(&dev->hw_lock, flags);
575}
576
577/* prepare transmission */
578static void ene_tx_enable(struct ene_device *dev)
579{
580 u8 conf1 = ene_read_reg(dev, ENE_CIRCFG);
581 u8 fwreg2 = ene_read_reg(dev, ENE_FW2);
582
583 dev->saved_conf1 = conf1;
584
585 /* Show information about currently connected transmitter jacks */
586 if (fwreg2 & ENE_FW2_EMMITER1_CONN)
587 dbg("TX: Transmitter #1 is connected");
588
589 if (fwreg2 & ENE_FW2_EMMITER2_CONN)
590 dbg("TX: Transmitter #2 is connected");
591
592 if (!(fwreg2 & (ENE_FW2_EMMITER1_CONN | ENE_FW2_EMMITER2_CONN)))
593 ene_warn("TX: transmitter cable isn't connected!");
594
595 /* disable receive on revc */
596 if (dev->hw_revision == ENE_HW_C)
597 conf1 &= ~ENE_CIRCFG_RX_EN;
598
599 /* Enable TX engine */
600 conf1 |= ENE_CIRCFG_TX_EN | ENE_CIRCFG_TX_IRQ;
601 ene_write_reg(dev, ENE_CIRCFG, conf1);
602}
603
604/* end transmission */
605static void ene_tx_disable(struct ene_device *dev)
606{
607 ene_write_reg(dev, ENE_CIRCFG, dev->saved_conf1);
608 dev->tx_buffer = NULL;
609}
610
611
612/* TX one sample - must be called with dev->hw_lock*/
613static void ene_tx_sample(struct ene_device *dev)
614{
615 u8 raw_tx;
616 u32 sample;
617 bool pulse = dev->tx_sample_pulse;
618
619 if (!dev->tx_buffer) {
620 ene_warn("TX: BUG: attempt to transmit NULL buffer");
621 return;
622 }
623
624 /* Grab next TX sample */
625 if (!dev->tx_sample) {
626
627 if (dev->tx_pos == dev->tx_len) {
628 if (!dev->tx_done) {
629 dbg("TX: no more data to send");
630 dev->tx_done = true;
631 goto exit;
632 } else {
633 dbg("TX: last sample sent by hardware");
634 ene_tx_disable(dev);
635 complete(&dev->tx_complete);
636 return;
637 }
638 }
639
640 sample = dev->tx_buffer[dev->tx_pos++];
641 dev->tx_sample_pulse = !dev->tx_sample_pulse;
642
643 dev->tx_sample = DIV_ROUND_CLOSEST(sample, sample_period);
644
645 if (!dev->tx_sample)
646 dev->tx_sample = 1;
647 }
648
649 raw_tx = min(dev->tx_sample , (unsigned int)ENE_CIRRLC_OUT_MASK);
650 dev->tx_sample -= raw_tx;
651
652 dbg("TX: sample %8d (%s)", raw_tx * sample_period,
653 pulse ? "pulse" : "space");
654 if (pulse)
655 raw_tx |= ENE_CIRRLC_OUT_PULSE;
656
657 ene_write_reg(dev,
658 dev->tx_reg ? ENE_CIRRLC_OUT1 : ENE_CIRRLC_OUT0, raw_tx);
659
660 dev->tx_reg = !dev->tx_reg;
661exit:
662 /* simulate TX done interrupt */
663 if (txsim)
664 mod_timer(&dev->tx_sim_timer, jiffies + HZ / 500);
665}
666
667/* timer to simulate tx done interrupt */
668static void ene_tx_irqsim(unsigned long data)
669{
670 struct ene_device *dev = (struct ene_device *)data;
671 unsigned long flags;
672
673 spin_lock_irqsave(&dev->hw_lock, flags);
674 ene_tx_sample(dev);
675 spin_unlock_irqrestore(&dev->hw_lock, flags);
676}
677
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300678
679/* read irq status and ack it */
680static int ene_irq_status(struct ene_device *dev)
681{
682 u8 irq_status;
683 u8 fw_flags1, fw_flags2;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300684 int retval = 0;
685
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300686 fw_flags2 = ene_read_reg(dev, ENE_FW2);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300687
688 if (dev->hw_revision < ENE_HW_C) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300689 irq_status = ene_read_reg(dev, ENEB_IRQ_STATUS);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300690
691 if (!(irq_status & ENEB_IRQ_STATUS_IR))
692 return 0;
693
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300694 ene_clear_reg_mask(dev, ENEB_IRQ_STATUS, ENEB_IRQ_STATUS_IR);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300695 return ENE_IRQ_RX;
696 }
697
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300698 irq_status = ene_read_reg(dev, ENE_IRQ);
699 if (!(irq_status & ENE_IRQ_STATUS))
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300700 return 0;
701
702 /* original driver does that twice - a workaround ? */
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300703 ene_write_reg(dev, ENE_IRQ, irq_status & ~ENE_IRQ_STATUS);
704 ene_write_reg(dev, ENE_IRQ, irq_status & ~ENE_IRQ_STATUS);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300705
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300706 /* check RX interrupt */
707 if (fw_flags2 & ENE_FW2_RXIRQ) {
708 retval |= ENE_IRQ_RX;
709 ene_write_reg(dev, ENE_FW2, fw_flags2 & ~ENE_FW2_RXIRQ);
710 }
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300711
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300712 /* check TX interrupt */
713 fw_flags1 = ene_read_reg(dev, ENE_FW1);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300714 if (fw_flags1 & ENE_FW1_TXIRQ) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300715 ene_write_reg(dev, ENE_FW1, fw_flags1 & ~ENE_FW1_TXIRQ);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300716 retval |= ENE_IRQ_TX;
717 }
718
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300719 return retval;
720}
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300721
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300722/* interrupt handler */
723static irqreturn_t ene_isr(int irq, void *data)
724{
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300725 u16 hw_value, reg;
726 int hw_sample, irq_status;
727 bool pulse;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300728 unsigned long flags;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300729 irqreturn_t retval = IRQ_NONE;
730 struct ene_device *dev = (struct ene_device *)data;
Maxim Levitsky46519182010-10-16 19:56:28 -0300731 DEFINE_IR_RAW_EVENT(ev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300732
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300733 spin_lock_irqsave(&dev->hw_lock, flags);
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300734
735 dbg_verbose("ISR called");
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -0300736 ene_rx_read_hw_pointer(dev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300737 irq_status = ene_irq_status(dev);
738
739 if (!irq_status)
740 goto unlock;
741
742 retval = IRQ_HANDLED;
743
744 if (irq_status & ENE_IRQ_TX) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300745 dbg_verbose("TX interrupt");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300746 if (!dev->hw_learning_and_tx_capable) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300747 dbg("TX interrupt on unsupported device!");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300748 goto unlock;
749 }
750 ene_tx_sample(dev);
751 }
752
753 if (!(irq_status & ENE_IRQ_RX))
754 goto unlock;
755
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300756 dbg_verbose("RX interrupt");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300757
Maxim Levitskye1b1ddb2010-10-16 19:56:29 -0300758 if (dev->hw_learning_and_tx_capable)
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300759 ene_rx_sense_carrier(dev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300760
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300761 /* On hardware that don't support extra buffer we need to trust
762 the interrupt and not track the read pointer */
763 if (!dev->hw_extra_buffer)
764 dev->r_pointer = dev->w_pointer == 0 ? ENE_FW_PACKET_SIZE : 0;
765
766 while (1) {
767
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -0300768 reg = ene_rx_get_sample_reg(dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300769
770 dbg_verbose("next sample to read at: %04x", reg);
771 if (!reg)
772 break;
773
774 hw_value = ene_read_reg(dev, reg);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300775
776 if (dev->rx_fan_input_inuse) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300777
778 int offset = ENE_FW_SMPL_BUF_FAN - ENE_FW_SAMPLE_BUFFER;
779
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300780 /* read high part of the sample */
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300781 hw_value |= ene_read_reg(dev, reg + offset) << 8;
782 pulse = hw_value & ENE_FW_SMPL_BUF_FAN_PLS;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300783
784 /* clear space bit, and other unused bits */
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300785 hw_value &= ENE_FW_SMPL_BUF_FAN_MSK;
786 hw_sample = hw_value * ENE_FW_SAMPLE_PERIOD_FAN;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300787
788 } else {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300789 pulse = !(hw_value & ENE_FW_SAMPLE_SPACE);
790 hw_value &= ~ENE_FW_SAMPLE_SPACE;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300791 hw_sample = hw_value * sample_period;
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300792
793 if (dev->rx_period_adjust) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300794 hw_sample *= 100;
795 hw_sample /= (100 + dev->rx_period_adjust);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300796 }
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300797 }
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300798
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300799 if (!dev->hw_extra_buffer && !hw_sample) {
800 dev->r_pointer = dev->w_pointer;
801 continue;
802 }
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300803
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300804 dbg("RX: %d (%s)", hw_sample, pulse ? "pulse" : "space");
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300805
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300806 ev.duration = MS_TO_NS(hw_sample);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300807 ev.pulse = pulse;
808 ir_raw_event_store_with_filter(dev->idev, &ev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300809 }
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300810
811 ir_raw_event_handle(dev->idev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300812unlock:
813 spin_unlock_irqrestore(&dev->hw_lock, flags);
814 return retval;
815}
816
817/* Initialize default settings */
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -0300818static void ene_setup_default_settings(struct ene_device *dev)
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300819{
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300820 dev->tx_period = 32;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300821 dev->tx_duty_cycle = 50; /*%*/
822 dev->transmitter_mask = 0x03;
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -0300823 dev->learning_mode_enabled = learning_mode_force;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300824
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300825 /* Set reasonable default timeout */
Maxim Levitskya06423c2010-10-15 13:06:37 -0300826 dev->props->timeout = MS_TO_NS(150000);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300827}
828
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -0300829/* Upload all hardware settings at once. Used at load and resume time */
830static void ene_setup_hw_settings(struct ene_device *dev)
831{
832 if (dev->hw_learning_and_tx_capable) {
833 ene_tx_set_carrier(dev);
834 ene_tx_set_transmitters(dev);
835 }
836
837 ene_rx_setup(dev);
838}
839
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300840/* outside interface: called on first open*/
841static int ene_open(void *data)
842{
843 struct ene_device *dev = (struct ene_device *)data;
844 unsigned long flags;
845
846 spin_lock_irqsave(&dev->hw_lock, flags);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300847 ene_rx_enable(dev);
848 spin_unlock_irqrestore(&dev->hw_lock, flags);
849 return 0;
850}
851
852/* outside interface: called on device close*/
853static void ene_close(void *data)
854{
855 struct ene_device *dev = (struct ene_device *)data;
856 unsigned long flags;
857 spin_lock_irqsave(&dev->hw_lock, flags);
858
859 ene_rx_disable(dev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300860 spin_unlock_irqrestore(&dev->hw_lock, flags);
861}
862
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300863/* outside interface: set transmitter mask */
864static int ene_set_tx_mask(void *data, u32 tx_mask)
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300865{
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300866 struct ene_device *dev = (struct ene_device *)data;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300867 dbg("TX: attempt to set transmitter mask %02x", tx_mask);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300868
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300869 /* invalid txmask */
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300870 if (!tx_mask || tx_mask & ~0x03) {
871 dbg("TX: invalid mask");
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300872 /* return count of transmitters */
873 return 2;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300874 }
875
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300876 dev->transmitter_mask = tx_mask;
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -0300877 ene_tx_set_transmitters(dev);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300878 return 0;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300879}
880
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300881/* outside interface : set tx carrier */
882static int ene_set_tx_carrier(void *data, u32 carrier)
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300883{
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300884 struct ene_device *dev = (struct ene_device *)data;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300885 u32 period = 2000000 / carrier;
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300886
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300887 dbg("TX: attempt to set tx carrier to %d kHz", carrier);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300888
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300889 if (period && (period > ENE_CIRMOD_PRD_MAX ||
890 period < ENE_CIRMOD_PRD_MIN)) {
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300891
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300892 dbg("TX: out of range %d-%d kHz carrier",
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -0300893 2000 / ENE_CIRMOD_PRD_MIN, 2000 / ENE_CIRMOD_PRD_MAX);
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300894 return -1;
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300895 }
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300896
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300897 dev->tx_period = period;
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -0300898 ene_tx_set_carrier(dev);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300899 return 0;
900}
901
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300902/*outside interface : set tx duty cycle */
903static int ene_set_tx_duty_cycle(void *data, u32 duty_cycle)
904{
905 struct ene_device *dev = (struct ene_device *)data;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300906 dbg("TX: setting duty cycle to %d%%", duty_cycle);
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300907 dev->tx_duty_cycle = duty_cycle;
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -0300908 ene_tx_set_carrier(dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300909 return 0;
910}
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300911
912/* outside interface: enable learning mode */
913static int ene_set_learning_mode(void *data, int enable)
914{
915 struct ene_device *dev = (struct ene_device *)data;
916 unsigned long flags;
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -0300917 if (enable == dev->learning_mode_enabled)
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300918 return 0;
919
920 spin_lock_irqsave(&dev->hw_lock, flags);
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -0300921 dev->learning_mode_enabled = enable;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300922 ene_rx_disable(dev);
923 ene_rx_setup(dev);
924 ene_rx_enable(dev);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300925 spin_unlock_irqrestore(&dev->hw_lock, flags);
926 return 0;
927}
928
Maxim Levitskye1b1ddb2010-10-16 19:56:29 -0300929static int ene_set_carrier_report(void *data, int enable)
930{
931 struct ene_device *dev = (struct ene_device *)data;
932 unsigned long flags;
933
934 if (enable == dev->carrier_detect_enabled)
935 return 0;
936
937 spin_lock_irqsave(&dev->hw_lock, flags);
938 dev->carrier_detect_enabled = enable;
939 ene_rx_disable(dev);
940 ene_rx_setup(dev);
941 ene_rx_enable(dev);
942 spin_unlock_irqrestore(&dev->hw_lock, flags);
943 return 0;
944}
945
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300946/* outside interface: enable or disable idle mode */
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -0300947static void ene_set_idle(void *data, bool idle)
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300948{
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -0300949 if (idle) {
950 ene_rx_reset((struct ene_device *)data);
951 dbg("RX: end of data");
952 }
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300953}
954
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300955/* outside interface: transmit */
956static int ene_transmit(void *data, int *buf, u32 n)
957{
958 struct ene_device *dev = (struct ene_device *)data;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300959 unsigned long flags;
960
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300961 dev->tx_buffer = buf;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300962 dev->tx_len = n / sizeof(int);
963 dev->tx_pos = 0;
964 dev->tx_reg = 0;
965 dev->tx_done = 0;
966 dev->tx_sample = 0;
967 dev->tx_sample_pulse = 0;
968
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300969 dbg("TX: %d samples", dev->tx_len);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300970
971 spin_lock_irqsave(&dev->hw_lock, flags);
972
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -0300973 ene_tx_enable(dev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300974
975 /* Transmit first two samples */
976 ene_tx_sample(dev);
977 ene_tx_sample(dev);
978
979 spin_unlock_irqrestore(&dev->hw_lock, flags);
980
981 if (wait_for_completion_timeout(&dev->tx_complete, 2 * HZ) == 0) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300982 dbg("TX: timeout");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300983 spin_lock_irqsave(&dev->hw_lock, flags);
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -0300984 ene_tx_disable(dev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300985 spin_unlock_irqrestore(&dev->hw_lock, flags);
986 } else
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300987 dbg("TX: done");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300988 return n;
989}
990
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300991/* probe entry */
992static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300993{
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300994 int error = -ENOMEM;
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300995 struct ir_dev_props *ir_props;
996 struct input_dev *input_dev;
997 struct ene_device *dev;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300998
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300999 /* allocate memory */
1000 input_dev = input_allocate_device();
1001 ir_props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001002 dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL);
1003
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001004 if (!input_dev || !ir_props || !dev)
Jiri Slaby2e75bce2010-10-01 18:13:40 -03001005 goto error1;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001006
1007 /* validate resources */
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001008 error = -ENODEV;
1009
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001010 if (!pnp_port_valid(pnp_dev, 0) ||
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001011 pnp_port_len(pnp_dev, 0) < ENE_IO_SIZE)
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001012 goto error;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001013
1014 if (!pnp_irq_valid(pnp_dev, 0))
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001015 goto error;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001016
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001017 spin_lock_init(&dev->hw_lock);
1018
1019 /* claim the resources */
1020 error = -EBUSY;
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001021 dev->hw_io = pnp_port_start(pnp_dev, 0);
1022 if (!request_region(dev->hw_io, ENE_IO_SIZE, ENE_DRIVER_NAME)) {
1023 dev->hw_io = -1;
1024 dev->irq = -1;
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001025 goto error;
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001026 }
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001027
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001028 dev->irq = pnp_irq(pnp_dev, 0);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001029 if (request_irq(dev->irq, ene_isr,
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001030 IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev)) {
1031 dev->irq = -1;
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001032 goto error;
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001033 }
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001034
1035 pnp_set_drvdata(pnp_dev, dev);
1036 dev->pnp_dev = pnp_dev;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001037
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001038 /* don't allow too short/long sample periods */
1039 if (sample_period < 5 || sample_period > 0x7F)
1040 sample_period = ENE_DEFAULT_SAMPLE_PERIOD;
1041
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001042 /* detect hardware version and features */
1043 error = ene_hw_detect(dev);
1044 if (error)
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001045 goto error;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001046
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001047 if (!dev->hw_learning_and_tx_capable && txsim) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001048 dev->hw_learning_and_tx_capable = true;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001049 setup_timer(&dev->tx_sim_timer, ene_tx_irqsim,
1050 (long unsigned int)dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001051 ene_warn("Simulation of TX activated");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001052 }
1053
Maxim Levitskya06423c2010-10-15 13:06:37 -03001054 if (!dev->hw_learning_and_tx_capable)
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -03001055 learning_mode_force = false;
Maxim Levitskya06423c2010-10-15 13:06:37 -03001056
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001057 ir_props->driver_type = RC_DRIVER_IR_RAW;
1058 ir_props->allowed_protos = IR_TYPE_ALL;
1059 ir_props->priv = dev;
1060 ir_props->open = ene_open;
1061 ir_props->close = ene_close;
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -03001062 ir_props->s_idle = ene_set_idle;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001063
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001064 dev->props = ir_props;
1065 dev->idev = input_dev;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001066
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001067 if (dev->hw_learning_and_tx_capable) {
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001068 ir_props->s_learning_mode = ene_set_learning_mode;
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001069 init_completion(&dev->tx_complete);
1070 ir_props->tx_ir = ene_transmit;
1071 ir_props->s_tx_mask = ene_set_tx_mask;
1072 ir_props->s_tx_carrier = ene_set_tx_carrier;
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001073 ir_props->s_tx_duty_cycle = ene_set_tx_duty_cycle;
Maxim Levitskye1b1ddb2010-10-16 19:56:29 -03001074 ir_props->s_carrier_report = ene_set_carrier_report;
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001075 }
1076
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -03001077 ene_rx_setup_hw_buffer(dev);
1078 ene_setup_default_settings(dev);
1079 ene_setup_hw_settings(dev);
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001080
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001081 device_set_wakeup_capable(&pnp_dev->dev, true);
1082 device_set_wakeup_enable(&pnp_dev->dev, true);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001083
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001084 if (dev->hw_learning_and_tx_capable)
1085 input_dev->name = "ENE eHome Infrared Remote Transceiver";
1086 else
1087 input_dev->name = "ENE eHome Infrared Remote Receiver";
1088
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001089 error = -ENODEV;
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001090 if (ir_input_register(input_dev, RC_MAP_RC6_MCE, ir_props,
1091 ENE_DRIVER_NAME))
1092 goto error;
1093
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001094 ene_notice("driver has been succesfully loaded");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001095 return 0;
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001096error:
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001097 if (dev && dev->irq >= 0)
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001098 free_irq(dev->irq, dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001099 if (dev && dev->hw_io >= 0)
1100 release_region(dev->hw_io, ENE_IO_SIZE);
Jiri Slaby2e75bce2010-10-01 18:13:40 -03001101error1:
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001102 input_free_device(input_dev);
1103 kfree(ir_props);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001104 kfree(dev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001105 return error;
1106}
1107
1108/* main unload function */
1109static void ene_remove(struct pnp_dev *pnp_dev)
1110{
1111 struct ene_device *dev = pnp_get_drvdata(pnp_dev);
1112 unsigned long flags;
1113
1114 spin_lock_irqsave(&dev->hw_lock, flags);
1115 ene_rx_disable(dev);
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -03001116 ene_rx_restore_hw_buffer(dev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001117 spin_unlock_irqrestore(&dev->hw_lock, flags);
1118
1119 free_irq(dev->irq, dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001120 release_region(dev->hw_io, ENE_IO_SIZE);
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001121 ir_input_unregister(dev->idev);
1122 kfree(dev->props);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001123 kfree(dev);
1124}
1125
1126/* enable wake on IR (wakes on specific button on original remote) */
1127static void ene_enable_wake(struct ene_device *dev, int enable)
1128{
1129 enable = enable && device_may_wakeup(&dev->pnp_dev->dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001130 dbg("wake on IR %s", enable ? "enabled" : "disabled");
1131 ene_set_clear_reg_mask(dev, ENE_FW1, ENE_FW1_WAKE, enable);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001132}
1133
1134#ifdef CONFIG_PM
1135static int ene_suspend(struct pnp_dev *pnp_dev, pm_message_t state)
1136{
1137 struct ene_device *dev = pnp_get_drvdata(pnp_dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001138 ene_enable_wake(dev, true);
1139
1140 /* TODO: add support for wake pattern */
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001141 return 0;
1142}
1143
1144static int ene_resume(struct pnp_dev *pnp_dev)
1145{
1146 struct ene_device *dev = pnp_get_drvdata(pnp_dev);
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -03001147 ene_setup_hw_settings(dev);
1148
1149 if (dev->rx_enabled)
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001150 ene_rx_enable(dev);
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -03001151
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001152 ene_enable_wake(dev, false);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001153 return 0;
1154}
1155#endif
1156
1157static void ene_shutdown(struct pnp_dev *pnp_dev)
1158{
1159 struct ene_device *dev = pnp_get_drvdata(pnp_dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001160 ene_enable_wake(dev, true);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001161}
1162
1163static const struct pnp_device_id ene_ids[] = {
1164 {.id = "ENE0100",},
1165 {.id = "ENE0200",},
1166 {.id = "ENE0201",},
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001167 {.id = "ENE0202",},
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001168 {},
1169};
1170
1171static struct pnp_driver ene_driver = {
1172 .name = ENE_DRIVER_NAME,
1173 .id_table = ene_ids,
1174 .flags = PNP_DRIVER_RES_DO_NOT_CHANGE,
1175
1176 .probe = ene_probe,
1177 .remove = __devexit_p(ene_remove),
1178#ifdef CONFIG_PM
1179 .suspend = ene_suspend,
1180 .resume = ene_resume,
1181#endif
1182 .shutdown = ene_shutdown,
1183};
1184
1185static int __init ene_init(void)
1186{
1187 return pnp_register_driver(&ene_driver);
1188}
1189
1190static void ene_exit(void)
1191{
1192 pnp_unregister_driver(&ene_driver);
1193}
1194
1195module_param(sample_period, int, S_IRUGO);
1196MODULE_PARM_DESC(sample_period, "Hardware sample period (50 us default)");
1197
Maxim Levitskyc29bc4d2010-10-16 19:56:30 -03001198module_param(learning_mode_force, bool, S_IRUGO);
1199MODULE_PARM_DESC(learning_mode_force, "Enable learning mode by default");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001200
1201module_param(debug, int, S_IRUGO | S_IWUSR);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001202MODULE_PARM_DESC(debug, "Debug level");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001203
1204module_param(txsim, bool, S_IRUGO);
1205MODULE_PARM_DESC(txsim,
1206 "Simulate TX features on unsupported hardware (dangerous)");
1207
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001208MODULE_DEVICE_TABLE(pnp, ene_ids);
1209MODULE_DESCRIPTION
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001210 ("Infrared input driver for KB3926B/C/D/E/F "
1211 "(aka ENE0100/ENE0200/ENE0201/ENE0202) CIR port");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001212
1213MODULE_AUTHOR("Maxim Levitsky");
1214MODULE_LICENSE("GPL");
1215
1216module_init(ene_init);
1217module_exit(ene_exit);