blob: 0795872ff5de1a2be0888b18e5ed9a6888fd5d4d [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 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/* Sense current received carrier */
194void ene_rx_sense_carrier(struct ene_device *dev)
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300195{
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300196 int period = ene_read_reg(dev, ENE_CIRCAR_PRD);
197 int hperiod = ene_read_reg(dev, ENE_CIRCAR_HPRD);
198 int carrier, duty_cycle;
199
200
201 if (!(period & ENE_CIRCAR_PRD_VALID))
202 return;
203
204 period &= ~ENE_CIRCAR_PRD_VALID;
205
206 if (!period)
207 return;
208
209 dbg("RX: hardware carrier period = %02x", period);
210 dbg("RX: hardware carrier pulse period = %02x", hperiod);
211
212
213 carrier = 2000000 / period;
214 duty_cycle = (hperiod * 100) / period;
215 dbg("RX: sensed carrier = %d Hz, duty cycle %d%%",
216 carrier, duty_cycle);
217
218 /* TODO: Send carrier & duty cycle to IR layer */
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300219}
220
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300221/* this enables/disables the CIR RX engine */
222static void ene_enable_cir_engine(struct ene_device *dev, bool enable)
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300223{
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300224 ene_set_clear_reg_mask(dev, ENE_CIRCFG,
225 ENE_CIRCFG_RX_EN | ENE_CIRCFG_RX_IRQ, enable);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300226}
227
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300228/* this selects input for CIR engine. Ether GPIO 0A or GPIO40*/
229static void ene_select_rx_input(struct ene_device *dev, bool gpio_0a)
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300230{
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300231 ene_set_clear_reg_mask(dev, ENE_CIRCFG2, ENE_CIRCFG2_GPIO0A, gpio_0a);
232}
233
234/*
235 * this enables alternative input via fan tachometer sensor and bypasses
236 * the hw CIR engine
237 */
238static void ene_enable_fan_input(struct ene_device *dev, bool enable)
239{
240 if (!dev->hw_fan_input)
241 return;
242
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300243 if (!enable)
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300244 ene_write_reg(dev, ENE_FAN_AS_IN1, 0);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300245 else {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300246 ene_write_reg(dev, ENE_FAN_AS_IN1, ENE_FAN_AS_IN1_EN);
247 ene_write_reg(dev, ENE_FAN_AS_IN2, ENE_FAN_AS_IN2_EN);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300248 }
249 dev->rx_fan_input_inuse = enable;
250}
251
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300252/* setup the receiver for RX*/
253static void ene_rx_setup(struct ene_device *dev)
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300254{
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300255 bool learning_mode = dev->learning_enabled ||
256 dev->carrier_detect_enabled;
257 int sample_period_adjust = 0;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300258
Maxim Levitskya06423c2010-10-15 13:06:37 -0300259 /* This selects RLC input and clears CFG2 settings */
260 ene_write_reg(dev, ENE_CIRCFG2, 0x00);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300261
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300262 /* set sample period*/
263 if (sample_period == ENE_DEFAULT_SAMPLE_PERIOD)
264 sample_period_adjust =
265 dev->pll_freq == ENE_DEFAULT_PLL_FREQ ? 1 : 2;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300266
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300267 ene_write_reg(dev, ENE_CIRRLC_CFG,
268 (sample_period + sample_period_adjust) |
269 ENE_CIRRLC_CFG_OVERFLOW);
270 /* revB doesn't support inputs */
271 if (dev->hw_revision < ENE_HW_C)
272 goto select_timeout;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300273
Maxim Levitskya06423c2010-10-15 13:06:37 -0300274 if (learning_mode) {
275
276 WARN_ON(!dev->hw_learning_and_tx_capable);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300277
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300278 /* Enable the opposite of the normal input
279 That means that if GPIO40 is normally used, use GPIO0A
280 and vice versa.
281 This input will carry non demodulated
282 signal, and we will tell the hw to demodulate it itself */
283 ene_select_rx_input(dev, !dev->hw_use_gpio_0a);
284 dev->rx_fan_input_inuse = false;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300285
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300286 /* Enable carrier demodulation */
287 ene_set_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_CARR_DEMOD);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300288
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300289 /* Enable carrier detection */
Maxim Levitskya06423c2010-10-15 13:06:37 -0300290 ene_write_reg(dev, ENE_CIRCAR_PULS, 0x63);
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300291 ene_set_clear_reg_mask(dev, ENE_CIRCFG2, ENE_CIRCFG2_CARR_DETECT,
292 dev->carrier_detect_enabled || debug);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300293 } else {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300294 if (dev->hw_fan_input)
295 dev->rx_fan_input_inuse = true;
296 else
297 ene_select_rx_input(dev, dev->hw_use_gpio_0a);
298
299 /* Disable carrier detection & demodulation */
300 ene_clear_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_CARR_DEMOD);
301 ene_clear_reg_mask(dev, ENE_CIRCFG2, ENE_CIRCFG2_CARR_DETECT);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300302 }
303
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300304select_timeout:
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300305 if (dev->rx_fan_input_inuse) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300306 dev->props->rx_resolution = MS_TO_NS(ENE_FW_SAMPLE_PERIOD_FAN);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300307
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300308 /* Fan input doesn't support timeouts, it just ends the
309 input with a maximum sample */
310 dev->props->min_timeout = dev->props->max_timeout =
311 MS_TO_NS(ENE_FW_SMPL_BUF_FAN_MSK *
312 ENE_FW_SAMPLE_PERIOD_FAN);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300313 } else {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300314 dev->props->rx_resolution = MS_TO_NS(sample_period);
315
316 /* Theoreticly timeout is unlimited, but we cap it
317 * because it was seen that on one device, it
318 * would stop sending spaces after around 250 msec.
319 * Besides, this is close to 2^32 anyway and timeout is u32.
320 */
321 dev->props->min_timeout = MS_TO_NS(127 * sample_period);
322 dev->props->max_timeout = MS_TO_NS(200000);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300323 }
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300324
325 if (dev->hw_learning_and_tx_capable)
326 dev->props->tx_resolution = MS_TO_NS(sample_period);
327
328 if (dev->props->timeout > dev->props->max_timeout)
329 dev->props->timeout = dev->props->max_timeout;
330 if (dev->props->timeout < dev->props->min_timeout)
331 dev->props->timeout = dev->props->min_timeout;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300332}
333
334/* Enable the device for receive */
335static void ene_rx_enable(struct ene_device *dev)
336{
337 u8 reg_value;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300338 dbg("RX: setup receiver, learning mode = %d", learning_mode);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300339
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300340 /* Enable system interrupt */
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300341 if (dev->hw_revision < ENE_HW_C) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300342 ene_write_reg(dev, ENEB_IRQ, dev->irq << 1);
343 ene_write_reg(dev, ENEB_IRQ_UNK1, 0x01);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300344 } else {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300345 reg_value = ene_read_reg(dev, ENE_IRQ) & 0xF0;
346 reg_value |= ENE_IRQ_UNK_EN;
347 reg_value &= ~ENE_IRQ_STATUS;
348 reg_value |= (dev->irq & ENE_IRQ_MASK);
349 ene_write_reg(dev, ENE_IRQ, reg_value);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300350 }
351
Maxim Levitskya06423c2010-10-15 13:06:37 -0300352 /* Enable inputs */
353 ene_enable_fan_input(dev, dev->rx_fan_input_inuse);
354 ene_enable_cir_engine(dev, !dev->rx_fan_input_inuse);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300355
356 /* ack any pending irqs - just in case */
357 ene_irq_status(dev);
358
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300359 /* enable firmware bits */
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300360 ene_set_reg_mask(dev, ENE_FW1, ENE_FW1_ENABLE | ENE_FW1_IRQ);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300361
362 /* enter idle mode */
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300363 ir_raw_event_set_idle(dev->idev, true);
364 dev->rx_enabled = true;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300365}
366
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300367/* Disable the device receiver */
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300368static void ene_rx_disable(struct ene_device *dev)
369{
370 /* disable inputs */
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300371 ene_enable_cir_engine(dev, false);
372 ene_enable_fan_input(dev, false);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300373
374 /* disable hardware IRQ and firmware flag */
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300375 ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_ENABLE | ENE_FW1_IRQ);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300376
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300377 ir_raw_event_set_idle(dev->idev, true);
378 dev->rx_enabled = false;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300379}
380
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300381/* prepare transmission */
382static void ene_tx_prepare(struct ene_device *dev)
383{
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300384 u8 conf1 = ene_read_reg(dev, ENE_CIRCFG);
385 u8 fwreg2 = ene_read_reg(dev, ENE_FW2);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300386
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300387 dev->saved_conf1 = conf1;
388
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300389 /* Show information about currently connected transmitter jacks */
390 if (fwreg2 & ENE_FW2_EMMITER1_CONN)
391 dbg("TX: Transmitter #1 is connected");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300392
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300393 if (fwreg2 & ENE_FW2_EMMITER2_CONN)
394 dbg("TX: Transmitter #2 is connected");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300395
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300396 if (!(fwreg2 & (ENE_FW2_EMMITER1_CONN | ENE_FW2_EMMITER2_CONN)))
397 ene_warn("TX: transmitter cable isn't connected!");
398
399 /* Set transmitter mask */
400 ene_set_clear_reg_mask(dev, ENE_GPIOFS8, ENE_GPIOFS8_GPIO41,
401 !!(dev->transmitter_mask & 0x01));
402 ene_set_clear_reg_mask(dev, ENE_GPIOFS1, ENE_GPIOFS1_GPIO0D,
403 !!(dev->transmitter_mask & 0x02));
404
405 /* Set the carrier period && duty cycle */
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300406 if (dev->tx_period) {
407
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300408 int tx_puls_width = dev->tx_period / (100 / dev->tx_duty_cycle);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300409
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300410 if (!tx_puls_width)
411 tx_puls_width = 1;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300412
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300413 dbg("TX: pulse distance = %d * 500 ns", dev->tx_period);
414 dbg("TX: pulse width = %d * 500 ns", tx_puls_width);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300415
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300416 ene_write_reg(dev, ENE_CIRMOD_PRD, ENE_CIRMOD_PRD_POL |
417 dev->tx_period);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300418
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300419 ene_write_reg(dev, ENE_CIRMOD_HPRD, tx_puls_width);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300420
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300421 conf1 |= ENE_CIRCFG_TX_CARR;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300422 } else
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300423 conf1 &= ~ENE_CIRCFG_TX_CARR;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300424
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300425 /* disable receive on revc */
426 if (dev->hw_revision == ENE_HW_C)
427 conf1 &= ~ENE_CIRCFG_RX_EN;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300428
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300429 /* Enable TX engine */
430 conf1 |= ENE_CIRCFG_TX_EN | ENE_CIRCFG_TX_IRQ;
431 ene_write_reg(dev, ENE_CIRCFG, conf1);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300432}
433
434/* end transmission */
435static void ene_tx_complete(struct ene_device *dev)
436{
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300437 ene_write_reg(dev, ENE_CIRCFG, dev->saved_conf1);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300438 dev->tx_buffer = NULL;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300439}
440
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300441
442/* TX one sample - must be called with dev->hw_lock*/
443static void ene_tx_sample(struct ene_device *dev)
444{
445 u8 raw_tx;
446 u32 sample;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300447 bool pulse = dev->tx_sample_pulse;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300448
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300449 if (!dev->tx_buffer) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300450 ene_warn("TX: BUG: attempt to transmit NULL buffer");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300451 return;
452 }
453
454 /* Grab next TX sample */
455 if (!dev->tx_sample) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300456
457 if (dev->tx_pos == dev->tx_len) {
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300458 if (!dev->tx_done) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300459 dbg("TX: no more data to send");
460 dev->tx_done = true;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300461 goto exit;
462 } else {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300463 dbg("TX: last sample sent by hardware");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300464 ene_tx_complete(dev);
465 complete(&dev->tx_complete);
466 return;
467 }
468 }
469
470 sample = dev->tx_buffer[dev->tx_pos++];
471 dev->tx_sample_pulse = !dev->tx_sample_pulse;
472
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300473 dev->tx_sample = DIV_ROUND_CLOSEST(sample, sample_period);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300474
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300475 if (!dev->tx_sample)
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300476 dev->tx_sample = 1;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300477 }
478
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300479 raw_tx = min(dev->tx_sample , (unsigned int)ENE_CIRRLC_OUT_MASK);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300480 dev->tx_sample -= raw_tx;
481
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300482 dbg("TX: sample %8d (%s)", raw_tx * sample_period,
483 pulse ? "pulse" : "space");
484 if (pulse)
485 raw_tx |= ENE_CIRRLC_OUT_PULSE;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300486
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300487 ene_write_reg(dev,
488 dev->tx_reg ? ENE_CIRRLC_OUT1 : ENE_CIRRLC_OUT0, raw_tx);
489
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300490 dev->tx_reg = !dev->tx_reg;
491exit:
492 /* simulate TX done interrupt */
493 if (txsim)
494 mod_timer(&dev->tx_sim_timer, jiffies + HZ / 500);
495}
496
497/* timer to simulate tx done interrupt */
498static void ene_tx_irqsim(unsigned long data)
499{
500 struct ene_device *dev = (struct ene_device *)data;
501 unsigned long flags;
502
503 spin_lock_irqsave(&dev->hw_lock, flags);
504 ene_tx_sample(dev);
505 spin_unlock_irqrestore(&dev->hw_lock, flags);
506}
507
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300508/* Read properities of hw sample buffer */
509static void ene_setup_hw_buffer(struct ene_device *dev)
510{
511 u16 tmp;
512
513 ene_read_hw_pointer(dev);
514 dev->r_pointer = dev->w_pointer;
515
516 if (!dev->hw_extra_buffer) {
517 dev->buffer_len = ENE_FW_PACKET_SIZE * 2;
518 return;
519 }
520
521 tmp = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER);
522 tmp |= ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER+1) << 8;
523 dev->extra_buf1_address = tmp;
524
525 dev->extra_buf1_len = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 2);
526
527 tmp = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 3);
528 tmp |= ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 4) << 8;
529 dev->extra_buf2_address = tmp;
530
531 dev->extra_buf2_len = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 5);
532
533 dev->buffer_len = dev->extra_buf1_len + dev->extra_buf2_len + 8;
534
535 ene_notice("Hardware uses 2 extended buffers:");
536 ene_notice(" 0x%04x - len : %d", dev->extra_buf1_address,
537 dev->extra_buf1_len);
538 ene_notice(" 0x%04x - len : %d", dev->extra_buf2_address,
539 dev->extra_buf2_len);
540
541 ene_notice("Total buffer len = %d", dev->buffer_len);
542
543 if (dev->buffer_len > 64 || dev->buffer_len < 16)
544 goto error;
545
546 if (dev->extra_buf1_address > 0xFBFC ||
547 dev->extra_buf1_address < 0xEC00)
548 goto error;
549
550 if (dev->extra_buf2_address > 0xFBFC ||
551 dev->extra_buf2_address < 0xEC00)
552 goto error;
553
554 if (dev->r_pointer > dev->buffer_len)
555 goto error;
556
557 ene_set_reg_mask(dev, ENE_FW1, ENE_FW1_EXTRA_BUF_HND);
558 return;
559error:
560 ene_warn("Error validating extra buffers, device probably won't work");
561 dev->hw_extra_buffer = false;
562 ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_EXTRA_BUF_HND);
563}
564
565
566/* Restore the pointers to extra buffers - to make module reload work*/
567static void ene_restore_extra_buffer(struct ene_device *dev)
568{
569 if (!dev->hw_extra_buffer)
570 return;
571
572 ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 0,
573 dev->extra_buf1_address & 0xFF);
574 ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 1,
575 dev->extra_buf1_address >> 8);
576 ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 2, dev->extra_buf1_len);
577
578 ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 3,
579 dev->extra_buf2_address & 0xFF);
580 ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 4,
581 dev->extra_buf2_address >> 8);
582 ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 5,
583 dev->extra_buf2_len);
584 ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_EXTRA_BUF_HND);
585}
586
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300587
588/* read irq status and ack it */
589static int ene_irq_status(struct ene_device *dev)
590{
591 u8 irq_status;
592 u8 fw_flags1, fw_flags2;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300593 int retval = 0;
594
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300595 fw_flags2 = ene_read_reg(dev, ENE_FW2);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300596
597 if (dev->hw_revision < ENE_HW_C) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300598 irq_status = ene_read_reg(dev, ENEB_IRQ_STATUS);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300599
600 if (!(irq_status & ENEB_IRQ_STATUS_IR))
601 return 0;
602
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300603 ene_clear_reg_mask(dev, ENEB_IRQ_STATUS, ENEB_IRQ_STATUS_IR);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300604 return ENE_IRQ_RX;
605 }
606
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300607 irq_status = ene_read_reg(dev, ENE_IRQ);
608 if (!(irq_status & ENE_IRQ_STATUS))
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300609 return 0;
610
611 /* original driver does that twice - a workaround ? */
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300612 ene_write_reg(dev, ENE_IRQ, irq_status & ~ENE_IRQ_STATUS);
613 ene_write_reg(dev, ENE_IRQ, irq_status & ~ENE_IRQ_STATUS);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300614
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300615 /* check RX interrupt */
616 if (fw_flags2 & ENE_FW2_RXIRQ) {
617 retval |= ENE_IRQ_RX;
618 ene_write_reg(dev, ENE_FW2, fw_flags2 & ~ENE_FW2_RXIRQ);
619 }
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300620
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300621 /* check TX interrupt */
622 fw_flags1 = ene_read_reg(dev, ENE_FW1);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300623 if (fw_flags1 & ENE_FW1_TXIRQ) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300624 ene_write_reg(dev, ENE_FW1, fw_flags1 & ~ENE_FW1_TXIRQ);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300625 retval |= ENE_IRQ_TX;
626 }
627
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300628 return retval;
629}
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300630
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300631/* Read hardware write pointer */
632static void ene_read_hw_pointer(struct ene_device *dev)
633{
634 if (dev->hw_extra_buffer)
635 dev->w_pointer = ene_read_reg(dev, ENE_FW_RX_POINTER);
636 else
637 dev->w_pointer = ene_read_reg(dev, ENE_FW2)
638 & ENE_FW2_BUF_WPTR ? 0 : ENE_FW_PACKET_SIZE;
639
640 dbg_verbose("RB: HW write pointer: %02x, driver read pointer: %02x",
641 dev->w_pointer, dev->r_pointer);
642}
643
644/* Gets address of next sample from HW ring buffer */
645static int ene_get_sample_reg(struct ene_device *dev)
646{
647 int r_pointer;
648
649 if (dev->r_pointer == dev->w_pointer) {
650 dbg_verbose("RB: hit end, try update w_pointer");
651 ene_read_hw_pointer(dev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300652 }
653
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300654 if (dev->r_pointer == dev->w_pointer) {
655 dbg_verbose("RB: end of data at %d", dev->r_pointer);
656 return 0;
657 }
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300658
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300659 dbg_verbose("RB: reading at offset %d", dev->r_pointer);
660 r_pointer = dev->r_pointer;
661
662 dev->r_pointer++;
663 if (dev->r_pointer == dev->buffer_len)
664 dev->r_pointer = 0;
665
666 dbg_verbose("RB: next read will be from offset %d", dev->r_pointer);
667
668 if (r_pointer < 8) {
669 dbg_verbose("RB: read at main buffer at %d", r_pointer);
670 return ENE_FW_SAMPLE_BUFFER + r_pointer;
671 }
672
673 r_pointer -= 8;
674
675 if (r_pointer < dev->extra_buf1_len) {
676 dbg_verbose("RB: read at 1st extra buffer at %d", r_pointer);
677 return dev->extra_buf1_address + r_pointer;
678 }
679
680 r_pointer -= dev->extra_buf1_len;
681
682 if (r_pointer < dev->extra_buf2_len) {
683 dbg_verbose("RB: read at 2nd extra buffer at %d", r_pointer);
684 return dev->extra_buf2_address + r_pointer;
685 }
686
687 dbg("attempt to read beyong ring bufer end");
688 return 0;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300689}
690
691/* interrupt handler */
692static irqreturn_t ene_isr(int irq, void *data)
693{
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300694 u16 hw_value, reg;
695 int hw_sample, irq_status;
696 bool pulse;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300697 unsigned long flags;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300698 irqreturn_t retval = IRQ_NONE;
699 struct ene_device *dev = (struct ene_device *)data;
Maxim Levitsky46519182010-10-16 19:56:28 -0300700 DEFINE_IR_RAW_EVENT(ev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300701
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300702 spin_lock_irqsave(&dev->hw_lock, flags);
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300703
704 dbg_verbose("ISR called");
705 ene_read_hw_pointer(dev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300706 irq_status = ene_irq_status(dev);
707
708 if (!irq_status)
709 goto unlock;
710
711 retval = IRQ_HANDLED;
712
713 if (irq_status & ENE_IRQ_TX) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300714 dbg_verbose("TX interrupt");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300715 if (!dev->hw_learning_and_tx_capable) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300716 dbg("TX interrupt on unsupported device!");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300717 goto unlock;
718 }
719 ene_tx_sample(dev);
720 }
721
722 if (!(irq_status & ENE_IRQ_RX))
723 goto unlock;
724
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300725 dbg_verbose("RX interrupt");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300726
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300727 if (dev->carrier_detect_enabled || debug)
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300728 ene_rx_sense_carrier(dev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300729
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300730 /* On hardware that don't support extra buffer we need to trust
731 the interrupt and not track the read pointer */
732 if (!dev->hw_extra_buffer)
733 dev->r_pointer = dev->w_pointer == 0 ? ENE_FW_PACKET_SIZE : 0;
734
735 while (1) {
736
737 reg = ene_get_sample_reg(dev);
738
739 dbg_verbose("next sample to read at: %04x", reg);
740 if (!reg)
741 break;
742
743 hw_value = ene_read_reg(dev, reg);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300744
745 if (dev->rx_fan_input_inuse) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300746
747 int offset = ENE_FW_SMPL_BUF_FAN - ENE_FW_SAMPLE_BUFFER;
748
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300749 /* read high part of the sample */
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300750 hw_value |= ene_read_reg(dev, reg + offset) << 8;
751 pulse = hw_value & ENE_FW_SMPL_BUF_FAN_PLS;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300752
753 /* clear space bit, and other unused bits */
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300754 hw_value &= ENE_FW_SMPL_BUF_FAN_MSK;
755 hw_sample = hw_value * ENE_FW_SAMPLE_PERIOD_FAN;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300756
757 } else {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300758 pulse = !(hw_value & ENE_FW_SAMPLE_SPACE);
759 hw_value &= ~ENE_FW_SAMPLE_SPACE;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300760 hw_sample = hw_value * sample_period;
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300761
762 if (dev->rx_period_adjust) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300763 hw_sample *= 100;
764 hw_sample /= (100 + dev->rx_period_adjust);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300765 }
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300766 }
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300767
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300768 if (!dev->hw_extra_buffer && !hw_sample) {
769 dev->r_pointer = dev->w_pointer;
770 continue;
771 }
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300772
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300773 dbg("RX: %d (%s)", hw_sample, pulse ? "pulse" : "space");
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300774
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300775 ev.duration = MS_TO_NS(hw_sample);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300776 ev.pulse = pulse;
777 ir_raw_event_store_with_filter(dev->idev, &ev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300778 }
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300779
780 ir_raw_event_handle(dev->idev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300781unlock:
782 spin_unlock_irqrestore(&dev->hw_lock, flags);
783 return retval;
784}
785
786/* Initialize default settings */
787static void ene_setup_settings(struct ene_device *dev)
788{
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300789 dev->tx_period = 32;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300790 dev->tx_duty_cycle = 50; /*%*/
791 dev->transmitter_mask = 0x03;
Maxim Levitskya06423c2010-10-15 13:06:37 -0300792 dev->learning_enabled = learning_mode;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300793
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300794 /* Set reasonable default timeout */
Maxim Levitskya06423c2010-10-15 13:06:37 -0300795 dev->props->timeout = MS_TO_NS(150000);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300796}
797
798/* outside interface: called on first open*/
799static int ene_open(void *data)
800{
801 struct ene_device *dev = (struct ene_device *)data;
802 unsigned long flags;
803
804 spin_lock_irqsave(&dev->hw_lock, flags);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300805 ene_rx_enable(dev);
806 spin_unlock_irqrestore(&dev->hw_lock, flags);
807 return 0;
808}
809
810/* outside interface: called on device close*/
811static void ene_close(void *data)
812{
813 struct ene_device *dev = (struct ene_device *)data;
814 unsigned long flags;
815 spin_lock_irqsave(&dev->hw_lock, flags);
816
817 ene_rx_disable(dev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300818 spin_unlock_irqrestore(&dev->hw_lock, flags);
819}
820
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300821/* outside interface: set transmitter mask */
822static int ene_set_tx_mask(void *data, u32 tx_mask)
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300823{
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300824 struct ene_device *dev = (struct ene_device *)data;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300825 unsigned long flags;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300826 dbg("TX: attempt to set transmitter mask %02x", tx_mask);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300827
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300828 /* invalid txmask */
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300829 if (!tx_mask || tx_mask & ~0x03) {
830 dbg("TX: invalid mask");
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300831 /* return count of transmitters */
832 return 2;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300833 }
834
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300835 spin_lock_irqsave(&dev->hw_lock, flags);
836 dev->transmitter_mask = tx_mask;
837 spin_unlock_irqrestore(&dev->hw_lock, flags);
838 return 0;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300839}
840
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300841/* outside interface : set tx carrier */
842static int ene_set_tx_carrier(void *data, u32 carrier)
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300843{
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300844 struct ene_device *dev = (struct ene_device *)data;
845 unsigned long flags;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300846 u32 period = 2000000 / carrier;
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300847
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300848 dbg("TX: attempt to set tx carrier to %d kHz", carrier);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300849
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300850 if (period && (period > ENE_CIRMOD_PRD_MAX ||
851 period < ENE_CIRMOD_PRD_MIN)) {
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300852
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300853 dbg("TX: out of range %d-%d kHz carrier",
854 2000 / ENE_CIRMOD_PRD_MIN,
855 2000 / ENE_CIRMOD_PRD_MAX);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300856
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300857 return -1;
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300858 }
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300859
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300860 dbg("TX: set carrier to %d kHz", carrier);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300861 spin_lock_irqsave(&dev->hw_lock, flags);
862 dev->tx_period = period;
863 spin_unlock_irqrestore(&dev->hw_lock, flags);
864 return 0;
865}
866
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300867/*outside interface : set tx duty cycle */
868static int ene_set_tx_duty_cycle(void *data, u32 duty_cycle)
869{
870 struct ene_device *dev = (struct ene_device *)data;
871 unsigned long flags;
872
873 dbg("TX: setting duty cycle to %d%%", duty_cycle);
874
875 BUG_ON(!duty_cycle || duty_cycle >= 100);
876
877 spin_lock_irqsave(&dev->hw_lock, flags);
878 dev->tx_duty_cycle = duty_cycle;
879 spin_unlock_irqrestore(&dev->hw_lock, flags);
880 return 0;
881}
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300882
883/* outside interface: enable learning mode */
884static int ene_set_learning_mode(void *data, int enable)
885{
886 struct ene_device *dev = (struct ene_device *)data;
887 unsigned long flags;
888 if (enable == dev->learning_enabled)
889 return 0;
890
891 spin_lock_irqsave(&dev->hw_lock, flags);
892 dev->learning_enabled = enable;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300893 ene_rx_disable(dev);
894 ene_rx_setup(dev);
895 ene_rx_enable(dev);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300896 spin_unlock_irqrestore(&dev->hw_lock, flags);
897 return 0;
898}
899
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300900/* outside interface: enable or disable idle mode */
Maxim Levitsky46519182010-10-16 19:56:28 -0300901static void ene_rx_set_idle(void *data, bool idle)
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300902{
903 struct ene_device *dev = (struct ene_device *)data;
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300904
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300905 if (!idle)
906 return;
907
908 dbg("RX: stopping the receiver");
909 ene_clear_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_RX_EN);
910 ene_set_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_RX_EN);
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300911}
912
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300913/* outside interface: transmit */
914static int ene_transmit(void *data, int *buf, u32 n)
915{
916 struct ene_device *dev = (struct ene_device *)data;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300917 unsigned long flags;
918
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300919 dev->tx_buffer = buf;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300920 dev->tx_len = n / sizeof(int);
921 dev->tx_pos = 0;
922 dev->tx_reg = 0;
923 dev->tx_done = 0;
924 dev->tx_sample = 0;
925 dev->tx_sample_pulse = 0;
926
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300927 dbg("TX: %d samples", dev->tx_len);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300928
929 spin_lock_irqsave(&dev->hw_lock, flags);
930
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300931 ene_tx_prepare(dev);
932
933 /* Transmit first two samples */
934 ene_tx_sample(dev);
935 ene_tx_sample(dev);
936
937 spin_unlock_irqrestore(&dev->hw_lock, flags);
938
939 if (wait_for_completion_timeout(&dev->tx_complete, 2 * HZ) == 0) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300940 dbg("TX: timeout");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300941 spin_lock_irqsave(&dev->hw_lock, flags);
942 ene_tx_complete(dev);
943 spin_unlock_irqrestore(&dev->hw_lock, flags);
944 } else
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300945 dbg("TX: done");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300946 return n;
947}
948
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300949/* probe entry */
950static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300951{
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300952 int error = -ENOMEM;
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300953 struct ir_dev_props *ir_props;
954 struct input_dev *input_dev;
955 struct ene_device *dev;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300956
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300957 /* allocate memory */
958 input_dev = input_allocate_device();
959 ir_props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300960 dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL);
961
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300962 if (!input_dev || !ir_props || !dev)
Jiri Slaby2e75bce2010-10-01 18:13:40 -0300963 goto error1;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300964
965 /* validate resources */
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300966 error = -ENODEV;
967
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300968 if (!pnp_port_valid(pnp_dev, 0) ||
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300969 pnp_port_len(pnp_dev, 0) < ENE_IO_SIZE)
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300970 goto error;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300971
972 if (!pnp_irq_valid(pnp_dev, 0))
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300973 goto error;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300974
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300975 spin_lock_init(&dev->hw_lock);
976
977 /* claim the resources */
978 error = -EBUSY;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300979 dev->hw_io = pnp_port_start(pnp_dev, 0);
980 if (!request_region(dev->hw_io, ENE_IO_SIZE, ENE_DRIVER_NAME)) {
981 dev->hw_io = -1;
982 dev->irq = -1;
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300983 goto error;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300984 }
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300985
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300986 dev->irq = pnp_irq(pnp_dev, 0);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300987 if (request_irq(dev->irq, ene_isr,
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300988 IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev)) {
989 dev->irq = -1;
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300990 goto error;
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300991 }
Maxim Levitsky931e39a2010-07-31 11:59:26 -0300992
993 pnp_set_drvdata(pnp_dev, dev);
994 dev->pnp_dev = pnp_dev;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -0300995
Maxim Levitsky11b64d32010-09-06 18:26:11 -0300996 /* don't allow too short/long sample periods */
997 if (sample_period < 5 || sample_period > 0x7F)
998 sample_period = ENE_DEFAULT_SAMPLE_PERIOD;
999
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001000 /* detect hardware version and features */
1001 error = ene_hw_detect(dev);
1002 if (error)
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001003 goto error;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001004
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001005 if (!dev->hw_learning_and_tx_capable && txsim) {
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001006 dev->hw_learning_and_tx_capable = true;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001007 setup_timer(&dev->tx_sim_timer, ene_tx_irqsim,
1008 (long unsigned int)dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001009 ene_warn("Simulation of TX activated");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001010 }
1011
Maxim Levitskya06423c2010-10-15 13:06:37 -03001012 if (!dev->hw_learning_and_tx_capable)
1013 learning_mode = false;
1014
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001015 ir_props->driver_type = RC_DRIVER_IR_RAW;
1016 ir_props->allowed_protos = IR_TYPE_ALL;
1017 ir_props->priv = dev;
1018 ir_props->open = ene_open;
1019 ir_props->close = ene_close;
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001020 ir_props->s_idle = ene_rx_set_idle;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001021
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001022 dev->props = ir_props;
1023 dev->idev = input_dev;
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001024
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001025 if (dev->hw_learning_and_tx_capable) {
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001026 ir_props->s_learning_mode = ene_set_learning_mode;
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001027 init_completion(&dev->tx_complete);
1028 ir_props->tx_ir = ene_transmit;
1029 ir_props->s_tx_mask = ene_set_tx_mask;
1030 ir_props->s_tx_carrier = ene_set_tx_carrier;
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001031 ir_props->s_tx_duty_cycle = ene_set_tx_duty_cycle;
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001032 /* ir_props->s_carrier_report = ene_set_carrier_report; */
1033 }
1034
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001035 ene_setup_hw_buffer(dev);
1036 ene_setup_settings(dev);
1037 ene_rx_setup(dev);
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001038
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001039 device_set_wakeup_capable(&pnp_dev->dev, true);
1040 device_set_wakeup_enable(&pnp_dev->dev, true);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001041
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001042 if (dev->hw_learning_and_tx_capable)
1043 input_dev->name = "ENE eHome Infrared Remote Transceiver";
1044 else
1045 input_dev->name = "ENE eHome Infrared Remote Receiver";
1046
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001047 error = -ENODEV;
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001048 if (ir_input_register(input_dev, RC_MAP_RC6_MCE, ir_props,
1049 ENE_DRIVER_NAME))
1050 goto error;
1051
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001052 ene_notice("driver has been succesfully loaded");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001053 return 0;
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001054error:
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001055 if (dev && dev->irq >= 0)
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001056 free_irq(dev->irq, dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001057 if (dev && dev->hw_io >= 0)
1058 release_region(dev->hw_io, ENE_IO_SIZE);
Jiri Slaby2e75bce2010-10-01 18:13:40 -03001059error1:
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001060 input_free_device(input_dev);
1061 kfree(ir_props);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001062 kfree(dev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001063 return error;
1064}
1065
1066/* main unload function */
1067static void ene_remove(struct pnp_dev *pnp_dev)
1068{
1069 struct ene_device *dev = pnp_get_drvdata(pnp_dev);
1070 unsigned long flags;
1071
1072 spin_lock_irqsave(&dev->hw_lock, flags);
1073 ene_rx_disable(dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001074 ene_restore_extra_buffer(dev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001075 spin_unlock_irqrestore(&dev->hw_lock, flags);
1076
1077 free_irq(dev->irq, dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001078 release_region(dev->hw_io, ENE_IO_SIZE);
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001079 ir_input_unregister(dev->idev);
1080 kfree(dev->props);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001081 kfree(dev);
1082}
1083
1084/* enable wake on IR (wakes on specific button on original remote) */
1085static void ene_enable_wake(struct ene_device *dev, int enable)
1086{
1087 enable = enable && device_may_wakeup(&dev->pnp_dev->dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001088 dbg("wake on IR %s", enable ? "enabled" : "disabled");
1089 ene_set_clear_reg_mask(dev, ENE_FW1, ENE_FW1_WAKE, enable);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001090}
1091
1092#ifdef CONFIG_PM
1093static int ene_suspend(struct pnp_dev *pnp_dev, pm_message_t state)
1094{
1095 struct ene_device *dev = pnp_get_drvdata(pnp_dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001096 ene_enable_wake(dev, true);
1097
1098 /* TODO: add support for wake pattern */
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001099 return 0;
1100}
1101
1102static int ene_resume(struct pnp_dev *pnp_dev)
1103{
1104 struct ene_device *dev = pnp_get_drvdata(pnp_dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001105 if (dev->rx_enabled) {
1106 ene_rx_setup(dev);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001107 ene_rx_enable(dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001108 }
1109 ene_enable_wake(dev, false);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001110 return 0;
1111}
1112#endif
1113
1114static void ene_shutdown(struct pnp_dev *pnp_dev)
1115{
1116 struct ene_device *dev = pnp_get_drvdata(pnp_dev);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001117 ene_enable_wake(dev, true);
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001118}
1119
1120static const struct pnp_device_id ene_ids[] = {
1121 {.id = "ENE0100",},
1122 {.id = "ENE0200",},
1123 {.id = "ENE0201",},
Maxim Levitsky931e39a2010-07-31 11:59:26 -03001124 {.id = "ENE0202",},
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001125 {},
1126};
1127
1128static struct pnp_driver ene_driver = {
1129 .name = ENE_DRIVER_NAME,
1130 .id_table = ene_ids,
1131 .flags = PNP_DRIVER_RES_DO_NOT_CHANGE,
1132
1133 .probe = ene_probe,
1134 .remove = __devexit_p(ene_remove),
1135#ifdef CONFIG_PM
1136 .suspend = ene_suspend,
1137 .resume = ene_resume,
1138#endif
1139 .shutdown = ene_shutdown,
1140};
1141
1142static int __init ene_init(void)
1143{
1144 return pnp_register_driver(&ene_driver);
1145}
1146
1147static void ene_exit(void)
1148{
1149 pnp_unregister_driver(&ene_driver);
1150}
1151
1152module_param(sample_period, int, S_IRUGO);
1153MODULE_PARM_DESC(sample_period, "Hardware sample period (50 us default)");
1154
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001155module_param(learning_mode, bool, S_IRUGO);
1156MODULE_PARM_DESC(learning_mode, "Enable learning mode by default");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001157
1158module_param(debug, int, S_IRUGO | S_IWUSR);
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001159MODULE_PARM_DESC(debug, "Debug level");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001160
1161module_param(txsim, bool, S_IRUGO);
1162MODULE_PARM_DESC(txsim,
1163 "Simulate TX features on unsupported hardware (dangerous)");
1164
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001165MODULE_DEVICE_TABLE(pnp, ene_ids);
1166MODULE_DESCRIPTION
Maxim Levitsky11b64d32010-09-06 18:26:11 -03001167 ("Infrared input driver for KB3926B/C/D/E/F "
1168 "(aka ENE0100/ENE0200/ENE0201/ENE0202) CIR port");
Maxim Levitsky9ea53b72010-07-31 11:59:25 -03001169
1170MODULE_AUTHOR("Maxim Levitsky");
1171MODULE_LICENSE("GPL");
1172
1173module_init(ene_init);
1174module_exit(ene_exit);