aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/misc/winbond-cir.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/misc/winbond-cir.c')
-rw-r--r--drivers/input/misc/winbond-cir.c213
1 files changed, 104 insertions, 109 deletions
diff --git a/drivers/input/misc/winbond-cir.c b/drivers/input/misc/winbond-cir.c
index c8f5a9a3fa14..cbec3dfdd42b 100644
--- a/drivers/input/misc/winbond-cir.c
+++ b/drivers/input/misc/winbond-cir.c
@@ -538,6 +538,7 @@ wbcir_reset_irdata(struct wbcir_data *data)
538 data->irdata_count = 0; 538 data->irdata_count = 0;
539 data->irdata_off = 0; 539 data->irdata_off = 0;
540 data->irdata_error = 0; 540 data->irdata_error = 0;
541 data->idle_count = 0;
541} 542}
542 543
543/* Adds one bit of irdata */ 544/* Adds one bit of irdata */
@@ -1006,7 +1007,6 @@ wbcir_irq_handler(int irqno, void *cookie)
1006 } 1007 }
1007 1008
1008 wbcir_reset_irdata(data); 1009 wbcir_reset_irdata(data);
1009 data->idle_count = 0;
1010 } 1010 }
1011 1011
1012out: 1012out:
@@ -1018,7 +1018,7 @@ out:
1018 1018
1019/***************************************************************************** 1019/*****************************************************************************
1020 * 1020 *
1021 * SUSPEND/RESUME FUNCTIONS 1021 * SETUP/INIT/SUSPEND/RESUME FUNCTIONS
1022 * 1022 *
1023 *****************************************************************************/ 1023 *****************************************************************************/
1024 1024
@@ -1197,7 +1197,16 @@ finish:
1197 } 1197 }
1198 1198
1199 /* Disable interrupts */ 1199 /* Disable interrupts */
1200 wbcir_select_bank(data, WBCIR_BANK_0);
1200 outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); 1201 outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
1202
1203 /*
1204 * ACPI will set the HW disable bit for SP3 which means that the
1205 * output signals are left in an undefined state which may cause
1206 * spurious interrupts which we need to ignore until the hardware
1207 * is reinitialized.
1208 */
1209 disable_irq(data->irq);
1201} 1210}
1202 1211
1203static int 1212static int
@@ -1207,37 +1216,15 @@ wbcir_suspend(struct pnp_dev *device, pm_message_t state)
1207 return 0; 1216 return 0;
1208} 1217}
1209 1218
1210static int
1211wbcir_resume(struct pnp_dev *device)
1212{
1213 struct wbcir_data *data = pnp_get_drvdata(device);
1214
1215 /* Clear BUFF_EN, Clear END_EN, Clear MATCH_EN */
1216 wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07);
1217
1218 /* Clear CEIR_EN */
1219 wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x00, 0x01);
1220
1221 /* Enable interrupts */
1222 wbcir_reset_irdata(data);
1223 outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER);
1224
1225 return 0;
1226}
1227
1228
1229
1230/*****************************************************************************
1231 *
1232 * SETUP/INIT FUNCTIONS
1233 *
1234 *****************************************************************************/
1235
1236static void 1219static void
1237wbcir_cfg_ceir(struct wbcir_data *data) 1220wbcir_init_hw(struct wbcir_data *data)
1238{ 1221{
1239 u8 tmp; 1222 u8 tmp;
1240 1223
1224 /* Disable interrupts */
1225 wbcir_select_bank(data, WBCIR_BANK_0);
1226 outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
1227
1241 /* Set PROT_SEL, RX_INV, Clear CEIR_EN (needed for the led) */ 1228 /* Set PROT_SEL, RX_INV, Clear CEIR_EN (needed for the led) */
1242 tmp = protocol << 4; 1229 tmp = protocol << 4;
1243 if (invert) 1230 if (invert)
@@ -1264,6 +1251,93 @@ wbcir_cfg_ceir(struct wbcir_data *data)
1264 * set SP3_IRRX_SW to binary 01, helpfully not documented 1251 * set SP3_IRRX_SW to binary 01, helpfully not documented
1265 */ 1252 */
1266 outb(0x10, data->ebase + WBCIR_REG_ECEIR_CTS); 1253 outb(0x10, data->ebase + WBCIR_REG_ECEIR_CTS);
1254
1255 /* Enable extended mode */
1256 wbcir_select_bank(data, WBCIR_BANK_2);
1257 outb(WBCIR_EXT_ENABLE, data->sbase + WBCIR_REG_SP3_EXCR1);
1258
1259 /*
1260 * Configure baud generator, IR data will be sampled at
1261 * a bitrate of: (24Mhz * prescaler) / (divisor * 16).
1262 *
1263 * The ECIR registers include a flag to change the
1264 * 24Mhz clock freq to 48Mhz.
1265 *
1266 * It's not documented in the specs, but fifo levels
1267 * other than 16 seems to be unsupported.
1268 */
1269
1270 /* prescaler 1.0, tx/rx fifo lvl 16 */
1271 outb(0x30, data->sbase + WBCIR_REG_SP3_EXCR2);
1272
1273 /* Set baud divisor to generate one byte per bit/cell */
1274 switch (protocol) {
1275 case IR_PROTOCOL_RC5:
1276 outb(0xA7, data->sbase + WBCIR_REG_SP3_BGDL);
1277 break;
1278 case IR_PROTOCOL_RC6:
1279 outb(0x53, data->sbase + WBCIR_REG_SP3_BGDL);
1280 break;
1281 case IR_PROTOCOL_NEC:
1282 outb(0x69, data->sbase + WBCIR_REG_SP3_BGDL);
1283 break;
1284 }
1285 outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH);
1286
1287 /* Set CEIR mode */
1288 wbcir_select_bank(data, WBCIR_BANK_0);
1289 outb(0xC0, data->sbase + WBCIR_REG_SP3_MCR);
1290 inb(data->sbase + WBCIR_REG_SP3_LSR); /* Clear LSR */
1291 inb(data->sbase + WBCIR_REG_SP3_MSR); /* Clear MSR */
1292
1293 /* Disable RX demod, run-length encoding/decoding, set freq span */
1294 wbcir_select_bank(data, WBCIR_BANK_7);
1295 outb(0x10, data->sbase + WBCIR_REG_SP3_RCCFG);
1296
1297 /* Disable timer */
1298 wbcir_select_bank(data, WBCIR_BANK_4);
1299 outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1);
1300
1301 /* Enable MSR interrupt, Clear AUX_IRX */
1302 wbcir_select_bank(data, WBCIR_BANK_5);
1303 outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR2);
1304
1305 /* Disable CRC */
1306 wbcir_select_bank(data, WBCIR_BANK_6);
1307 outb(0x20, data->sbase + WBCIR_REG_SP3_IRCR3);
1308
1309 /* Set RX/TX (de)modulation freq, not really used */
1310 wbcir_select_bank(data, WBCIR_BANK_7);
1311 outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC);
1312 outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC);
1313
1314 /* Set invert and pin direction */
1315 if (invert)
1316 outb(0x10, data->sbase + WBCIR_REG_SP3_IRCFG4);
1317 else
1318 outb(0x00, data->sbase + WBCIR_REG_SP3_IRCFG4);
1319
1320 /* Set FIFO thresholds (RX = 8, TX = 3), reset RX/TX */
1321 wbcir_select_bank(data, WBCIR_BANK_0);
1322 outb(0x97, data->sbase + WBCIR_REG_SP3_FCR);
1323
1324 /* Clear AUX status bits */
1325 outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR);
1326
1327 /* Enable interrupts */
1328 wbcir_reset_irdata(data);
1329 outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER);
1330}
1331
1332static int
1333wbcir_resume(struct pnp_dev *device)
1334{
1335 struct wbcir_data *data = pnp_get_drvdata(device);
1336
1337 wbcir_init_hw(data);
1338 enable_irq(data->irq);
1339
1340 return 0;
1267} 1341}
1268 1342
1269static int __devinit 1343static int __devinit
@@ -1393,86 +1467,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
1393 1467
1394 device_init_wakeup(&device->dev, 1); 1468 device_init_wakeup(&device->dev, 1);
1395 1469
1396 wbcir_cfg_ceir(data); 1470 wbcir_init_hw(data);
1397
1398 /* Disable interrupts */
1399 wbcir_select_bank(data, WBCIR_BANK_0);
1400 outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
1401
1402 /* Enable extended mode */
1403 wbcir_select_bank(data, WBCIR_BANK_2);
1404 outb(WBCIR_EXT_ENABLE, data->sbase + WBCIR_REG_SP3_EXCR1);
1405
1406 /*
1407 * Configure baud generator, IR data will be sampled at
1408 * a bitrate of: (24Mhz * prescaler) / (divisor * 16).
1409 *
1410 * The ECIR registers include a flag to change the
1411 * 24Mhz clock freq to 48Mhz.
1412 *
1413 * It's not documented in the specs, but fifo levels
1414 * other than 16 seems to be unsupported.
1415 */
1416
1417 /* prescaler 1.0, tx/rx fifo lvl 16 */
1418 outb(0x30, data->sbase + WBCIR_REG_SP3_EXCR2);
1419
1420 /* Set baud divisor to generate one byte per bit/cell */
1421 switch (protocol) {
1422 case IR_PROTOCOL_RC5:
1423 outb(0xA7, data->sbase + WBCIR_REG_SP3_BGDL);
1424 break;
1425 case IR_PROTOCOL_RC6:
1426 outb(0x53, data->sbase + WBCIR_REG_SP3_BGDL);
1427 break;
1428 case IR_PROTOCOL_NEC:
1429 outb(0x69, data->sbase + WBCIR_REG_SP3_BGDL);
1430 break;
1431 }
1432 outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH);
1433
1434 /* Set CEIR mode */
1435 wbcir_select_bank(data, WBCIR_BANK_0);
1436 outb(0xC0, data->sbase + WBCIR_REG_SP3_MCR);
1437 inb(data->sbase + WBCIR_REG_SP3_LSR); /* Clear LSR */
1438 inb(data->sbase + WBCIR_REG_SP3_MSR); /* Clear MSR */
1439
1440 /* Disable RX demod, run-length encoding/decoding, set freq span */
1441 wbcir_select_bank(data, WBCIR_BANK_7);
1442 outb(0x10, data->sbase + WBCIR_REG_SP3_RCCFG);
1443
1444 /* Disable timer */
1445 wbcir_select_bank(data, WBCIR_BANK_4);
1446 outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1);
1447
1448 /* Enable MSR interrupt, Clear AUX_IRX */
1449 wbcir_select_bank(data, WBCIR_BANK_5);
1450 outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR2);
1451
1452 /* Disable CRC */
1453 wbcir_select_bank(data, WBCIR_BANK_6);
1454 outb(0x20, data->sbase + WBCIR_REG_SP3_IRCR3);
1455
1456 /* Set RX/TX (de)modulation freq, not really used */
1457 wbcir_select_bank(data, WBCIR_BANK_7);
1458 outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC);
1459 outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC);
1460
1461 /* Set invert and pin direction */
1462 if (invert)
1463 outb(0x10, data->sbase + WBCIR_REG_SP3_IRCFG4);
1464 else
1465 outb(0x00, data->sbase + WBCIR_REG_SP3_IRCFG4);
1466
1467 /* Set FIFO thresholds (RX = 8, TX = 3), reset RX/TX */
1468 wbcir_select_bank(data, WBCIR_BANK_0);
1469 outb(0x97, data->sbase + WBCIR_REG_SP3_FCR);
1470
1471 /* Clear AUX status bits */
1472 outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR);
1473
1474 /* Enable interrupts */
1475 outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER);
1476 1471
1477 return 0; 1472 return 0;
1478 1473