diff options
author | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | 2005-11-09 00:37:19 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-09 10:56:16 -0500 |
commit | 18f47d10bc8076bb126a1a369b782e29cc91c824 (patch) | |
tree | b25d010e3aa82b27f3b58c321e2a7de6f8864f39 /drivers/media/video/msp3400.c | |
parent | 6df840f20d1ff63fd13ed1bb3e186395ee800794 (diff) |
[PATCH] v4l: 759: more improvements at msp3400 c from ivtv code
- More improvements at msp3400.c from ivtv code.
Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/media/video/msp3400.c')
-rw-r--r-- | drivers/media/video/msp3400.c | 111 |
1 files changed, 93 insertions, 18 deletions
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c index 4689dee882f3..117d124657d0 100644 --- a/drivers/media/video/msp3400.c +++ b/drivers/media/video/msp3400.c | |||
@@ -649,6 +649,30 @@ msp3400c_print_mode(struct msp3400c *msp) | |||
649 | } | 649 | } |
650 | } | 650 | } |
651 | 651 | ||
652 | #define MSP3400_MAX 4 | ||
653 | static struct i2c_client *msps[MSP3400_MAX]; | ||
654 | static void msp3400c_restore_dfp(struct i2c_client *client) | ||
655 | { | ||
656 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
657 | int i; | ||
658 | |||
659 | for (i = 0; i < DFP_COUNT; i++) { | ||
660 | if (-1 == msp->dfp_regs[i]) | ||
661 | continue; | ||
662 | msp3400c_write(client, I2C_MSP3400C_DFP, i, msp->dfp_regs[i]); | ||
663 | } | ||
664 | } | ||
665 | |||
666 | /* if the dfp_regs is set, set what's in there. Otherwise, set the default value */ | ||
667 | static int msp3400c_write_dfp_with_default(struct i2c_client *client, | ||
668 | int addr, int default_value) | ||
669 | { | ||
670 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
671 | int value = default_value; | ||
672 | if (addr < DFP_COUNT && -1 != msp->dfp_regs[addr]) | ||
673 | value = msp->dfp_regs[addr]; | ||
674 | return msp3400c_write(client, I2C_MSP3400C_DFP, addr, value); | ||
675 | } | ||
652 | 676 | ||
653 | /* ----------------------------------------------------------------------- */ | 677 | /* ----------------------------------------------------------------------- */ |
654 | 678 | ||
@@ -834,7 +858,8 @@ static int msp3400c_thread(void *data) | |||
834 | goto restart; | 858 | goto restart; |
835 | 859 | ||
836 | /* carrier detect pass #1 -- main carrier */ | 860 | /* carrier detect pass #1 -- main carrier */ |
837 | cd = carrier_detect_main; count = CARRIER_COUNT(carrier_detect_main); | 861 | cd = carrier_detect_main; |
862 | count = CARRIER_COUNT(carrier_detect_main); | ||
838 | 863 | ||
839 | if (amsound && (msp->norm == VIDEO_MODE_SECAM)) { | 864 | if (amsound && (msp->norm == VIDEO_MODE_SECAM)) { |
840 | /* autodetect doesn't work well with AM ... */ | 865 | /* autodetect doesn't work well with AM ... */ |
@@ -868,13 +893,16 @@ static int msp3400c_thread(void *data) | |||
868 | case 0: /* 4.5 */ | 893 | case 0: /* 4.5 */ |
869 | case 2: /* 6.0 */ | 894 | case 2: /* 6.0 */ |
870 | default: | 895 | default: |
871 | cd = NULL; count = 0; | 896 | cd = NULL; |
897 | count = 0; | ||
872 | break; | 898 | break; |
873 | } | 899 | } |
874 | 900 | ||
875 | if (amsound && (msp->norm == VIDEO_MODE_SECAM)) { | 901 | if (amsound && (msp->norm == VIDEO_MODE_SECAM)) { |
876 | /* autodetect doesn't work well with AM ... */ | 902 | /* autodetect doesn't work well with AM ... */ |
877 | cd = NULL; count = 0; max2 = 0; | 903 | cd = NULL; |
904 | count = 0; | ||
905 | max2 = 0; | ||
878 | } | 906 | } |
879 | for (this = 0; this < count; this++) { | 907 | for (this = 0; this < count; this++) { |
880 | msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo); | 908 | msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo); |
@@ -962,6 +990,8 @@ static int msp3400c_thread(void *data) | |||
962 | 990 | ||
963 | /* unmute */ | 991 | /* unmute */ |
964 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); | 992 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); |
993 | msp3400c_restore_dfp(client); | ||
994 | |||
965 | if (debug) | 995 | if (debug) |
966 | msp3400c_print_mode(msp); | 996 | msp3400c_print_mode(msp); |
967 | 997 | ||
@@ -1207,6 +1237,7 @@ static int msp3410d_thread(void *data) | |||
1207 | msp3400c_settreble(client, msp->treble); | 1237 | msp3400c_settreble(client, msp->treble); |
1208 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); | 1238 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); |
1209 | msp3400c_write(client, I2C_MSP3400C_DFP, 0x0013, msp->acb); | 1239 | msp3400c_write(client, I2C_MSP3400C_DFP, 0x0013, msp->acb); |
1240 | msp3400c_restore_dfp(client); | ||
1210 | 1241 | ||
1211 | /* monitor tv audio mode */ | 1242 | /* monitor tv audio mode */ |
1212 | while (msp->watch_stereo) { | 1243 | while (msp->watch_stereo) { |
@@ -1230,7 +1261,7 @@ static void msp34xxg_set_source(struct i2c_client *client, int source); | |||
1230 | /* (re-)initialize the msp34xxg, according to the current norm in msp->norm | 1261 | /* (re-)initialize the msp34xxg, according to the current norm in msp->norm |
1231 | * return 0 if it worked, -1 if it failed | 1262 | * return 0 if it worked, -1 if it failed |
1232 | */ | 1263 | */ |
1233 | static int msp34xxg_init(struct i2c_client *client) | 1264 | static int msp34xxg_reset(struct i2c_client *client) |
1234 | { | 1265 | { |
1235 | struct msp3400c *msp = i2c_get_clientdata(client); | 1266 | struct msp3400c *msp = i2c_get_clientdata(client); |
1236 | int modus,std; | 1267 | int modus,std; |
@@ -1257,7 +1288,7 @@ static int msp34xxg_init(struct i2c_client *client) | |||
1257 | return -1; | 1288 | return -1; |
1258 | if (msp3400c_write(client, | 1289 | if (msp3400c_write(client, |
1259 | I2C_MSP3400C_DEM, | 1290 | I2C_MSP3400C_DEM, |
1260 | 0x20/*stanard*/, | 1291 | 0x20/*standard*/, |
1261 | std)) | 1292 | std)) |
1262 | return -1; | 1293 | return -1; |
1263 | 1294 | ||
@@ -1265,21 +1296,18 @@ static int msp34xxg_init(struct i2c_client *client) | |||
1265 | standard/audio autodetection right now */ | 1296 | standard/audio autodetection right now */ |
1266 | msp34xxg_set_source(client, msp->source); | 1297 | msp34xxg_set_source(client, msp->source); |
1267 | 1298 | ||
1268 | if (msp3400c_write(client, I2C_MSP3400C_DFP, | 1299 | if (msp3400c_write_dfp_with_default(client, 0x0e, /* AM/FM Prescale */ |
1269 | 0x0e, /* AM/FM Prescale */ | 1300 | 0x3000 |
1270 | 0x3000 /* default: [15:8] 75khz deviation */)) | 1301 | /* default: [15:8] 75khz deviation */ |
1302 | )) | ||
1271 | return -1; | 1303 | return -1; |
1272 | 1304 | ||
1273 | if (msp3400c_write(client, I2C_MSP3400C_DFP, | 1305 | if (msp3400c_write_dfp_with_default(client, 0x10, /* NICAM Prescale */ |
1274 | 0x10, /* NICAM Prescale */ | 1306 | 0x5a00 |
1275 | 0x5a00 /* default: 9db gain (as recommended) */)) | 1307 | /* default: 9db gain (as recommended) */ |
1308 | )) | ||
1276 | return -1; | 1309 | return -1; |
1277 | 1310 | ||
1278 | if (msp3400c_write(client, | ||
1279 | I2C_MSP3400C_DEM, | ||
1280 | 0x20, /* STANDARD SELECT */ | ||
1281 | standard /* default: 0x01 for automatic standard select*/)) | ||
1282 | return -1; | ||
1283 | return 0; | 1311 | return 0; |
1284 | } | 1312 | } |
1285 | 1313 | ||
@@ -1303,7 +1331,7 @@ static int msp34xxg_thread(void *data) | |||
1303 | break; | 1331 | break; |
1304 | 1332 | ||
1305 | /* setup the chip*/ | 1333 | /* setup the chip*/ |
1306 | msp34xxg_init(client); | 1334 | msp34xxg_reset(client); |
1307 | std = standard; | 1335 | std = standard; |
1308 | if (std != 0x01) | 1336 | if (std != 0x01) |
1309 | goto unmute; | 1337 | goto unmute; |
@@ -1486,6 +1514,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind) | |||
1486 | struct msp3400c *msp; | 1514 | struct msp3400c *msp; |
1487 | struct i2c_client *c; | 1515 | struct i2c_client *c; |
1488 | int (*thread_func)(void *data) = NULL; | 1516 | int (*thread_func)(void *data) = NULL; |
1517 | int i; | ||
1489 | 1518 | ||
1490 | client_template.adapter = adap; | 1519 | client_template.adapter = adap; |
1491 | client_template.addr = addr; | 1520 | client_template.addr = addr; |
@@ -1504,12 +1533,15 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind) | |||
1504 | } | 1533 | } |
1505 | 1534 | ||
1506 | memset(msp,0,sizeof(struct msp3400c)); | 1535 | memset(msp,0,sizeof(struct msp3400c)); |
1536 | msp->norm = VIDEO_MODE_NTSC; | ||
1507 | msp->left = 58880; /* 0db gain */ | 1537 | msp->left = 58880; /* 0db gain */ |
1508 | msp->right = 58880; /* 0db gain */ | 1538 | msp->right = 58880; /* 0db gain */ |
1509 | msp->bass = 32768; | 1539 | msp->bass = 32768; |
1510 | msp->treble = 32768; | 1540 | msp->treble = 32768; |
1511 | msp->input = -1; | 1541 | msp->input = -1; |
1512 | msp->muted = 0; | 1542 | msp->muted = 0; |
1543 | for (i = 0; i < DFP_COUNT; i++) | ||
1544 | msp->dfp_regs[i] = -1; | ||
1513 | 1545 | ||
1514 | i2c_set_clientdata(c, msp); | 1546 | i2c_set_clientdata(c, msp); |
1515 | init_waitqueue_head(&msp->wq); | 1547 | init_waitqueue_head(&msp->wq); |
@@ -1579,6 +1611,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind) | |||
1579 | /* startup control thread if needed */ | 1611 | /* startup control thread if needed */ |
1580 | if (thread_func) { | 1612 | if (thread_func) { |
1581 | msp->kthread = kthread_run(thread_func, c, "msp34xx"); | 1613 | msp->kthread = kthread_run(thread_func, c, "msp34xx"); |
1614 | |||
1582 | if (NULL == msp->kthread) | 1615 | if (NULL == msp->kthread) |
1583 | printk(KERN_WARNING "msp34xx: kernel_thread() failed\n"); | 1616 | printk(KERN_WARNING "msp34xx: kernel_thread() failed\n"); |
1584 | msp_wake_thread(c); | 1617 | msp_wake_thread(c); |
@@ -1587,21 +1620,39 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind) | |||
1587 | /* done */ | 1620 | /* done */ |
1588 | i2c_attach_client(c); | 1621 | i2c_attach_client(c); |
1589 | 1622 | ||
1623 | /* update our own array */ | ||
1624 | for (i = 0; i < MSP3400_MAX; i++) { | ||
1625 | if (NULL == msps[i]) { | ||
1626 | msps[i] = c; | ||
1627 | break; | ||
1628 | } | ||
1629 | } | ||
1630 | |||
1590 | return 0; | 1631 | return 0; |
1591 | } | 1632 | } |
1592 | 1633 | ||
1593 | static int msp_detach(struct i2c_client *client) | 1634 | static int msp_detach(struct i2c_client *client) |
1594 | { | 1635 | { |
1595 | struct msp3400c *msp = i2c_get_clientdata(client); | 1636 | struct msp3400c *msp = i2c_get_clientdata(client); |
1637 | int i; | ||
1596 | 1638 | ||
1597 | /* shutdown control thread */ | 1639 | /* shutdown control thread */ |
1598 | if (msp->kthread) { | 1640 | if (msp->kthread) { |
1599 | msp->restart = 1; | 1641 | msp->restart = 1; |
1600 | kthread_stop(msp->kthread); | 1642 | kthread_stop(msp->kthread); |
1601 | } | 1643 | } |
1602 | msp3400c_reset(client); | 1644 | msp3400c_reset(client); |
1645 | |||
1646 | /* update our own array */ | ||
1647 | for (i = 0; i < MSP3400_MAX; i++) { | ||
1648 | if (client == msps[i]) { | ||
1649 | msps[i] = NULL; | ||
1650 | break; | ||
1651 | } | ||
1652 | } | ||
1603 | 1653 | ||
1604 | i2c_detach_client(client); | 1654 | i2c_detach_client(client); |
1655 | |||
1605 | kfree(msp); | 1656 | kfree(msp); |
1606 | kfree(client); | 1657 | kfree(client); |
1607 | return 0; | 1658 | return 0; |
@@ -1753,6 +1804,30 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1753 | break; | 1804 | break; |
1754 | } | 1805 | } |
1755 | break; | 1806 | break; |
1807 | /* work-in-progress: hook to control the DFP registers */ | ||
1808 | case MSP_SET_DFPREG: | ||
1809 | { | ||
1810 | struct msp_dfpreg *r = arg; | ||
1811 | int i; | ||
1812 | |||
1813 | if (r->reg < 0 || r->reg >= DFP_COUNT) | ||
1814 | return -EINVAL; | ||
1815 | for (i = 0; i < sizeof(bl_dfp) / sizeof(int); i++) | ||
1816 | if (r->reg == bl_dfp[i]) | ||
1817 | return -EINVAL; | ||
1818 | msp->dfp_regs[r->reg] = r->value; | ||
1819 | msp3400c_write(client, I2C_MSP3400C_DFP, r->reg, r->value); | ||
1820 | return 0; | ||
1821 | } | ||
1822 | case MSP_GET_DFPREG: | ||
1823 | { | ||
1824 | struct msp_dfpreg *r = arg; | ||
1825 | |||
1826 | if (r->reg < 0 || r->reg >= DFP_COUNT) | ||
1827 | return -EINVAL; | ||
1828 | r->value = msp3400c_read(client, I2C_MSP3400C_DFP, r->reg); | ||
1829 | return 0; | ||
1830 | } | ||
1756 | 1831 | ||
1757 | /* --- v4l ioctls --- */ | 1832 | /* --- v4l ioctls --- */ |
1758 | /* take care: bttv does userspace copying, we'll get a | 1833 | /* take care: bttv does userspace copying, we'll get a |