aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
diff options
context:
space:
mode:
authorAntti Palosaari <crope@iki.fi>2013-06-04 08:17:03 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-06-08 20:55:38 -0400
commitf39fac3e409322d23261e89374a7d9daecfd6acb (patch)
treee8e3c74db32393da66f3939bda145ae5a0ebd2bd /drivers/media/usb/dvb-usb-v2/rtl28xxu.c
parent1e41413f9869c4a688b2f937ff50584bd62eeb31 (diff)
[media] rtl28xxu: reimplement rtl2832u remote controller
Thanks to Rodrigo for original implementation! 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.c152
1 files changed, 56 insertions, 96 deletions
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index e592662ccc06..416701167434 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -1114,17 +1114,6 @@ static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff)
1114 if (ret) 1114 if (ret)
1115 goto err; 1115 goto err;
1116 } else { 1116 } else {
1117 /* demod_ctl_1 */
1118 ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL1, &val);
1119 if (ret)
1120 goto err;
1121
1122 val |= 0x0c;
1123
1124 ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL1, val);
1125 if (ret)
1126 goto err;
1127
1128 /* set output values */ 1117 /* set output values */
1129 ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val); 1118 ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val);
1130 if (ret) 1119 if (ret)
@@ -1249,72 +1238,44 @@ static int rtl2831u_get_rc_config(struct dvb_usb_device *d,
1249#if IS_ENABLED(CONFIG_RC_CORE) 1238#if IS_ENABLED(CONFIG_RC_CORE)
1250static int rtl2832u_rc_query(struct dvb_usb_device *d) 1239static int rtl2832u_rc_query(struct dvb_usb_device *d)
1251{ 1240{
1252#define TICSAT38KHZTONS(x) ((x) * (1000000000/38000)) 1241 int ret, i, len;
1253 int ret, i;
1254 struct rtl28xxu_priv *priv = d->priv; 1242 struct rtl28xxu_priv *priv = d->priv;
1243 struct ir_raw_event ev;
1255 u8 buf[128]; 1244 u8 buf[128];
1256 int len; 1245 static const struct rtl28xxu_reg_val_mask refresh_tab[] = {
1257 struct ir_raw_event ev; //encode single ir event (pulse or space) 1246 {IR_RX_IF, 0x03, 0xff},
1258 struct rtl28xxu_xreg_val rc_sys_init_tab[] = { 1247 {IR_RX_BUF_CTRL, 0x80, 0xff},
1259 { SYS_DEMOD_CTL1, OP_AND, 0xfb }, 1248 {IR_RX_CTRL, 0x80, 0xff},
1260 { SYS_DEMOD_CTL1, OP_AND, 0xf7 }, 1249 };
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[] = {
1267 { IR_RX_CTRL, 0x20 },
1268 { IR_RX_BUF_CTRL, 0x80 },
1269 { IR_RX_IF, 0xff },
1270 { IR_RX_IE, 0xff },
1271 { IR_MAX_DURATION0, 0xd0 },
1272 { IR_MAX_DURATION1, 0x07 },
1273 { IR_IDLE_LEN0, 0xc0 },
1274 { IR_IDLE_LEN1, 0x00 },
1275 { IR_GLITCH_LEN, 0x03 },
1276 { IR_RX_CLK, 0x09 },
1277 { IR_RX_CFG, 0x1c },
1278 { IR_MAX_H_TOL_LEN, 0x1e },
1279 { IR_MAX_L_TOL_LEN, 0x1e },
1280 { IR_RX_CTRL, 0x80 },
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
1294 1250
1295 /* init remote controller */ 1251 /* init remote controller */
1296 if (!priv->rc_active) { 1252 if (!priv->rc_active) {
1297 for (i = 0; i < ARRAY_SIZE(rc_sys_init_tab); i++) { 1253 static const struct rtl28xxu_reg_val_mask init_tab[] = {
1298 ret = rtl28xx_rd_reg(d, rc_sys_init_tab[i].reg, &buf[0]); 1254 {SYS_DEMOD_CTL1, 0x00, 0x04},
1299 if (ret) 1255 {SYS_DEMOD_CTL1, 0x00, 0x08},
1300 goto err; 1256 {USB_CTRL, 0x20, 0x20},
1301 if (rc_sys_init_tab[i].op == OP_AND) { 1257 {SYS_GPIO_DIR, 0x00, 0x08},
1302 buf[0] &= rc_sys_init_tab[i].mask; 1258 {SYS_GPIO_OUT_EN, 0x08, 0x08},
1303 } 1259 {SYS_GPIO_OUT_VAL, 0x08, 0x08},
1304 else {//OP_OR 1260 {IR_MAX_DURATION0, 0xd0, 0xff},
1305 buf[0] |= rc_sys_init_tab[i].mask; 1261 {IR_MAX_DURATION1, 0x07, 0xff},
1306 } 1262 {IR_IDLE_LEN0, 0xc0, 0xff},
1307 ret = rtl28xx_wr_reg(d, rc_sys_init_tab[i].reg, 1263 {IR_IDLE_LEN1, 0x00, 0xff},
1308 buf[0]); 1264 {IR_GLITCH_LEN, 0x03, 0xff},
1309 if (ret) 1265 {IR_RX_CLK, 0x09, 0xff},
1310 goto err; 1266 {IR_RX_CFG, 0x1c, 0xff},
1311 } 1267 {IR_MAX_H_TOL_LEN, 0x1e, 0xff},
1312 for (i = 0; i < ARRAY_SIZE(rc_init_tab); i++) { 1268 {IR_MAX_L_TOL_LEN, 0x1e, 0xff},
1313 ret = rtl28xx_wr_reg(d, rc_init_tab[i].reg, 1269 {IR_RX_CTRL, 0x80, 0xff},
1314 rc_init_tab[i].val); 1270 };
1271
1272 for (i = 0; i < ARRAY_SIZE(init_tab); i++) {
1273 ret = rtl28xx_wr_reg_mask(d, init_tab[i].reg,
1274 init_tab[i].val, init_tab[i].mask);
1315 if (ret) 1275 if (ret)
1316 goto err; 1276 goto err;
1317 } 1277 }
1278
1318 priv->rc_active = true; 1279 priv->rc_active = true;
1319 } 1280 }
1320 1281
@@ -1323,57 +1284,56 @@ static int rtl2832u_rc_query(struct dvb_usb_device *d)
1323 goto err; 1284 goto err;
1324 1285
1325 if (buf[0] != 0x83) 1286 if (buf[0] != 0x83)
1326 goto err; 1287 goto exit;
1327 1288
1328 ret = rtl28xx_rd_reg(d, IR_RX_BC, &buf[0]); 1289 ret = rtl28xx_rd_reg(d, IR_RX_BC, &buf[0]);
1329 if (ret) 1290 if (ret)
1330 goto err; 1291 goto err;
1331 1292
1332 len = buf[0]; 1293 len = buf[0];
1333 ret = rtl2831_rd_regs(d, IR_RX_BUF, buf, len);
1334 1294
1335 /* pass raw IR to Kernel IR decoder */ 1295 /* read raw code from hw */
1336 init_ir_raw_event(&ev); 1296 ret = rtl2831_rd_regs(d, IR_RX_BUF, buf, len);
1337 ir_raw_event_reset(d->rc_dev); 1297 if (ret)
1338 ev.pulse=1; 1298 goto err;
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);
1350 1299
1351 for (i = 0; i < ARRAY_SIZE(rc_clear_tab); i++) { 1300 /* let hw receive new code */
1352 ret = rtl28xx_wr_reg(d, rc_clear_tab[i].reg, 1301 for (i = 0; i < ARRAY_SIZE(refresh_tab); i++) {
1353 rc_clear_tab[i].val); 1302 ret = rtl28xx_wr_reg_mask(d, refresh_tab[i].reg,
1303 refresh_tab[i].val, refresh_tab[i].mask);
1354 if (ret) 1304 if (ret)
1355 goto err; 1305 goto err;
1356 } 1306 }
1357 1307
1308 /* pass data to Kernel IR decoder */
1309 init_ir_raw_event(&ev);
1310
1311 for (i = 0; i < len; i++) {
1312 ev.pulse = buf[i] >> 7;
1313 ev.duration = 50800 * (buf[i] & 0x7f);
1314 ir_raw_event_store_with_filter(d->rc_dev, &ev);
1315 }
1316
1317 /* 'flush' ir_raw_event_store_with_filter() */
1318 ir_raw_event_set_idle(d->rc_dev, true);
1319 ir_raw_event_handle(d->rc_dev);
1320exit:
1358 return ret; 1321 return ret;
1359err: 1322err:
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 }
1364 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); 1323 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
1365 return ret; 1324 return ret;
1366#undef TICSAT38KHZTONS
1367} 1325}
1368 1326
1369static int rtl2832u_get_rc_config(struct dvb_usb_device *d, 1327static int rtl2832u_get_rc_config(struct dvb_usb_device *d,
1370 struct dvb_usb_rc *rc) 1328 struct dvb_usb_rc *rc)
1371{ 1329{
1372 rc->map_name = RC_MAP_EMPTY; 1330 /* load empty to enable rc */
1331 if (!rc->map_name)
1332 rc->map_name = RC_MAP_EMPTY;
1373 rc->allowed_protos = RC_BIT_ALL; 1333 rc->allowed_protos = RC_BIT_ALL;
1334 rc->driver_type = RC_DRIVER_IR_RAW;
1374 rc->query = rtl2832u_rc_query; 1335 rc->query = rtl2832u_rc_query;
1375 rc->interval = 400; 1336 rc->interval = 400;
1376 rc->driver_type = RC_DRIVER_IR_RAW;
1377 1337
1378 return 0; 1338 return 0;
1379} 1339}