diff options
author | Tim Kaiser <timkaiser@t-online.de> | 2006-06-25 08:14:07 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-06-26 08:21:26 -0400 |
commit | 61391e0446e97bea44d93bd1624e5b32d3cc8474 (patch) | |
tree | c1a1579505a07a1c58c3c7f58ed8ba775acd02c0 /drivers/media | |
parent | 4a4edcca22bf46622f34db74a876a7eb91d95865 (diff) |
V4L/DVB (4219): Av7110: analog sound output of DVB-C rev 2.3
Added support for the msp34x5 audio dac. Analog sound output of
Technotrend DVB-C 2300 (aka Hauppauge Nexus-CA) works now.
Signed-off-by: Tim Kaiser <timkaiser@t-online.de>
Signed-off-by: Marco Schluessler <marco@lordzodiac.de>
Signed-off-by: Oliver Endriss <o.endriss@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/dvb/ttpci/av7110.c | 8 | ||||
-rw-r--r-- | drivers/media/dvb/ttpci/av7110_av.c | 25 | ||||
-rw-r--r-- | drivers/media/dvb/ttpci/av7110_v4l.c | 50 |
3 files changed, 64 insertions, 19 deletions
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 8832f80c05f7..7a5c99c200e8 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c | |||
@@ -152,13 +152,9 @@ static void init_av7110_av(struct av7110 *av7110) | |||
152 | /* remaining inits according to card and frontend type */ | 152 | /* remaining inits according to card and frontend type */ |
153 | av7110->analog_tuner_flags = 0; | 153 | av7110->analog_tuner_flags = 0; |
154 | av7110->current_input = 0; | 154 | av7110->current_input = 0; |
155 | if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000a) { | 155 | if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000a) |
156 | printk("dvb-ttpci: MSP3415 audio DAC @ card %d\n", | ||
157 | av7110->dvb_adapter.num); | ||
158 | av7110->adac_type = DVB_ADAC_MSP34x5; | ||
159 | av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 0); // SPDIF on | 156 | av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 0); // SPDIF on |
160 | } | 157 | if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) { |
161 | else if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) { | ||
162 | printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n", | 158 | printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n", |
163 | av7110->dvb_adapter.num); | 159 | av7110->dvb_adapter.num); |
164 | av7110->adac_type = DVB_ADAC_CRYSTAL; | 160 | av7110->adac_type = DVB_ADAC_CRYSTAL; |
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c index 2eff09f638d3..0f3a044aeb17 100644 --- a/drivers/media/dvb/ttpci/av7110_av.c +++ b/drivers/media/dvb/ttpci/av7110_av.c | |||
@@ -318,7 +318,17 @@ int av7110_set_volume(struct av7110 *av7110, int volleft, int volright) | |||
318 | msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */ | 318 | msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */ |
319 | msp_writereg(av7110, MSP_WR_DSP, 0x0006, val); /* headphonesr */ | 319 | msp_writereg(av7110, MSP_WR_DSP, 0x0006, val); /* headphonesr */ |
320 | return 0; | 320 | return 0; |
321 | |||
322 | case DVB_ADAC_MSP34x5: | ||
323 | vol = (volleft > volright) ? volleft : volright; | ||
324 | val = (vol * 0x73 / 255) << 8; | ||
325 | if (vol > 0) | ||
326 | balance = ((volright - volleft) * 127) / vol; | ||
327 | msp_writereg(av7110, MSP_WR_DSP, 0x0001, balance << 8); | ||
328 | msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */ | ||
329 | return 0; | ||
321 | } | 330 | } |
331 | |||
322 | return 0; | 332 | return 0; |
323 | } | 333 | } |
324 | 334 | ||
@@ -1267,23 +1277,32 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, | |||
1267 | switch(av7110->audiostate.channel_select) { | 1277 | switch(av7110->audiostate.channel_select) { |
1268 | case AUDIO_STEREO: | 1278 | case AUDIO_STEREO: |
1269 | ret = audcom(av7110, AUDIO_CMD_STEREO); | 1279 | ret = audcom(av7110, AUDIO_CMD_STEREO); |
1270 | if (!ret) | 1280 | if (!ret) { |
1271 | if (av7110->adac_type == DVB_ADAC_CRYSTAL) | 1281 | if (av7110->adac_type == DVB_ADAC_CRYSTAL) |
1272 | i2c_writereg(av7110, 0x20, 0x02, 0x49); | 1282 | i2c_writereg(av7110, 0x20, 0x02, 0x49); |
1283 | else if (av7110->adac_type == DVB_ADAC_MSP34x5) | ||
1284 | msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); | ||
1285 | } | ||
1273 | break; | 1286 | break; |
1274 | 1287 | ||
1275 | case AUDIO_MONO_LEFT: | 1288 | case AUDIO_MONO_LEFT: |
1276 | ret = audcom(av7110, AUDIO_CMD_MONO_L); | 1289 | ret = audcom(av7110, AUDIO_CMD_MONO_L); |
1277 | if (!ret) | 1290 | if (!ret) { |
1278 | if (av7110->adac_type == DVB_ADAC_CRYSTAL) | 1291 | if (av7110->adac_type == DVB_ADAC_CRYSTAL) |
1279 | i2c_writereg(av7110, 0x20, 0x02, 0x4a); | 1292 | i2c_writereg(av7110, 0x20, 0x02, 0x4a); |
1293 | else if (av7110->adac_type == DVB_ADAC_MSP34x5) | ||
1294 | msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0200); | ||
1295 | } | ||
1280 | break; | 1296 | break; |
1281 | 1297 | ||
1282 | case AUDIO_MONO_RIGHT: | 1298 | case AUDIO_MONO_RIGHT: |
1283 | ret = audcom(av7110, AUDIO_CMD_MONO_R); | 1299 | ret = audcom(av7110, AUDIO_CMD_MONO_R); |
1284 | if (!ret) | 1300 | if (!ret) { |
1285 | if (av7110->adac_type == DVB_ADAC_CRYSTAL) | 1301 | if (av7110->adac_type == DVB_ADAC_CRYSTAL) |
1286 | i2c_writereg(av7110, 0x20, 0x02, 0x45); | 1302 | i2c_writereg(av7110, 0x20, 0x02, 0x45); |
1303 | else if (av7110->adac_type == DVB_ADAC_MSP34x5) | ||
1304 | msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0210); | ||
1305 | } | ||
1287 | break; | 1306 | break; |
1288 | 1307 | ||
1289 | default: | 1308 | default: |
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c index 603a22e4bfe2..64055461559d 100644 --- a/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/drivers/media/dvb/ttpci/av7110_v4l.c | |||
@@ -42,7 +42,18 @@ | |||
42 | int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val) | 42 | int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val) |
43 | { | 43 | { |
44 | u8 msg[5] = { dev, reg >> 8, reg & 0xff, val >> 8 , val & 0xff }; | 44 | u8 msg[5] = { dev, reg >> 8, reg & 0xff, val >> 8 , val & 0xff }; |
45 | struct i2c_msg msgs = { .flags = 0, .addr = 0x40, .len = 5, .buf = msg }; | 45 | struct i2c_msg msgs = { .flags = 0, .len = 5, .buf = msg }; |
46 | |||
47 | switch (av7110->adac_type) { | ||
48 | case DVB_ADAC_MSP34x0: | ||
49 | msgs.addr = 0x40; | ||
50 | break; | ||
51 | case DVB_ADAC_MSP34x5: | ||
52 | msgs.addr = 0x42; | ||
53 | break; | ||
54 | default: | ||
55 | return 0; | ||
56 | } | ||
46 | 57 | ||
47 | if (i2c_transfer(&av7110->i2c_adap, &msgs, 1) != 1) { | 58 | if (i2c_transfer(&av7110->i2c_adap, &msgs, 1) != 1) { |
48 | dprintk(1, "dvb-ttpci: failed @ card %d, %u = %u\n", | 59 | dprintk(1, "dvb-ttpci: failed @ card %d, %u = %u\n", |
@@ -57,10 +68,23 @@ static int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val) | |||
57 | u8 msg1[3] = { dev, reg >> 8, reg & 0xff }; | 68 | u8 msg1[3] = { dev, reg >> 8, reg & 0xff }; |
58 | u8 msg2[2]; | 69 | u8 msg2[2]; |
59 | struct i2c_msg msgs[2] = { | 70 | struct i2c_msg msgs[2] = { |
60 | { .flags = 0, .addr = 0x40, .len = 3, .buf = msg1 }, | 71 | { .flags = 0 , .len = 3, .buf = msg1 }, |
61 | { .flags = I2C_M_RD, .addr = 0x40, .len = 2, .buf = msg2 } | 72 | { .flags = I2C_M_RD, .len = 2, .buf = msg2 } |
62 | }; | 73 | }; |
63 | 74 | ||
75 | switch (av7110->adac_type) { | ||
76 | case DVB_ADAC_MSP34x0: | ||
77 | msgs[0].addr = 0x40; | ||
78 | msgs[1].addr = 0x40; | ||
79 | break; | ||
80 | case DVB_ADAC_MSP34x5: | ||
81 | msgs[0].addr = 0x42; | ||
82 | msgs[1].addr = 0x42; | ||
83 | break; | ||
84 | default: | ||
85 | return 0; | ||
86 | } | ||
87 | |||
64 | if (i2c_transfer(&av7110->i2c_adap, &msgs[0], 2) != 2) { | 88 | if (i2c_transfer(&av7110->i2c_adap, &msgs[0], 2) != 2) { |
65 | dprintk(1, "dvb-ttpci: failed @ card %d, %u\n", | 89 | dprintk(1, "dvb-ttpci: failed @ card %d, %u\n", |
66 | av7110->dvb_adapter.num, reg); | 90 | av7110->dvb_adapter.num, reg); |
@@ -678,17 +702,23 @@ int av7110_init_analog_module(struct av7110 *av7110) | |||
678 | { | 702 | { |
679 | u16 version1, version2; | 703 | u16 version1, version2; |
680 | 704 | ||
681 | if (i2c_writereg(av7110, 0x80, 0x0, 0x80) != 1 | 705 | if (i2c_writereg(av7110, 0x80, 0x0, 0x80) == 1 && |
682 | || i2c_writereg(av7110, 0x80, 0x0, 0) != 1) | 706 | i2c_writereg(av7110, 0x80, 0x0, 0) == 1) { |
707 | printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3400\n", | ||
708 | av7110->dvb_adapter.num); | ||
709 | av7110->adac_type = DVB_ADAC_MSP34x0; | ||
710 | } else if (i2c_writereg(av7110, 0x84, 0x0, 0x80) == 1 && | ||
711 | i2c_writereg(av7110, 0x84, 0x0, 0) == 1) { | ||
712 | printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3415\n", | ||
713 | av7110->dvb_adapter.num); | ||
714 | av7110->adac_type = DVB_ADAC_MSP34x5; | ||
715 | } else | ||
683 | return -ENODEV; | 716 | return -ENODEV; |
684 | 717 | ||
685 | printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3400\n", | ||
686 | av7110->dvb_adapter.num); | ||
687 | av7110->adac_type = DVB_ADAC_MSP34x0; | ||
688 | msleep(100); // the probing above resets the msp... | 718 | msleep(100); // the probing above resets the msp... |
689 | msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1); | 719 | msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1); |
690 | msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2); | 720 | msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2); |
691 | dprintk(1, "dvb-ttpci: @ card %d MSP3400 version 0x%04x 0x%04x\n", | 721 | dprintk(1, "dvb-ttpci: @ card %d MSP34xx version 0x%04x 0x%04x\n", |
692 | av7110->dvb_adapter.num, version1, version2); | 722 | av7110->dvb_adapter.num, version1, version2); |
693 | msp_writereg(av7110, MSP_WR_DSP, 0x0013, 0x0c00); | 723 | msp_writereg(av7110, MSP_WR_DSP, 0x0013, 0x0c00); |
694 | msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone | 724 | msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone |
@@ -697,7 +727,7 @@ int av7110_init_analog_module(struct av7110 *av7110) | |||
697 | msp_writereg(av7110, MSP_WR_DSP, 0x0004, 0x7f00); // loudspeaker volume | 727 | msp_writereg(av7110, MSP_WR_DSP, 0x0004, 0x7f00); // loudspeaker volume |
698 | msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source | 728 | msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source |
699 | msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume | 729 | msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume |
700 | msp_writereg(av7110, MSP_WR_DSP, 0x000d, 0x4800); // prescale SCART | 730 | msp_writereg(av7110, MSP_WR_DSP, 0x000d, 0x1900); // prescale SCART |
701 | 731 | ||
702 | if (i2c_writereg(av7110, 0x48, 0x01, 0x00)!=1) { | 732 | if (i2c_writereg(av7110, 0x48, 0x01, 0x00)!=1) { |
703 | INFO(("saa7113 not accessible.\n")); | 733 | INFO(("saa7113 not accessible.\n")); |