diff options
author | Rodrigo Tartajo <rtarty@gmail.com> | 2013-04-20 19:02:12 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-06-08 20:54:53 -0400 |
commit | 1e41413f9869c4a688b2f937ff50584bd62eeb31 (patch) | |
tree | 553cbbbc533ccff04816e64553f52c4f55c99056 /drivers/media/usb/dvb-usb-v2/rtl28xxu.c | |
parent | 1bddf1b3ac021feb9dafcc2c6ef7018453e22589 (diff) |
[media] rtl2832u: restore ir remote control support
Hi,
This patch uses the driver from openpli[1] as a template to restore the remote control support.
I had to divert from the original to use the in kernel rc protocol decoder. The key repetition does,
not seem to work but I cant find the problem in the driver. As a raw rc provider, no key table is
hardcoded.
Rodrigo.
[1]: https://aur.archlinux.org/packages/dvb-usb-rtl2832u-openpli/?comments=all
Signed-off-by: Rodrigo Tartajo <rtarty@gmail.com>
Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/usb/dvb-usb-v2/rtl28xxu.c')
-rw-r--r-- | drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 83 |
1 files changed, 71 insertions, 12 deletions
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 22015fe1a0f3..e592662ccc06 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c | |||
@@ -1249,11 +1249,21 @@ static int rtl2831u_get_rc_config(struct dvb_usb_device *d, | |||
1249 | #if IS_ENABLED(CONFIG_RC_CORE) | 1249 | #if IS_ENABLED(CONFIG_RC_CORE) |
1250 | static int rtl2832u_rc_query(struct dvb_usb_device *d) | 1250 | static int rtl2832u_rc_query(struct dvb_usb_device *d) |
1251 | { | 1251 | { |
1252 | #define TICSAT38KHZTONS(x) ((x) * (1000000000/38000)) | ||
1252 | int ret, i; | 1253 | int ret, i; |
1253 | struct rtl28xxu_priv *priv = d->priv; | 1254 | struct rtl28xxu_priv *priv = d->priv; |
1254 | u8 buf[128]; | 1255 | u8 buf[128]; |
1255 | int len; | 1256 | int len; |
1256 | struct rtl28xxu_reg_val rc_nec_tab[] = { | 1257 | struct ir_raw_event ev; //encode single ir event (pulse or space) |
1258 | struct rtl28xxu_xreg_val rc_sys_init_tab[] = { | ||
1259 | { SYS_DEMOD_CTL1, OP_AND, 0xfb }, | ||
1260 | { SYS_DEMOD_CTL1, OP_AND, 0xf7 }, | ||
1261 | { USB_CTRL, OP_OR , 0x20 }, | ||
1262 | { SYS_SYS1, OP_AND, 0xf7 }, | ||
1263 | { SYS_GPIO_OUT_EN, OP_OR , 0x08 }, | ||
1264 | { SYS_GPIO_OUT_VAL, OP_OR , 0x08 }, | ||
1265 | }; // system hard init | ||
1266 | struct rtl28xxu_reg_val rc_init_tab[] = { | ||
1257 | { IR_RX_CTRL, 0x20 }, | 1267 | { IR_RX_CTRL, 0x20 }, |
1258 | { IR_RX_BUF_CTRL, 0x80 }, | 1268 | { IR_RX_BUF_CTRL, 0x80 }, |
1259 | { IR_RX_IF, 0xff }, | 1269 | { IR_RX_IF, 0xff }, |
@@ -1268,13 +1278,40 @@ static int rtl2832u_rc_query(struct dvb_usb_device *d) | |||
1268 | { IR_MAX_H_TOL_LEN, 0x1e }, | 1278 | { IR_MAX_H_TOL_LEN, 0x1e }, |
1269 | { IR_MAX_L_TOL_LEN, 0x1e }, | 1279 | { IR_MAX_L_TOL_LEN, 0x1e }, |
1270 | { IR_RX_CTRL, 0x80 }, | 1280 | { IR_RX_CTRL, 0x80 }, |
1271 | }; | 1281 | }; // hard init |
1282 | struct rtl28xxu_reg_val rc_reinit_tab[] = { | ||
1283 | { IR_RX_CTRL, 0x20 }, | ||
1284 | { IR_RX_BUF_CTRL, 0x80 }, | ||
1285 | { IR_RX_IF, 0xff }, | ||
1286 | { IR_RX_IE, 0xff }, | ||
1287 | { IR_RX_CTRL, 0x80 }, | ||
1288 | }; // reinit IR | ||
1289 | struct rtl28xxu_reg_val rc_clear_tab[] = { | ||
1290 | { IR_RX_IF, 0x03 }, | ||
1291 | { IR_RX_BUF_CTRL, 0x80 }, | ||
1292 | { IR_RX_CTRL, 0x80 }, | ||
1293 | }; // clear reception | ||
1272 | 1294 | ||
1273 | /* init remote controller */ | 1295 | /* init remote controller */ |
1274 | if (!priv->rc_active) { | 1296 | if (!priv->rc_active) { |
1275 | for (i = 0; i < ARRAY_SIZE(rc_nec_tab); i++) { | 1297 | for (i = 0; i < ARRAY_SIZE(rc_sys_init_tab); i++) { |
1276 | ret = rtl28xx_wr_reg(d, rc_nec_tab[i].reg, | 1298 | ret = rtl28xx_rd_reg(d, rc_sys_init_tab[i].reg, &buf[0]); |
1277 | rc_nec_tab[i].val); | 1299 | if (ret) |
1300 | goto err; | ||
1301 | if (rc_sys_init_tab[i].op == OP_AND) { | ||
1302 | buf[0] &= rc_sys_init_tab[i].mask; | ||
1303 | } | ||
1304 | else {//OP_OR | ||
1305 | buf[0] |= rc_sys_init_tab[i].mask; | ||
1306 | } | ||
1307 | ret = rtl28xx_wr_reg(d, rc_sys_init_tab[i].reg, | ||
1308 | buf[0]); | ||
1309 | if (ret) | ||
1310 | goto err; | ||
1311 | } | ||
1312 | for (i = 0; i < ARRAY_SIZE(rc_init_tab); i++) { | ||
1313 | ret = rtl28xx_wr_reg(d, rc_init_tab[i].reg, | ||
1314 | rc_init_tab[i].val); | ||
1278 | if (ret) | 1315 | if (ret) |
1279 | goto err; | 1316 | goto err; |
1280 | } | 1317 | } |
@@ -1286,7 +1323,7 @@ static int rtl2832u_rc_query(struct dvb_usb_device *d) | |||
1286 | goto err; | 1323 | goto err; |
1287 | 1324 | ||
1288 | if (buf[0] != 0x83) | 1325 | if (buf[0] != 0x83) |
1289 | goto exit; | 1326 | goto err; |
1290 | 1327 | ||
1291 | ret = rtl28xx_rd_reg(d, IR_RX_BC, &buf[0]); | 1328 | ret = rtl28xx_rd_reg(d, IR_RX_BC, &buf[0]); |
1292 | if (ret) | 1329 | if (ret) |
@@ -1295,26 +1332,48 @@ static int rtl2832u_rc_query(struct dvb_usb_device *d) | |||
1295 | len = buf[0]; | 1332 | len = buf[0]; |
1296 | ret = rtl2831_rd_regs(d, IR_RX_BUF, buf, len); | 1333 | ret = rtl2831_rd_regs(d, IR_RX_BUF, buf, len); |
1297 | 1334 | ||
1298 | /* TODO: pass raw IR to Kernel IR decoder */ | 1335 | /* pass raw IR to Kernel IR decoder */ |
1336 | init_ir_raw_event(&ev); | ||
1337 | ir_raw_event_reset(d->rc_dev); | ||
1338 | ev.pulse=1; | ||
1339 | for(i=0; true; ++i) { // conver count to time | ||
1340 | if (i >= len || !(buf[i] & 0x80) != !(ev.pulse)) {//end or transition pulse/space: flush | ||
1341 | ir_raw_event_store(d->rc_dev, &ev); | ||
1342 | ev.duration = 0; | ||
1343 | } | ||
1344 | if (i >= len) | ||
1345 | break; | ||
1346 | ev.pulse = buf[i] >> 7; | ||
1347 | ev.duration += TICSAT38KHZTONS(((u32)(buf[i] & 0x7F)) << 1); | ||
1348 | } | ||
1349 | ir_raw_event_handle(d->rc_dev); | ||
1299 | 1350 | ||
1300 | ret = rtl28xx_wr_reg(d, IR_RX_IF, 0x03); | 1351 | for (i = 0; i < ARRAY_SIZE(rc_clear_tab); i++) { |
1301 | ret = rtl28xx_wr_reg(d, IR_RX_BUF_CTRL, 0x80); | 1352 | ret = rtl28xx_wr_reg(d, rc_clear_tab[i].reg, |
1302 | ret = rtl28xx_wr_reg(d, IR_RX_CTRL, 0x80); | 1353 | rc_clear_tab[i].val); |
1354 | if (ret) | ||
1355 | goto err; | ||
1356 | } | ||
1303 | 1357 | ||
1304 | exit: | ||
1305 | return ret; | 1358 | return ret; |
1306 | err: | 1359 | err: |
1360 | for (i = 0; i < ARRAY_SIZE(rc_reinit_tab); i++) { | ||
1361 | ret = rtl28xx_wr_reg(d, rc_reinit_tab[i].reg, | ||
1362 | rc_reinit_tab[i].val); | ||
1363 | } | ||
1307 | dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); | 1364 | dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); |
1308 | return ret; | 1365 | return ret; |
1366 | #undef TICSAT38KHZTONS | ||
1309 | } | 1367 | } |
1310 | 1368 | ||
1311 | static int rtl2832u_get_rc_config(struct dvb_usb_device *d, | 1369 | static int rtl2832u_get_rc_config(struct dvb_usb_device *d, |
1312 | struct dvb_usb_rc *rc) | 1370 | struct dvb_usb_rc *rc) |
1313 | { | 1371 | { |
1314 | rc->map_name = RC_MAP_EMPTY; | 1372 | rc->map_name = RC_MAP_EMPTY; |
1315 | rc->allowed_protos = RC_BIT_NEC; | 1373 | rc->allowed_protos = RC_BIT_ALL; |
1316 | rc->query = rtl2832u_rc_query; | 1374 | rc->query = rtl2832u_rc_query; |
1317 | rc->interval = 400; | 1375 | rc->interval = 400; |
1376 | rc->driver_type = RC_DRIVER_IR_RAW; | ||
1318 | 1377 | ||
1319 | return 0; | 1378 | return 0; |
1320 | } | 1379 | } |