blob: 7880d9c72d47f54c7c8f2c91b8d60cfc8c3b522c [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;
46static bool learning_mode;
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 Levitsky11b64d32010-09-06 18:26:11 -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 dev->hw_fan_input = dev->hw_learning_and_tx_capable &&
163 (fw_reg2 & ENE_FW2_FAN_INPUT);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300164
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300165 ene_notice("Hardware features:");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300166
167 if (dev->hw_learning_and_tx_capable) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300168 ene_notice("* Supports transmitting & learning mode");
169 ene_notice(" This feature is rare and therefore,");
170 ene_notice(" you are welcome to test it,");
171 ene_notice(" and/or contact the author via:");
172 ene_notice(" lirc-list@lists.sourceforge.net");
173 ene_notice(" or maximlevitsky@gmail.com");
174
175 ene_notice("* Uses GPIO %s for IR raw input",
176 dev->hw_use_gpio_0a ? "40" : "0A");
177
178 if (dev->hw_fan_input)
179 ene_notice("* Uses unused fan feedback input as source"
180 " of demodulated IR data");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300181 }
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300182
183 if (!dev->hw_fan_input)
184 ene_notice("* Uses GPIO %s for IR demodulated input",
185 dev->hw_use_gpio_0a ? "0A" : "40");
186
187 if (dev->hw_extra_buffer)
188 ene_notice("* Uses new style input buffer");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300189 return 0;
190}
191
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300192/* Sense current received carrier */
193void ene_rx_sense_carrier(struct ene_device *dev)
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300194{
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300195 int period = ene_read_reg(dev, ENE_CIRCAR_PRD);
196 int hperiod = ene_read_reg(dev, ENE_CIRCAR_HPRD);
197 int carrier, duty_cycle;
198
199
200 if (!(period & ENE_CIRCAR_PRD_VALID))
201 return;
202
203 period &= ~ENE_CIRCAR_PRD_VALID;
204
205 if (!period)
206 return;
207
208 dbg("RX: hardware carrier period = %02x", period);
209 dbg("RX: hardware carrier pulse period = %02x", hperiod);
210
211
212 carrier = 2000000 / period;
213 duty_cycle = (hperiod * 100) / period;
214 dbg("RX: sensed carrier = %d Hz, duty cycle %d%%",
215 carrier, duty_cycle);
216
217 /* TODO: Send carrier & duty cycle to IR layer */
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300218}
219
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300220/* this enables/disables the CIR RX engine */
221static void ene_enable_cir_engine(struct ene_device *dev, bool enable)
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300222{
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300223 ene_set_clear_reg_mask(dev, ENE_CIRCFG,
224 ENE_CIRCFG_RX_EN | ENE_CIRCFG_RX_IRQ, enable);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300225}
226
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300227/* this selects input for CIR engine. Ether GPIO 0A or GPIO40*/
228static void ene_select_rx_input(struct ene_device *dev, bool gpio_0a)
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300229{
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300230 ene_set_clear_reg_mask(dev, ENE_CIRCFG2, ENE_CIRCFG2_GPIO0A, gpio_0a);
231}
232
233/*
234 * this enables alternative input via fan tachometer sensor and bypasses
235 * the hw CIR engine
236 */
237static void ene_enable_fan_input(struct ene_device *dev, bool enable)
238{
239 if (!dev->hw_fan_input)
240 return;
241
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300242 if (!enable)
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300243 ene_write_reg(dev, ENE_FAN_AS_IN1, 0);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300244 else {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300245 ene_write_reg(dev, ENE_FAN_AS_IN1, ENE_FAN_AS_IN1_EN);
246 ene_write_reg(dev, ENE_FAN_AS_IN2, ENE_FAN_AS_IN2_EN);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300247 }
248 dev->rx_fan_input_inuse = enable;
249}
250
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300251/* setup the receiver for RX*/
252static void ene_rx_setup(struct ene_device *dev)
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300253{
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300254 bool learning_mode = dev->learning_enabled ||
255 dev->carrier_detect_enabled;
256 int sample_period_adjust = 0;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300257
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300258
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300259 /* set sample period*/
260 if (sample_period == ENE_DEFAULT_SAMPLE_PERIOD)
261 sample_period_adjust =
262 dev->pll_freq == ENE_DEFAULT_PLL_FREQ ? 1 : 2;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300263
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300264 ene_write_reg(dev, ENE_CIRRLC_CFG,
265 (sample_period + sample_period_adjust) |
266 ENE_CIRRLC_CFG_OVERFLOW);
267 /* revB doesn't support inputs */
268 if (dev->hw_revision < ENE_HW_C)
269 goto select_timeout;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300270
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300271 if (learning_mode && dev->hw_learning_and_tx_capable) {
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300272
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300273 /* Enable the opposite of the normal input
274 That means that if GPIO40 is normally used, use GPIO0A
275 and vice versa.
276 This input will carry non demodulated
277 signal, and we will tell the hw to demodulate it itself */
278 ene_select_rx_input(dev, !dev->hw_use_gpio_0a);
279 dev->rx_fan_input_inuse = false;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300280
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300281 /* Enable carrier demodulation */
282 ene_set_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_CARR_DEMOD);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300283
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300284 /* Enable carrier detection */
285 ene_set_clear_reg_mask(dev, ENE_CIRCFG2, ENE_CIRCFG2_CARR_DETECT,
286 dev->carrier_detect_enabled || debug);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300287 } else {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300288 if (dev->hw_fan_input)
289 dev->rx_fan_input_inuse = true;
290 else
291 ene_select_rx_input(dev, dev->hw_use_gpio_0a);
292
293 /* Disable carrier detection & demodulation */
294 ene_clear_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_CARR_DEMOD);
295 ene_clear_reg_mask(dev, ENE_CIRCFG2, ENE_CIRCFG2_CARR_DETECT);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300296 }
297
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300298select_timeout:
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300299 if (dev->rx_fan_input_inuse) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300300 dev->props->rx_resolution = MS_TO_NS(ENE_FW_SAMPLE_PERIOD_FAN);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300301
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300302 /* Fan input doesn't support timeouts, it just ends the
303 input with a maximum sample */
304 dev->props->min_timeout = dev->props->max_timeout =
305 MS_TO_NS(ENE_FW_SMPL_BUF_FAN_MSK *
306 ENE_FW_SAMPLE_PERIOD_FAN);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300307 } else {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300308 dev->props->rx_resolution = MS_TO_NS(sample_period);
309
310 /* Theoreticly timeout is unlimited, but we cap it
311 * because it was seen that on one device, it
312 * would stop sending spaces after around 250 msec.
313 * Besides, this is close to 2^32 anyway and timeout is u32.
314 */
315 dev->props->min_timeout = MS_TO_NS(127 * sample_period);
316 dev->props->max_timeout = MS_TO_NS(200000);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300317 }
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300318
319 if (dev->hw_learning_and_tx_capable)
320 dev->props->tx_resolution = MS_TO_NS(sample_period);
321
322 if (dev->props->timeout > dev->props->max_timeout)
323 dev->props->timeout = dev->props->max_timeout;
324 if (dev->props->timeout < dev->props->min_timeout)
325 dev->props->timeout = dev->props->min_timeout;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300326}
327
328/* Enable the device for receive */
329static void ene_rx_enable(struct ene_device *dev)
330{
331 u8 reg_value;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300332 dbg("RX: setup receiver, learning mode = %d", learning_mode);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300333
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300334 /* Enable system interrupt */
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300335 if (dev->hw_revision < ENE_HW_C) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300336 ene_write_reg(dev, ENEB_IRQ, dev->irq << 1);
337 ene_write_reg(dev, ENEB_IRQ_UNK1, 0x01);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300338 } else {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300339 reg_value = ene_read_reg(dev, ENE_IRQ) & 0xF0;
340 reg_value |= ENE_IRQ_UNK_EN;
341 reg_value &= ~ENE_IRQ_STATUS;
342 reg_value |= (dev->irq & ENE_IRQ_MASK);
343 ene_write_reg(dev, ENE_IRQ, reg_value);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300344 }
345
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300346 if (dev->hw_revision >= ENE_HW_C)
347 ene_write_reg(dev, ENE_CIRCAR_PULS, 0x63);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300348
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300349 /* Enable the inputs */
350 ene_write_reg(dev, ENE_CIRCFG2, 0x00);
351
352 if (dev->rx_fan_input_inuse) {
353 ene_enable_cir_engine(dev, false);
354 ene_enable_fan_input(dev, true);
355 } else {
356 ene_enable_cir_engine(dev, true);
357 ene_enable_fan_input(dev, false);
358 }
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300359
360 /* ack any pending irqs - just in case */
361 ene_irq_status(dev);
362
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300363 /* enable firmware bits */
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300364 ene_set_reg_mask(dev, ENE_FW1, ENE_FW1_ENABLE | ENE_FW1_IRQ);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300365
366 /* enter idle mode */
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300367 ir_raw_event_set_idle(dev->idev, true);
368 dev->rx_enabled = true;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300369}
370
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300371/* Disable the device receiver */
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300372static void ene_rx_disable(struct ene_device *dev)
373{
374 /* disable inputs */
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300375 ene_enable_cir_engine(dev, false);
376 ene_enable_fan_input(dev, false);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300377
378 /* disable hardware IRQ and firmware flag */
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300379 ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_ENABLE | ENE_FW1_IRQ);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300380
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300381 ir_raw_event_set_idle(dev->idev, true);
382 dev->rx_enabled = false;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300383}
384
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300385/* prepare transmission */
386static void ene_tx_prepare(struct ene_device *dev)
387{
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300388 u8 conf1 = ene_read_reg(dev, ENE_CIRCFG);
389 u8 fwreg2 = ene_read_reg(dev, ENE_FW2);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300390
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300391 dev->saved_conf1 = conf1;
392
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300393 /* Show information about currently connected transmitter jacks */
394 if (fwreg2 & ENE_FW2_EMMITER1_CONN)
395 dbg("TX: Transmitter #1 is connected");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300396
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300397 if (fwreg2 & ENE_FW2_EMMITER2_CONN)
398 dbg("TX: Transmitter #2 is connected");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300399
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300400 if (!(fwreg2 & (ENE_FW2_EMMITER1_CONN | ENE_FW2_EMMITER2_CONN)))
401 ene_warn("TX: transmitter cable isn't connected!");
402
403 /* Set transmitter mask */
404 ene_set_clear_reg_mask(dev, ENE_GPIOFS8, ENE_GPIOFS8_GPIO41,
405 !!(dev->transmitter_mask & 0x01));
406 ene_set_clear_reg_mask(dev, ENE_GPIOFS1, ENE_GPIOFS1_GPIO0D,
407 !!(dev->transmitter_mask & 0x02));
408
409 /* Set the carrier period && duty cycle */
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300410 if (dev->tx_period) {
411
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300412 int tx_puls_width = dev->tx_period / (100 / dev->tx_duty_cycle);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300413
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300414 if (!tx_puls_width)
415 tx_puls_width = 1;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300416
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300417 dbg("TX: pulse distance = %d * 500 ns", dev->tx_period);
418 dbg("TX: pulse width = %d * 500 ns", tx_puls_width);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300419
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300420 ene_write_reg(dev, ENE_CIRMOD_PRD, ENE_CIRMOD_PRD_POL |
421 dev->tx_period);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300422
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300423 ene_write_reg(dev, ENE_CIRMOD_HPRD, tx_puls_width);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300424
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300425 conf1 |= ENE_CIRCFG_TX_CARR;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300426 } else
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300427 conf1 &= ~ENE_CIRCFG_TX_CARR;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300428
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300429 /* disable receive on revc */
430 if (dev->hw_revision == ENE_HW_C)
431 conf1 &= ~ENE_CIRCFG_RX_EN;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300432
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300433 /* Enable TX engine */
434 conf1 |= ENE_CIRCFG_TX_EN | ENE_CIRCFG_TX_IRQ;
435 ene_write_reg(dev, ENE_CIRCFG, conf1);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300436}
437
438/* end transmission */
439static void ene_tx_complete(struct ene_device *dev)
440{
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300441 ene_write_reg(dev, ENE_CIRCFG, dev->saved_conf1);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300442 dev->tx_buffer = NULL;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300443}
444
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300445
446/* TX one sample - must be called with dev->hw_lock*/
447static void ene_tx_sample(struct ene_device *dev)
448{
449 u8 raw_tx;
450 u32 sample;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300451 bool pulse = dev->tx_sample_pulse;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300452
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300453 if (!dev->tx_buffer) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300454 ene_warn("TX: BUG: attempt to transmit NULL buffer");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300455 return;
456 }
457
458 /* Grab next TX sample */
459 if (!dev->tx_sample) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300460
461 if (dev->tx_pos == dev->tx_len) {
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300462 if (!dev->tx_done) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300463 dbg("TX: no more data to send");
464 dev->tx_done = true;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300465 goto exit;
466 } else {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300467 dbg("TX: last sample sent by hardware");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300468 ene_tx_complete(dev);
469 complete(&dev->tx_complete);
470 return;
471 }
472 }
473
474 sample = dev->tx_buffer[dev->tx_pos++];
475 dev->tx_sample_pulse = !dev->tx_sample_pulse;
476
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300477 dev->tx_sample = DIV_ROUND_CLOSEST(sample, sample_period);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300478
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300479 if (!dev->tx_sample)
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300480 dev->tx_sample = 1;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300481 }
482
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300483 raw_tx = min(dev->tx_sample , (unsigned int)ENE_CIRRLC_OUT_MASK);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300484 dev->tx_sample -= raw_tx;
485
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300486 dbg("TX: sample %8d (%s)", raw_tx * sample_period,
487 pulse ? "pulse" : "space");
488 if (pulse)
489 raw_tx |= ENE_CIRRLC_OUT_PULSE;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300490
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300491 ene_write_reg(dev,
492 dev->tx_reg ? ENE_CIRRLC_OUT1 : ENE_CIRRLC_OUT0, raw_tx);
493
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300494 dev->tx_reg = !dev->tx_reg;
495exit:
496 /* simulate TX done interrupt */
497 if (txsim)
498 mod_timer(&dev->tx_sim_timer, jiffies + HZ / 500);
499}
500
501/* timer to simulate tx done interrupt */
502static void ene_tx_irqsim(unsigned long data)
503{
504 struct ene_device *dev = (struct ene_device *)data;
505 unsigned long flags;
506
507 spin_lock_irqsave(&dev->hw_lock, flags);
508 ene_tx_sample(dev);
509 spin_unlock_irqrestore(&dev->hw_lock, flags);
510}
511
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300512/* Read properities of hw sample buffer */
513static void ene_setup_hw_buffer(struct ene_device *dev)
514{
515 u16 tmp;
516
517 ene_read_hw_pointer(dev);
518 dev->r_pointer = dev->w_pointer;
519
520 if (!dev->hw_extra_buffer) {
521 dev->buffer_len = ENE_FW_PACKET_SIZE * 2;
522 return;
523 }
524
525 tmp = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER);
526 tmp |= ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER+1) << 8;
527 dev->extra_buf1_address = tmp;
528
529 dev->extra_buf1_len = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 2);
530
531 tmp = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 3);
532 tmp |= ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 4) << 8;
533 dev->extra_buf2_address = tmp;
534
535 dev->extra_buf2_len = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 5);
536
537 dev->buffer_len = dev->extra_buf1_len + dev->extra_buf2_len + 8;
538
539 ene_notice("Hardware uses 2 extended buffers:");
540 ene_notice(" 0x%04x - len : %d", dev->extra_buf1_address,
541 dev->extra_buf1_len);
542 ene_notice(" 0x%04x - len : %d", dev->extra_buf2_address,
543 dev->extra_buf2_len);
544
545 ene_notice("Total buffer len = %d", dev->buffer_len);
546
547 if (dev->buffer_len > 64 || dev->buffer_len < 16)
548 goto error;
549
550 if (dev->extra_buf1_address > 0xFBFC ||
551 dev->extra_buf1_address < 0xEC00)
552 goto error;
553
554 if (dev->extra_buf2_address > 0xFBFC ||
555 dev->extra_buf2_address < 0xEC00)
556 goto error;
557
558 if (dev->r_pointer > dev->buffer_len)
559 goto error;
560
561 ene_set_reg_mask(dev, ENE_FW1, ENE_FW1_EXTRA_BUF_HND);
562 return;
563error:
564 ene_warn("Error validating extra buffers, device probably won't work");
565 dev->hw_extra_buffer = false;
566 ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_EXTRA_BUF_HND);
567}
568
569
570/* Restore the pointers to extra buffers - to make module reload work*/
571static void ene_restore_extra_buffer(struct ene_device *dev)
572{
573 if (!dev->hw_extra_buffer)
574 return;
575
576 ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 0,
577 dev->extra_buf1_address & 0xFF);
578 ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 1,
579 dev->extra_buf1_address >> 8);
580 ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 2, dev->extra_buf1_len);
581
582 ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 3,
583 dev->extra_buf2_address & 0xFF);
584 ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 4,
585 dev->extra_buf2_address >> 8);
586 ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 5,
587 dev->extra_buf2_len);
588 ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_EXTRA_BUF_HND);
589}
590
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300591
592/* read irq status and ack it */
593static int ene_irq_status(struct ene_device *dev)
594{
595 u8 irq_status;
596 u8 fw_flags1, fw_flags2;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300597 int retval = 0;
598
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300599 fw_flags2 = ene_read_reg(dev, ENE_FW2);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300600
601 if (dev->hw_revision < ENE_HW_C) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300602 irq_status = ene_read_reg(dev, ENEB_IRQ_STATUS);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300603
604 if (!(irq_status & ENEB_IRQ_STATUS_IR))
605 return 0;
606
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300607 ene_clear_reg_mask(dev, ENEB_IRQ_STATUS, ENEB_IRQ_STATUS_IR);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300608 return ENE_IRQ_RX;
609 }
610
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300611 irq_status = ene_read_reg(dev, ENE_IRQ);
612 if (!(irq_status & ENE_IRQ_STATUS))
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300613 return 0;
614
615 /* original driver does that twice - a workaround ? */
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300616 ene_write_reg(dev, ENE_IRQ, irq_status & ~ENE_IRQ_STATUS);
617 ene_write_reg(dev, ENE_IRQ, irq_status & ~ENE_IRQ_STATUS);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300618
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300619 /* check RX interrupt */
620 if (fw_flags2 & ENE_FW2_RXIRQ) {
621 retval |= ENE_IRQ_RX;
622 ene_write_reg(dev, ENE_FW2, fw_flags2 & ~ENE_FW2_RXIRQ);
623 }
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300624
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300625 /* check TX interrupt */
626 fw_flags1 = ene_read_reg(dev, ENE_FW1);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300627 if (fw_flags1 & ENE_FW1_TXIRQ) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300628 ene_write_reg(dev, ENE_FW1, fw_flags1 & ~ENE_FW1_TXIRQ);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300629 retval |= ENE_IRQ_TX;
630 }
631
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300632 return retval;
633}
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300634
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300635/* Read hardware write pointer */
636static void ene_read_hw_pointer(struct ene_device *dev)
637{
638 if (dev->hw_extra_buffer)
639 dev->w_pointer = ene_read_reg(dev, ENE_FW_RX_POINTER);
640 else
641 dev->w_pointer = ene_read_reg(dev, ENE_FW2)
642 & ENE_FW2_BUF_WPTR ? 0 : ENE_FW_PACKET_SIZE;
643
644 dbg_verbose("RB: HW write pointer: %02x, driver read pointer: %02x",
645 dev->w_pointer, dev->r_pointer);
646}
647
648/* Gets address of next sample from HW ring buffer */
649static int ene_get_sample_reg(struct ene_device *dev)
650{
651 int r_pointer;
652
653 if (dev->r_pointer == dev->w_pointer) {
654 dbg_verbose("RB: hit end, try update w_pointer");
655 ene_read_hw_pointer(dev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300656 }
657
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300658 if (dev->r_pointer == dev->w_pointer) {
659 dbg_verbose("RB: end of data at %d", dev->r_pointer);
660 return 0;
661 }
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300662
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300663 dbg_verbose("RB: reading at offset %d", dev->r_pointer);
664 r_pointer = dev->r_pointer;
665
666 dev->r_pointer++;
667 if (dev->r_pointer == dev->buffer_len)
668 dev->r_pointer = 0;
669
670 dbg_verbose("RB: next read will be from offset %d", dev->r_pointer);
671
672 if (r_pointer < 8) {
673 dbg_verbose("RB: read at main buffer at %d", r_pointer);
674 return ENE_FW_SAMPLE_BUFFER + r_pointer;
675 }
676
677 r_pointer -= 8;
678
679 if (r_pointer < dev->extra_buf1_len) {
680 dbg_verbose("RB: read at 1st extra buffer at %d", r_pointer);
681 return dev->extra_buf1_address + r_pointer;
682 }
683
684 r_pointer -= dev->extra_buf1_len;
685
686 if (r_pointer < dev->extra_buf2_len) {
687 dbg_verbose("RB: read at 2nd extra buffer at %d", r_pointer);
688 return dev->extra_buf2_address + r_pointer;
689 }
690
691 dbg("attempt to read beyong ring bufer end");
692 return 0;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300693}
694
695/* interrupt handler */
696static irqreturn_t ene_isr(int irq, void *data)
697{
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300698 u16 hw_value, reg;
699 int hw_sample, irq_status;
700 bool pulse;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300701 unsigned long flags;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300702 irqreturn_t retval = IRQ_NONE;
703 struct ene_device *dev = (struct ene_device *)data;
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300704 struct ir_raw_event ev;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300705
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300706 spin_lock_irqsave(&dev->hw_lock, flags);
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300707
708 dbg_verbose("ISR called");
709 ene_read_hw_pointer(dev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300710 irq_status = ene_irq_status(dev);
711
712 if (!irq_status)
713 goto unlock;
714
715 retval = IRQ_HANDLED;
716
717 if (irq_status & ENE_IRQ_TX) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300718 dbg_verbose("TX interrupt");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300719 if (!dev->hw_learning_and_tx_capable) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300720 dbg("TX interrupt on unsupported device!");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300721 goto unlock;
722 }
723 ene_tx_sample(dev);
724 }
725
726 if (!(irq_status & ENE_IRQ_RX))
727 goto unlock;
728
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300729 dbg_verbose("RX interrupt");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300730
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300731 if (dev->carrier_detect_enabled || debug)
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300732 ene_rx_sense_carrier(dev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300733
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300734 /* On hardware that don't support extra buffer we need to trust
735 the interrupt and not track the read pointer */
736 if (!dev->hw_extra_buffer)
737 dev->r_pointer = dev->w_pointer == 0 ? ENE_FW_PACKET_SIZE : 0;
738
739 while (1) {
740
741 reg = ene_get_sample_reg(dev);
742
743 dbg_verbose("next sample to read at: %04x", reg);
744 if (!reg)
745 break;
746
747 hw_value = ene_read_reg(dev, reg);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300748
749 if (dev->rx_fan_input_inuse) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300750
751 int offset = ENE_FW_SMPL_BUF_FAN - ENE_FW_SAMPLE_BUFFER;
752
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300753 /* read high part of the sample */
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300754 hw_value |= ene_read_reg(dev, reg + offset) << 8;
755 pulse = hw_value & ENE_FW_SMPL_BUF_FAN_PLS;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300756
757 /* clear space bit, and other unused bits */
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300758 hw_value &= ENE_FW_SMPL_BUF_FAN_MSK;
759 hw_sample = hw_value * ENE_FW_SAMPLE_PERIOD_FAN;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300760
761 } else {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300762 pulse = !(hw_value & ENE_FW_SAMPLE_SPACE);
763 hw_value &= ~ENE_FW_SAMPLE_SPACE;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300764 hw_sample = hw_value * sample_period;
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300765
766 if (dev->rx_period_adjust) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300767 hw_sample *= 100;
768 hw_sample /= (100 + dev->rx_period_adjust);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300769 }
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300770 }
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300771
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300772 if (!dev->hw_extra_buffer && !hw_sample) {
773 dev->r_pointer = dev->w_pointer;
774 continue;
775 }
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300776
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300777 dbg("RX: %d (%s)", hw_sample, pulse ? "pulse" : "space");
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300778
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300779 ev.duration = MS_TO_NS(hw_sample);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300780 ev.pulse = pulse;
781 ir_raw_event_store_with_filter(dev->idev, &ev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300782 }
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300783
784 ir_raw_event_handle(dev->idev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300785unlock:
786 spin_unlock_irqrestore(&dev->hw_lock, flags);
787 return retval;
788}
789
790/* Initialize default settings */
791static void ene_setup_settings(struct ene_device *dev)
792{
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300793 dev->tx_period = 32;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300794 dev->tx_duty_cycle = 50; /*%*/
795 dev->transmitter_mask = 0x03;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300796
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300797 dev->learning_enabled =
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300798 (learning_mode && dev->hw_learning_and_tx_capable);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300799
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300800 /* Set reasonable default timeout */
801 dev->props->timeout = MS_TO_NS(15000);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300802}
803
804/* outside interface: called on first open*/
805static int ene_open(void *data)
806{
807 struct ene_device *dev = (struct ene_device *)data;
808 unsigned long flags;
809
810 spin_lock_irqsave(&dev->hw_lock, flags);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300811 ene_rx_enable(dev);
812 spin_unlock_irqrestore(&dev->hw_lock, flags);
813 return 0;
814}
815
816/* outside interface: called on device close*/
817static void ene_close(void *data)
818{
819 struct ene_device *dev = (struct ene_device *)data;
820 unsigned long flags;
821 spin_lock_irqsave(&dev->hw_lock, flags);
822
823 ene_rx_disable(dev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300824 spin_unlock_irqrestore(&dev->hw_lock, flags);
825}
826
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300827/* outside interface: set transmitter mask */
828static int ene_set_tx_mask(void *data, u32 tx_mask)
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300829{
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300830 struct ene_device *dev = (struct ene_device *)data;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300831 unsigned long flags;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300832 dbg("TX: attempt to set transmitter mask %02x", tx_mask);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300833
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300834 /* invalid txmask */
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300835 if (!tx_mask || tx_mask & ~0x03) {
836 dbg("TX: invalid mask");
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300837 /* return count of transmitters */
838 return 2;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300839 }
840
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300841 spin_lock_irqsave(&dev->hw_lock, flags);
842 dev->transmitter_mask = tx_mask;
843 spin_unlock_irqrestore(&dev->hw_lock, flags);
844 return 0;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300845}
846
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300847/* outside interface : set tx carrier */
848static int ene_set_tx_carrier(void *data, u32 carrier)
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300849{
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300850 struct ene_device *dev = (struct ene_device *)data;
851 unsigned long flags;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300852 u32 period = 2000000 / carrier;
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300853
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300854 dbg("TX: attempt to set tx carrier to %d kHz", carrier);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300855
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300856 if (period && (period > ENE_CIRMOD_PRD_MAX ||
857 period < ENE_CIRMOD_PRD_MIN)) {
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300858
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300859 dbg("TX: out of range %d-%d kHz carrier",
860 2000 / ENE_CIRMOD_PRD_MIN,
861 2000 / ENE_CIRMOD_PRD_MAX);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300862
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300863 return -1;
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300864 }
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300865
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300866 dbg("TX: set carrier to %d kHz", carrier);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300867 spin_lock_irqsave(&dev->hw_lock, flags);
868 dev->tx_period = period;
869 spin_unlock_irqrestore(&dev->hw_lock, flags);
870 return 0;
871}
872
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300873/*outside interface : set tx duty cycle */
874static int ene_set_tx_duty_cycle(void *data, u32 duty_cycle)
875{
876 struct ene_device *dev = (struct ene_device *)data;
877 unsigned long flags;
878
879 dbg("TX: setting duty cycle to %d%%", duty_cycle);
880
881 BUG_ON(!duty_cycle || duty_cycle >= 100);
882
883 spin_lock_irqsave(&dev->hw_lock, flags);
884 dev->tx_duty_cycle = duty_cycle;
885 spin_unlock_irqrestore(&dev->hw_lock, flags);
886 return 0;
887}
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300888
889/* outside interface: enable learning mode */
890static int ene_set_learning_mode(void *data, int enable)
891{
892 struct ene_device *dev = (struct ene_device *)data;
893 unsigned long flags;
894 if (enable == dev->learning_enabled)
895 return 0;
896
897 spin_lock_irqsave(&dev->hw_lock, flags);
898 dev->learning_enabled = enable;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300899 ene_rx_disable(dev);
900 ene_rx_setup(dev);
901 ene_rx_enable(dev);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300902 spin_unlock_irqrestore(&dev->hw_lock, flags);
903 return 0;
904}
905
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300906/* outside interface: enable or disable idle mode */
907static void ene_rx_set_idle(void *data, int idle)
908{
909 struct ene_device *dev = (struct ene_device *)data;
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300910
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300911 if (!idle)
912 return;
913
914 dbg("RX: stopping the receiver");
915 ene_clear_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_RX_EN);
916 ene_set_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_RX_EN);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300917}
918
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300919/* outside interface: transmit */
920static int ene_transmit(void *data, int *buf, u32 n)
921{
922 struct ene_device *dev = (struct ene_device *)data;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300923 unsigned long flags;
924
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300925 dev->tx_buffer = buf;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300926 dev->tx_len = n / sizeof(int);
927 dev->tx_pos = 0;
928 dev->tx_reg = 0;
929 dev->tx_done = 0;
930 dev->tx_sample = 0;
931 dev->tx_sample_pulse = 0;
932
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300933 dbg("TX: %d samples", dev->tx_len);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300934
935 spin_lock_irqsave(&dev->hw_lock, flags);
936
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300937 ene_tx_prepare(dev);
938
939 /* Transmit first two samples */
940 ene_tx_sample(dev);
941 ene_tx_sample(dev);
942
943 spin_unlock_irqrestore(&dev->hw_lock, flags);
944
945 if (wait_for_completion_timeout(&dev->tx_complete, 2 * HZ) == 0) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300946 dbg("TX: timeout");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300947 spin_lock_irqsave(&dev->hw_lock, flags);
948 ene_tx_complete(dev);
949 spin_unlock_irqrestore(&dev->hw_lock, flags);
950 } else
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300951 dbg("TX: done");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300952 return n;
953}
954
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300955/* probe entry */
956static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300957{
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300958 int error = -ENOMEM;
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300959 struct ir_dev_props *ir_props;
960 struct input_dev *input_dev;
961 struct ene_device *dev;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300962
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300963 /* allocate memory */
964 input_dev = input_allocate_device();
965 ir_props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300966 dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL);
967
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300968 if (!input_dev || !ir_props || !dev)
969 goto error;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300970
971 /* validate resources */
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300972 error = -ENODEV;
973
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300974 if (!pnp_port_valid(pnp_dev, 0) ||
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300975 pnp_port_len(pnp_dev, 0) < ENE_IO_SIZE)
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300976 goto error;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300977
978 if (!pnp_irq_valid(pnp_dev, 0))
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300979 goto error;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300980
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300981 spin_lock_init(&dev->hw_lock);
982
983 /* claim the resources */
984 error = -EBUSY;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300985 dev->hw_io = pnp_port_start(pnp_dev, 0);
986 if (!request_region(dev->hw_io, ENE_IO_SIZE, ENE_DRIVER_NAME)) {
987 dev->hw_io = -1;
988 dev->irq = -1;
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300989 goto error;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300990 }
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300991
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300992 dev->irq = pnp_irq(pnp_dev, 0);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300993 if (request_irq(dev->irq, ene_isr,
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300994 IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev)) {
995 dev->irq = -1;
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300996 goto error;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300997 }
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300998
999 pnp_set_drvdata(pnp_dev, dev);
1000 dev->pnp_dev = pnp_dev;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001001
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001002 /* don't allow too short/long sample periods */
1003 if (sample_period < 5 || sample_period > 0x7F)
1004 sample_period = ENE_DEFAULT_SAMPLE_PERIOD;
1005
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001006 /* detect hardware version and features */
1007 error = ene_hw_detect(dev);
1008 if (error)
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001009 goto error;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001010
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001011 if (!dev->hw_learning_and_tx_capable && txsim) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001012 dev->hw_learning_and_tx_capable = true;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001013 setup_timer(&dev->tx_sim_timer, ene_tx_irqsim,
1014 (long unsigned int)dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001015 ene_warn("Simulation of TX activated");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001016 }
1017
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001018 ir_props->driver_type = RC_DRIVER_IR_RAW;
1019 ir_props->allowed_protos = IR_TYPE_ALL;
1020 ir_props->priv = dev;
1021 ir_props->open = ene_open;
1022 ir_props->close = ene_close;
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001023 ir_props->s_idle = ene_rx_set_idle;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001024
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001025 dev->props = ir_props;
1026 dev->idev = input_dev;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001027
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001028 if (dev->hw_learning_and_tx_capable) {
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001029 ir_props->s_learning_mode = ene_set_learning_mode;
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001030 init_completion(&dev->tx_complete);
1031 ir_props->tx_ir = ene_transmit;
1032 ir_props->s_tx_mask = ene_set_tx_mask;
1033 ir_props->s_tx_carrier = ene_set_tx_carrier;
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001034 ir_props->s_tx_duty_cycle = ene_set_tx_duty_cycle;
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001035 /* ir_props->s_carrier_report = ene_set_carrier_report; */
1036 }
1037
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001038 ene_setup_hw_buffer(dev);
1039 ene_setup_settings(dev);
1040 ene_rx_setup(dev);
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001041
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001042 device_set_wakeup_capable(&pnp_dev->dev, true);
1043 device_set_wakeup_enable(&pnp_dev->dev, true);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001044
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001045 if (dev->hw_learning_and_tx_capable)
1046 input_dev->name = "ENE eHome Infrared Remote Transceiver";
1047 else
1048 input_dev->name = "ENE eHome Infrared Remote Receiver";
1049
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001050 error = -ENODEV;
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001051 if (ir_input_register(input_dev, RC_MAP_RC6_MCE, ir_props,
1052 ENE_DRIVER_NAME))
1053 goto error;
1054
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001055 ene_notice("driver has been succesfully loaded");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001056 return 0;
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001057error:
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001058 if (dev && dev->irq >= 0)
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001059 free_irq(dev->irq, dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001060 if (dev && dev->hw_io >= 0)
1061 release_region(dev->hw_io, ENE_IO_SIZE);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001062
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001063 input_free_device(input_dev);
1064 kfree(ir_props);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001065 kfree(dev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001066 return error;
1067}
1068
1069/* main unload function */
1070static void ene_remove(struct pnp_dev *pnp_dev)
1071{
1072 struct ene_device *dev = pnp_get_drvdata(pnp_dev);
1073 unsigned long flags;
1074
1075 spin_lock_irqsave(&dev->hw_lock, flags);
1076 ene_rx_disable(dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001077 ene_restore_extra_buffer(dev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001078 spin_unlock_irqrestore(&dev->hw_lock, flags);
1079
1080 free_irq(dev->irq, dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001081 release_region(dev->hw_io, ENE_IO_SIZE);
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001082 ir_input_unregister(dev->idev);
1083 kfree(dev->props);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001084 kfree(dev);
1085}
1086
1087/* enable wake on IR (wakes on specific button on original remote) */
1088static void ene_enable_wake(struct ene_device *dev, int enable)
1089{
1090 enable = enable && device_may_wakeup(&dev->pnp_dev->dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001091 dbg("wake on IR %s", enable ? "enabled" : "disabled");
1092 ene_set_clear_reg_mask(dev, ENE_FW1, ENE_FW1_WAKE, enable);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001093}
1094
1095#ifdef CONFIG_PM
1096static int ene_suspend(struct pnp_dev *pnp_dev, pm_message_t state)
1097{
1098 struct ene_device *dev = pnp_get_drvdata(pnp_dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001099 ene_enable_wake(dev, true);
1100
1101 /* TODO: add support for wake pattern */
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001102 return 0;
1103}
1104
1105static int ene_resume(struct pnp_dev *pnp_dev)
1106{
1107 struct ene_device *dev = pnp_get_drvdata(pnp_dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001108 if (dev->rx_enabled) {
1109 ene_rx_setup(dev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001110 ene_rx_enable(dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001111 }
1112 ene_enable_wake(dev, false);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001113 return 0;
1114}
1115#endif
1116
1117static void ene_shutdown(struct pnp_dev *pnp_dev)
1118{
1119 struct ene_device *dev = pnp_get_drvdata(pnp_dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001120 ene_enable_wake(dev, true);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001121}
1122
1123static const struct pnp_device_id ene_ids[] = {
1124 {.id = "ENE0100",},
1125 {.id = "ENE0200",},
1126 {.id = "ENE0201",},
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001127 {.id = "ENE0202",},
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001128 {},
1129};
1130
1131static struct pnp_driver ene_driver = {
1132 .name = ENE_DRIVER_NAME,
1133 .id_table = ene_ids,
1134 .flags = PNP_DRIVER_RES_DO_NOT_CHANGE,
1135
1136 .probe = ene_probe,
1137 .remove = __devexit_p(ene_remove),
1138#ifdef CONFIG_PM
1139 .suspend = ene_suspend,
1140 .resume = ene_resume,
1141#endif
1142 .shutdown = ene_shutdown,
1143};
1144
1145static int __init ene_init(void)
1146{
1147 return pnp_register_driver(&ene_driver);
1148}
1149
1150static void ene_exit(void)
1151{
1152 pnp_unregister_driver(&ene_driver);
1153}
1154
1155module_param(sample_period, int, S_IRUGO);
1156MODULE_PARM_DESC(sample_period, "Hardware sample period (50 us default)");
1157
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001158module_param(learning_mode, bool, S_IRUGO);
1159MODULE_PARM_DESC(learning_mode, "Enable learning mode by default");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001160
1161module_param(debug, int, S_IRUGO | S_IWUSR);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001162MODULE_PARM_DESC(debug, "Debug level");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001163
1164module_param(txsim, bool, S_IRUGO);
1165MODULE_PARM_DESC(txsim,
1166 "Simulate TX features on unsupported hardware (dangerous)");
1167
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001168MODULE_DEVICE_TABLE(pnp, ene_ids);
1169MODULE_DESCRIPTION
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001170 ("Infrared input driver for KB3926B/C/D/E/F "
1171 "(aka ENE0100/ENE0200/ENE0201/ENE0202) CIR port");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001172
1173MODULE_AUTHOR("Maxim Levitsky");
1174MODULE_LICENSE("GPL");
1175
1176module_init(ene_init);
1177module_exit(ene_exit);