aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/au0828/au0828-cards.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/au0828/au0828-cards.c')
-rw-r--r--drivers/media/video/au0828/au0828-cards.c127
1 files changed, 113 insertions, 14 deletions
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
index d60123b413f5..1aabaa7e55bb 100644
--- a/drivers/media/video/au0828/au0828-cards.c
+++ b/drivers/media/video/au0828/au0828-cards.c
@@ -21,25 +21,89 @@
21 21
22#include "au0828.h" 22#include "au0828.h"
23#include "au0828-cards.h" 23#include "au0828-cards.h"
24#include "au8522.h"
25#include "media/tuner.h"
26#include "media/v4l2-common.h"
27
28void hvr950q_cs5340_audio(void *priv, int enable)
29{
30 /* Because the HVR-950q shares an i2s bus between the cs5340 and the
31 au8522, we need to hold cs5340 in reset when using the au8522 */
32 struct au0828_dev *dev = priv;
33 if (enable == 1)
34 au0828_set(dev, REG_000, 0x10);
35 else
36 au0828_clear(dev, REG_000, 0x10);
37}
24 38
25struct au0828_board au0828_boards[] = { 39struct au0828_board au0828_boards[] = {
26 [AU0828_BOARD_UNKNOWN] = { 40 [AU0828_BOARD_UNKNOWN] = {
27 .name = "Unknown board", 41 .name = "Unknown board",
42 .tuner_type = UNSET,
43 .tuner_addr = ADDR_UNSET,
28 }, 44 },
29 [AU0828_BOARD_HAUPPAUGE_HVR850] = { 45 [AU0828_BOARD_HAUPPAUGE_HVR850] = {
30 .name = "Hauppauge HVR850", 46 .name = "Hauppauge HVR850",
47 .tuner_type = TUNER_XC5000,
48 .tuner_addr = 0x61,
49 .input = {
50 {
51 .type = AU0828_VMUX_TELEVISION,
52 .vmux = AU8522_COMPOSITE_CH4_SIF,
53 .amux = AU8522_AUDIO_SIF,
54 },
55 {
56 .type = AU0828_VMUX_COMPOSITE,
57 .vmux = AU8522_COMPOSITE_CH1,
58 .amux = AU8522_AUDIO_NONE,
59 .audio_setup = hvr950q_cs5340_audio,
60 },
61 {
62 .type = AU0828_VMUX_SVIDEO,
63 .vmux = AU8522_SVIDEO_CH13,
64 .amux = AU8522_AUDIO_NONE,
65 .audio_setup = hvr950q_cs5340_audio,
66 },
67 },
31 }, 68 },
32 [AU0828_BOARD_HAUPPAUGE_HVR950Q] = { 69 [AU0828_BOARD_HAUPPAUGE_HVR950Q] = {
33 .name = "Hauppauge HVR950Q", 70 .name = "Hauppauge HVR950Q",
71 .tuner_type = TUNER_XC5000,
72 .tuner_addr = 0x61,
73 .input = {
74 {
75 .type = AU0828_VMUX_TELEVISION,
76 .vmux = AU8522_COMPOSITE_CH4_SIF,
77 .amux = AU8522_AUDIO_SIF,
78 },
79 {
80 .type = AU0828_VMUX_COMPOSITE,
81 .vmux = AU8522_COMPOSITE_CH1,
82 .amux = AU8522_AUDIO_NONE,
83 .audio_setup = hvr950q_cs5340_audio,
84 },
85 {
86 .type = AU0828_VMUX_SVIDEO,
87 .vmux = AU8522_SVIDEO_CH13,
88 .amux = AU8522_AUDIO_NONE,
89 .audio_setup = hvr950q_cs5340_audio,
90 },
91 },
34 }, 92 },
35 [AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL] = { 93 [AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL] = {
36 .name = "Hauppauge HVR950Q rev xxF8", 94 .name = "Hauppauge HVR950Q rev xxF8",
95 .tuner_type = UNSET,
96 .tuner_addr = ADDR_UNSET,
37 }, 97 },
38 [AU0828_BOARD_DVICO_FUSIONHDTV7] = { 98 [AU0828_BOARD_DVICO_FUSIONHDTV7] = {
39 .name = "DViCO FusionHDTV USB", 99 .name = "DViCO FusionHDTV USB",
100 .tuner_type = UNSET,
101 .tuner_addr = ADDR_UNSET,
40 }, 102 },
41 [AU0828_BOARD_HAUPPAUGE_WOODBURY] = { 103 [AU0828_BOARD_HAUPPAUGE_WOODBURY] = {
42 .name = "Hauppauge Woodbury", 104 .name = "Hauppauge Woodbury",
105 .tuner_type = UNSET,
106 .tuner_addr = ADDR_UNSET,
43 }, 107 },
44}; 108};
45 109
@@ -52,7 +116,7 @@ int au0828_tuner_callback(void *priv, int component, int command, int arg)
52 116
53 dprintk(1, "%s()\n", __func__); 117 dprintk(1, "%s()\n", __func__);
54 118
55 switch (dev->board) { 119 switch (dev->boardnr) {
56 case AU0828_BOARD_HAUPPAUGE_HVR850: 120 case AU0828_BOARD_HAUPPAUGE_HVR850:
57 case AU0828_BOARD_HAUPPAUGE_HVR950Q: 121 case AU0828_BOARD_HAUPPAUGE_HVR950Q:
58 case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL: 122 case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
@@ -81,17 +145,18 @@ static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data)
81 struct tveeprom tv; 145 struct tveeprom tv;
82 146
83 tveeprom_hauppauge_analog(&dev->i2c_client, &tv, eeprom_data); 147 tveeprom_hauppauge_analog(&dev->i2c_client, &tv, eeprom_data);
148 dev->board.tuner_type = tv.tuner_type;
84 149
85 /* Make sure we support the board model */ 150 /* Make sure we support the board model */
86 switch (tv.model) { 151 switch (tv.model) {
87 case 72000: /* WinTV-HVR950q (Retail, IR, ATSC/QAM */ 152 case 72000: /* WinTV-HVR950q (Retail, IR, ATSC/QAM */
88 case 72001: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and basic analog video */ 153 case 72001: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and analog video */
89 case 72211: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */ 154 case 72211: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */
90 case 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */ 155 case 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */
91 case 72231: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */ 156 case 72231: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */
92 case 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and basic analog video */ 157 case 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and analog video */
93 case 72251: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and basic analog video */ 158 case 72251: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and analog video */
94 case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and basic analog video */ 159 case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and analog video */
95 case 72500: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM */ 160 case 72500: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM */
96 break; 161 break;
97 default: 162 default:
@@ -107,15 +172,21 @@ static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data)
107void au0828_card_setup(struct au0828_dev *dev) 172void au0828_card_setup(struct au0828_dev *dev)
108{ 173{
109 static u8 eeprom[256]; 174 static u8 eeprom[256];
175 struct tuner_setup tun_setup;
176 struct v4l2_subdev *sd;
177 unsigned int mode_mask = T_ANALOG_TV |
178 T_DIGITAL_TV;
110 179
111 dprintk(1, "%s()\n", __func__); 180 dprintk(1, "%s()\n", __func__);
112 181
182 memcpy(&dev->board, &au0828_boards[dev->boardnr], sizeof(dev->board));
183
113 if (dev->i2c_rc == 0) { 184 if (dev->i2c_rc == 0) {
114 dev->i2c_client.addr = 0xa0 >> 1; 185 dev->i2c_client.addr = 0xa0 >> 1;
115 tveeprom_read(&dev->i2c_client, eeprom, sizeof(eeprom)); 186 tveeprom_read(&dev->i2c_client, eeprom, sizeof(eeprom));
116 } 187 }
117 188
118 switch (dev->board) { 189 switch (dev->boardnr) {
119 case AU0828_BOARD_HAUPPAUGE_HVR850: 190 case AU0828_BOARD_HAUPPAUGE_HVR850:
120 case AU0828_BOARD_HAUPPAUGE_HVR950Q: 191 case AU0828_BOARD_HAUPPAUGE_HVR950Q:
121 case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL: 192 case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
@@ -124,6 +195,32 @@ void au0828_card_setup(struct au0828_dev *dev)
124 hauppauge_eeprom(dev, eeprom+0xa0); 195 hauppauge_eeprom(dev, eeprom+0xa0);
125 break; 196 break;
126 } 197 }
198
199 if (AUVI_INPUT(0).type != AU0828_VMUX_UNDEFINED) {
200 /* Load the analog demodulator driver (note this would need to
201 be abstracted out if we ever need to support a different
202 demod) */
203 sd = v4l2_i2c_new_subdev(&dev->i2c_adap, "au8522", "au8522",
204 0x8e >> 1);
205 if (sd == NULL)
206 printk(KERN_ERR "analog subdev registration failed\n");
207 }
208
209 /* Setup tuners */
210 if (dev->board.tuner_type != TUNER_ABSENT) {
211 /* Load the tuner module, which does the attach */
212 sd = v4l2_i2c_new_subdev(&dev->i2c_adap, "tuner", "tuner",
213 dev->board.tuner_addr);
214 if (sd == NULL)
215 printk(KERN_ERR "tuner subdev registration fail\n");
216
217 tun_setup.mode_mask = mode_mask;
218 tun_setup.type = dev->board.tuner_type;
219 tun_setup.addr = dev->board.tuner_addr;
220 tun_setup.tuner_callback = au0828_tuner_callback;
221 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr,
222 &tun_setup);
223 }
127} 224}
128 225
129/* 226/*
@@ -135,7 +232,7 @@ void au0828_gpio_setup(struct au0828_dev *dev)
135{ 232{
136 dprintk(1, "%s()\n", __func__); 233 dprintk(1, "%s()\n", __func__);
137 234
138 switch (dev->board) { 235 switch (dev->boardnr) {
139 case AU0828_BOARD_HAUPPAUGE_HVR850: 236 case AU0828_BOARD_HAUPPAUGE_HVR850:
140 case AU0828_BOARD_HAUPPAUGE_HVR950Q: 237 case AU0828_BOARD_HAUPPAUGE_HVR950Q:
141 case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL: 238 case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
@@ -144,21 +241,23 @@ void au0828_gpio_setup(struct au0828_dev *dev)
144 * 4 - CS5340 241 * 4 - CS5340
145 * 5 - AU8522 Demodulator 242 * 5 - AU8522 Demodulator
146 * 6 - eeprom W/P 243 * 6 - eeprom W/P
244 * 7 - power supply
147 * 9 - XC5000 Tuner 245 * 9 - XC5000 Tuner
148 */ 246 */
149 247
150 /* Into reset */ 248 /* Into reset */
151 au0828_write(dev, REG_003, 0x02); 249 au0828_write(dev, REG_003, 0x02);
152 au0828_write(dev, REG_002, 0x88 | 0x20); 250 au0828_write(dev, REG_002, 0x80 | 0x20 | 0x10);
153 au0828_write(dev, REG_001, 0x0); 251 au0828_write(dev, REG_001, 0x0);
154 au0828_write(dev, REG_000, 0x0); 252 au0828_write(dev, REG_000, 0x0);
155 msleep(100); 253 msleep(100);
156 254
157 /* Out of reset */ 255 /* Out of reset (leave the cs5340 in reset until needed) */
158 au0828_write(dev, REG_003, 0x02); 256 au0828_write(dev, REG_003, 0x02);
159 au0828_write(dev, REG_001, 0x02); 257 au0828_write(dev, REG_001, 0x02);
160 au0828_write(dev, REG_002, 0x88 | 0x20); 258 au0828_write(dev, REG_002, 0x80 | 0x20 | 0x10);
161 au0828_write(dev, REG_000, 0x88 | 0x20 | 0x40); 259 au0828_write(dev, REG_000, 0x80 | 0x40 | 0x20);
260
162 msleep(250); 261 msleep(250);
163 break; 262 break;
164 case AU0828_BOARD_DVICO_FUSIONHDTV7: 263 case AU0828_BOARD_DVICO_FUSIONHDTV7: