diff options
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/mxb.c | 13 | ||||
-rw-r--r-- | drivers/media/video/tda9840.c | 166 | ||||
-rw-r--r-- | drivers/media/video/tea6415c.c | 131 | ||||
-rw-r--r-- | drivers/media/video/tea6420.c | 147 |
4 files changed, 155 insertions, 302 deletions
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c index 8ef578caba3b..7c9820c72a6f 100644 --- a/drivers/media/video/mxb.c +++ b/drivers/media/video/mxb.c | |||
@@ -466,15 +466,15 @@ static int mxb_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data | |||
466 | /* checking for i2c-devices can be omitted here, because we | 466 | /* checking for i2c-devices can be omitted here, because we |
467 | already did this in "mxb_vl42_probe" */ | 467 | already did this in "mxb_vl42_probe" */ |
468 | 468 | ||
469 | saa7146_vv_init(dev,&vv_data); | 469 | saa7146_vv_init(dev, &vv_data); |
470 | if( 0 != saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) { | 470 | if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) { |
471 | ERR(("cannot register capture v4l2 device. skipping.\n")); | 471 | ERR(("cannot register capture v4l2 device. skipping.\n")); |
472 | return -1; | 472 | return -1; |
473 | } | 473 | } |
474 | 474 | ||
475 | /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/ | 475 | /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/ |
476 | if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) { | 476 | if (MXB_BOARD_CAN_DO_VBI(dev)) { |
477 | if( 0 != saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) { | 477 | if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) { |
478 | ERR(("cannot register vbi v4l2 device. skipping.\n")); | 478 | ERR(("cannot register vbi v4l2 device. skipping.\n")); |
479 | } | 479 | } |
480 | } | 480 | } |
@@ -486,7 +486,7 @@ static int mxb_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data | |||
486 | i2c_use_client(mxb->saa7111a); | 486 | i2c_use_client(mxb->saa7111a); |
487 | i2c_use_client(mxb->tuner); | 487 | i2c_use_client(mxb->tuner); |
488 | 488 | ||
489 | printk("mxb: found 'Multimedia eXtension Board'-%d.\n",mxb_num); | 489 | printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num); |
490 | 490 | ||
491 | mxb_num++; | 491 | mxb_num++; |
492 | mxb_init_done(dev); | 492 | mxb_init_done(dev); |
@@ -737,8 +737,8 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
737 | DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index)); | 737 | DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index)); |
738 | 738 | ||
739 | memset(t,0,sizeof(*t)); | 739 | memset(t,0,sizeof(*t)); |
740 | strcpy(t->name, "Television"); | ||
741 | 740 | ||
741 | strlcpy(t->name, "Television", sizeof(t->name)); | ||
742 | t->type = V4L2_TUNER_ANALOG_TV; | 742 | t->type = V4L2_TUNER_ANALOG_TV; |
743 | t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; | 743 | t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; |
744 | t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */ | 744 | t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */ |
@@ -746,7 +746,6 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
746 | /* FIXME: add the real signal strength here */ | 746 | /* FIXME: add the real signal strength here */ |
747 | t->signal = 0xffff; | 747 | t->signal = 0xffff; |
748 | t->afc = 0; | 748 | t->afc = 0; |
749 | |||
750 | mxb->tda9840->driver->command(mxb->tda9840,TDA9840_DETECT, &byte); | 749 | mxb->tda9840->driver->command(mxb->tda9840,TDA9840_DETECT, &byte); |
751 | t->audmode = mxb->cur_mode; | 750 | t->audmode = mxb->cur_mode; |
752 | 751 | ||
diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c index 2437c1a269c5..57deeb893318 100644 --- a/drivers/media/video/tda9840.c +++ b/drivers/media/video/tda9840.c | |||
@@ -2,6 +2,7 @@ | |||
2 | tda9840 - i2c-driver for the tda9840 by SGS Thomson | 2 | tda9840 - i2c-driver for the tda9840 by SGS Thomson |
3 | 3 | ||
4 | Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de> | 4 | Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de> |
5 | Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl> | ||
5 | 6 | ||
6 | The tda9840 is a stereo/dual sound processor with digital | 7 | The tda9840 is a stereo/dual sound processor with digital |
7 | identification. It can be found at address 0x84 on the i2c-bus. | 8 | identification. It can be found at address 0x84 on the i2c-bus. |
@@ -28,15 +29,18 @@ | |||
28 | #include <linux/module.h> | 29 | #include <linux/module.h> |
29 | #include <linux/ioctl.h> | 30 | #include <linux/ioctl.h> |
30 | #include <linux/i2c.h> | 31 | #include <linux/i2c.h> |
31 | 32 | #include <media/v4l2-common.h> | |
33 | #include <media/v4l2-i2c-drv-legacy.h> | ||
32 | #include "tda9840.h" | 34 | #include "tda9840.h" |
33 | 35 | ||
34 | static int debug; /* insmod parameter */ | 36 | MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); |
37 | MODULE_DESCRIPTION("tda9840 driver"); | ||
38 | MODULE_LICENSE("GPL"); | ||
39 | |||
40 | static int debug; | ||
35 | module_param(debug, int, 0644); | 41 | module_param(debug, int, 0644); |
36 | MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); | ||
37 | 42 | ||
38 | #define dprintk(args...) \ | 43 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
39 | do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __func__, __LINE__); printk(args); } } while (0) | ||
40 | 44 | ||
41 | #define SWITCH 0x00 | 45 | #define SWITCH 0x00 |
42 | #define LEVEL_ADJUST 0x02 | 46 | #define LEVEL_ADJUST 0x02 |
@@ -49,18 +53,21 @@ static unsigned short normal_i2c[] = { I2C_ADDR_TDA9840, I2C_CLIENT_END }; | |||
49 | /* magic definition of all other variables and things */ | 53 | /* magic definition of all other variables and things */ |
50 | I2C_CLIENT_INSMOD; | 54 | I2C_CLIENT_INSMOD; |
51 | 55 | ||
52 | static struct i2c_driver driver; | 56 | static void tda9840_write(struct i2c_client *client, u8 reg, u8 val) |
53 | static struct i2c_client client_template; | 57 | { |
58 | if (i2c_smbus_write_byte_data(client, reg, val)) | ||
59 | v4l_dbg(1, debug, client, "error writing %02x to %02x\n", | ||
60 | val, reg); | ||
61 | } | ||
54 | 62 | ||
55 | static int command(struct i2c_client *client, unsigned int cmd, void *arg) | 63 | static int tda9840_command(struct i2c_client *client, unsigned cmd, void *arg) |
56 | { | 64 | { |
57 | int result; | 65 | int result; |
58 | int byte = *(int *)arg; | 66 | int byte = *(int *)arg; |
59 | 67 | ||
60 | switch (cmd) { | 68 | switch (cmd) { |
61 | case TDA9840_SWITCH: | 69 | case TDA9840_SWITCH: |
62 | 70 | v4l_dbg(1, debug, client, "TDA9840_SWITCH: 0x%02x\n", byte); | |
63 | dprintk("TDA9840_SWITCH: 0x%02x\n", byte); | ||
64 | 71 | ||
65 | if (byte != TDA9840_SET_MONO | 72 | if (byte != TDA9840_SET_MONO |
66 | && byte != TDA9840_SET_MUTE | 73 | && byte != TDA9840_SET_MUTE |
@@ -73,14 +80,11 @@ static int command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
73 | return -EINVAL; | 80 | return -EINVAL; |
74 | } | 81 | } |
75 | 82 | ||
76 | result = i2c_smbus_write_byte_data(client, SWITCH, byte); | 83 | tda9840_write(client, SWITCH, byte); |
77 | if (result) | ||
78 | dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result); | ||
79 | break; | 84 | break; |
80 | 85 | ||
81 | case TDA9840_LEVEL_ADJUST: | 86 | case TDA9840_LEVEL_ADJUST: |
82 | 87 | v4l_dbg(1, debug, client, "TDA9840_LEVEL_ADJUST: %d\n", byte); | |
83 | dprintk("TDA9840_LEVEL_ADJUST: %d\n", byte); | ||
84 | 88 | ||
85 | /* check for correct range */ | 89 | /* check for correct range */ |
86 | if (byte > 25 || byte < -20) | 90 | if (byte > 25 || byte < -20) |
@@ -92,15 +96,11 @@ static int command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
92 | byte += 0x8; | 96 | byte += 0x8; |
93 | else | 97 | else |
94 | byte = -byte; | 98 | byte = -byte; |
95 | 99 | tda9840_write(client, LEVEL_ADJUST, byte); | |
96 | result = i2c_smbus_write_byte_data(client, LEVEL_ADJUST, byte); | ||
97 | if (result) | ||
98 | dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result); | ||
99 | break; | 100 | break; |
100 | 101 | ||
101 | case TDA9840_STEREO_ADJUST: | 102 | case TDA9840_STEREO_ADJUST: |
102 | 103 | v4l_dbg(1, debug, client, "TDA9840_STEREO_ADJUST: %d\n", byte); | |
103 | dprintk("TDA9840_STEREO_ADJUST: %d\n", byte); | ||
104 | 104 | ||
105 | /* check for correct range */ | 105 | /* check for correct range */ |
106 | if (byte > 25 || byte < -24) | 106 | if (byte > 25 || byte < -24) |
@@ -113,9 +113,7 @@ static int command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
113 | else | 113 | else |
114 | byte = -byte; | 114 | byte = -byte; |
115 | 115 | ||
116 | result = i2c_smbus_write_byte_data(client, STEREO_ADJUST, byte); | 116 | tda9840_write(client, STEREO_ADJUST, byte); |
117 | if (result) | ||
118 | dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result); | ||
119 | break; | 117 | break; |
120 | 118 | ||
121 | case TDA9840_DETECT: { | 119 | case TDA9840_DETECT: { |
@@ -123,29 +121,29 @@ static int command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
123 | 121 | ||
124 | byte = i2c_smbus_read_byte_data(client, STEREO_ADJUST); | 122 | byte = i2c_smbus_read_byte_data(client, STEREO_ADJUST); |
125 | if (byte == -1) { | 123 | if (byte == -1) { |
126 | dprintk("i2c_smbus_read_byte_data() failed\n"); | 124 | v4l_dbg(1, debug, client, |
125 | "i2c_smbus_read_byte_data() failed\n"); | ||
127 | return -EIO; | 126 | return -EIO; |
128 | } | 127 | } |
129 | 128 | ||
130 | if (0 != (byte & 0x80)) { | 129 | if (byte & 0x80) { |
131 | dprintk("TDA9840_DETECT: register contents invalid\n"); | 130 | v4l_dbg(1, debug, client, |
131 | "TDA9840_DETECT: register contents invalid\n"); | ||
132 | return -EINVAL; | 132 | return -EINVAL; |
133 | } | 133 | } |
134 | 134 | ||
135 | dprintk("TDA9840_DETECT: byte: 0x%02x\n", byte); | 135 | v4l_dbg(1, debug, client, "TDA9840_DETECT: byte: 0x%02x\n", byte); |
136 | *ret = ((byte & 0x60) >> 5); | 136 | *ret = (byte & 0x60) >> 5; |
137 | result = 0; | 137 | result = 0; |
138 | break; | 138 | break; |
139 | } | 139 | } |
140 | case TDA9840_TEST: | 140 | case TDA9840_TEST: |
141 | dprintk("TDA9840_TEST: 0x%02x\n", byte); | 141 | v4l_dbg(1, debug, client, "TDA9840_TEST: 0x%02x\n", byte); |
142 | 142 | ||
143 | /* mask out irrelevant bits */ | 143 | /* mask out irrelevant bits */ |
144 | byte &= 0x3; | 144 | byte &= 0x3; |
145 | 145 | ||
146 | result = i2c_smbus_write_byte_data(client, TEST, byte); | 146 | tda9840_write(client, TEST, byte); |
147 | if (result) | ||
148 | dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result); | ||
149 | break; | 147 | break; |
150 | default: | 148 | default: |
151 | return -ENOIOCTLCMD; | 149 | return -ENOIOCTLCMD; |
@@ -157,99 +155,51 @@ static int command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
157 | return 0; | 155 | return 0; |
158 | } | 156 | } |
159 | 157 | ||
160 | static int detect(struct i2c_adapter *adapter, int address, int kind) | 158 | static int tda9840_probe(struct i2c_client *client, |
159 | const struct i2c_device_id *id) | ||
161 | { | 160 | { |
162 | struct i2c_client *client; | 161 | int result; |
163 | int result = 0; | 162 | int byte; |
164 | |||
165 | int byte = 0x0; | ||
166 | 163 | ||
167 | /* let's see whether this adapter can support what we need */ | 164 | /* let's see whether this adapter can support what we need */ |
168 | if (0 == i2c_check_functionality(adapter, | 165 | if (!i2c_check_functionality(client->adapter, |
169 | I2C_FUNC_SMBUS_READ_BYTE_DATA | | 166 | I2C_FUNC_SMBUS_READ_BYTE_DATA | |
170 | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { | 167 | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) |
171 | return 0; | 168 | return 0; |
172 | } | ||
173 | 169 | ||
174 | /* allocate memory for client structure */ | 170 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
175 | client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); | 171 | client->addr << 1, client->adapter->name); |
176 | if (!client) { | ||
177 | printk("not enough kernel memory\n"); | ||
178 | return -ENOMEM; | ||
179 | } | ||
180 | |||
181 | /* fill client structure */ | ||
182 | memcpy(client, &client_template, sizeof(struct i2c_client)); | ||
183 | client->addr = address; | ||
184 | client->adapter = adapter; | ||
185 | |||
186 | /* tell the i2c layer a new client has arrived */ | ||
187 | if (0 != (result = i2c_attach_client(client))) { | ||
188 | kfree(client); | ||
189 | return result; | ||
190 | } | ||
191 | 172 | ||
192 | /* set initial values for level & stereo - adjustment, mode */ | 173 | /* set initial values for level & stereo - adjustment, mode */ |
193 | byte = 0; | 174 | byte = 0; |
194 | result = command(client, TDA9840_LEVEL_ADJUST, &byte); | 175 | result = tda9840_command(client, TDA9840_LEVEL_ADJUST, &byte); |
195 | result += command(client, TDA9840_STEREO_ADJUST, &byte); | 176 | result += tda9840_command(client, TDA9840_STEREO_ADJUST, &byte); |
196 | byte = TDA9840_SET_MONO; | 177 | byte = TDA9840_SET_MONO; |
197 | result = command(client, TDA9840_SWITCH, &byte); | 178 | result = tda9840_command(client, TDA9840_SWITCH, &byte); |
198 | if (result) { | 179 | if (result) { |
199 | dprintk("could not initialize tda9840\n"); | 180 | v4l_dbg(1, debug, client, "could not initialize tda9840\n"); |
200 | return -ENODEV; | 181 | return -ENODEV; |
201 | } | 182 | } |
202 | |||
203 | printk("tda9840: detected @ 0x%02x on adapter %s\n", address, &client->adapter->name[0]); | ||
204 | return 0; | 183 | return 0; |
205 | } | 184 | } |
206 | 185 | ||
207 | static int attach(struct i2c_adapter *adapter) | 186 | static int tda9840_legacy_probe(struct i2c_adapter *adapter) |
208 | { | 187 | { |
209 | /* let's see whether this is a know adapter we can attach to */ | 188 | /* Let's see whether this is a known adapter we can attach to. |
210 | if (adapter->id != I2C_HW_SAA7146) { | 189 | Prevents conflicts with tvaudio.c. */ |
211 | dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id); | 190 | return adapter->id == I2C_HW_SAA7146; |
212 | return -ENODEV; | ||
213 | } | ||
214 | |||
215 | return i2c_probe(adapter, &addr_data, &detect); | ||
216 | } | 191 | } |
217 | 192 | static const struct i2c_device_id tda9840_id[] = { | |
218 | static int detach(struct i2c_client *client) | 193 | { "tda9840", 0 }, |
219 | { | 194 | { } |
220 | int ret = i2c_detach_client(client); | ||
221 | kfree(client); | ||
222 | return ret; | ||
223 | } | ||
224 | |||
225 | static struct i2c_driver driver = { | ||
226 | .driver = { | ||
227 | .name = "tda9840", | ||
228 | }, | ||
229 | .id = I2C_DRIVERID_TDA9840, | ||
230 | .attach_adapter = attach, | ||
231 | .detach_client = detach, | ||
232 | .command = command, | ||
233 | }; | 195 | }; |
196 | MODULE_DEVICE_TABLE(i2c, tda9840_id); | ||
234 | 197 | ||
235 | static struct i2c_client client_template = { | 198 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { |
236 | .name = "tda9840", | 199 | .name = "tda9840", |
237 | .driver = &driver, | 200 | .driverid = I2C_DRIVERID_TDA9840, |
201 | .command = tda9840_command, | ||
202 | .probe = tda9840_probe, | ||
203 | .legacy_probe = tda9840_legacy_probe, | ||
204 | .id_table = tda9840_id, | ||
238 | }; | 205 | }; |
239 | |||
240 | static int __init this_module_init(void) | ||
241 | { | ||
242 | return i2c_add_driver(&driver); | ||
243 | } | ||
244 | |||
245 | static void __exit this_module_exit(void) | ||
246 | { | ||
247 | i2c_del_driver(&driver); | ||
248 | } | ||
249 | |||
250 | module_init(this_module_init); | ||
251 | module_exit(this_module_exit); | ||
252 | |||
253 | MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); | ||
254 | MODULE_DESCRIPTION("tda9840 driver"); | ||
255 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c index 421c1445e96c..cde092adbb5a 100644 --- a/drivers/media/video/tea6415c.c +++ b/drivers/media/video/tea6415c.c | |||
@@ -2,6 +2,7 @@ | |||
2 | tea6415c - i2c-driver for the tea6415c by SGS Thomson | 2 | tea6415c - i2c-driver for the tea6415c by SGS Thomson |
3 | 3 | ||
4 | Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de> | 4 | Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de> |
5 | Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl> | ||
5 | 6 | ||
6 | The tea6415c is a bus controlled video-matrix-switch | 7 | The tea6415c is a bus controlled video-matrix-switch |
7 | with 8 inputs and 6 outputs. | 8 | with 8 inputs and 6 outputs. |
@@ -30,18 +31,18 @@ | |||
30 | #include <linux/module.h> | 31 | #include <linux/module.h> |
31 | #include <linux/ioctl.h> | 32 | #include <linux/ioctl.h> |
32 | #include <linux/i2c.h> | 33 | #include <linux/i2c.h> |
33 | 34 | #include <media/v4l2-common.h> | |
35 | #include <media/v4l2-i2c-drv-legacy.h> | ||
34 | #include "tea6415c.h" | 36 | #include "tea6415c.h" |
35 | 37 | ||
36 | static int debug; /* insmod parameter */ | 38 | MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); |
37 | module_param(debug, int, 0644); | 39 | MODULE_DESCRIPTION("tea6415c driver"); |
38 | MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); | 40 | MODULE_LICENSE("GPL"); |
39 | 41 | ||
40 | #define dprintk(args...) \ | 42 | static int debug; |
41 | do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __func__, __LINE__); printk(args); } } while (0) | 43 | module_param(debug, int, 0644); |
42 | 44 | ||
43 | #define TEA6415C_NUM_INPUTS 8 | 45 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
44 | #define TEA6415C_NUM_OUTPUTS 6 | ||
45 | 46 | ||
46 | /* addresses to scan, found only at 0x03 and/or 0x43 (7-bit) */ | 47 | /* addresses to scan, found only at 0x03 and/or 0x43 (7-bit) */ |
47 | static unsigned short normal_i2c[] = { I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIENT_END }; | 48 | static unsigned short normal_i2c[] = { I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIENT_END }; |
@@ -49,60 +50,6 @@ static unsigned short normal_i2c[] = { I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIEN | |||
49 | /* magic definition of all other variables and things */ | 50 | /* magic definition of all other variables and things */ |
50 | I2C_CLIENT_INSMOD; | 51 | I2C_CLIENT_INSMOD; |
51 | 52 | ||
52 | static struct i2c_driver driver; | ||
53 | static struct i2c_client client_template; | ||
54 | |||
55 | /* this function is called by i2c_probe */ | ||
56 | static int detect(struct i2c_adapter *adapter, int address, int kind) | ||
57 | { | ||
58 | struct i2c_client *client = NULL; | ||
59 | int err = 0; | ||
60 | |||
61 | /* let's see whether this adapter can support what we need */ | ||
62 | if (0 == i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) { | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | /* allocate memory for client structure */ | ||
67 | client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
68 | if (!client) { | ||
69 | return -ENOMEM; | ||
70 | } | ||
71 | |||
72 | /* fill client structure */ | ||
73 | memcpy(client, &client_template, sizeof(struct i2c_client)); | ||
74 | client->addr = address; | ||
75 | client->adapter = adapter; | ||
76 | |||
77 | /* tell the i2c layer a new client has arrived */ | ||
78 | if (0 != (err = i2c_attach_client(client))) { | ||
79 | kfree(client); | ||
80 | return err; | ||
81 | } | ||
82 | |||
83 | printk("tea6415c: detected @ 0x%02x on adapter %s\n", address, &client->adapter->name[0]); | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static int attach(struct i2c_adapter *adapter) | ||
89 | { | ||
90 | /* let's see whether this is a know adapter we can attach to */ | ||
91 | if (adapter->id != I2C_HW_SAA7146) { | ||
92 | dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id); | ||
93 | return -ENODEV; | ||
94 | } | ||
95 | |||
96 | return i2c_probe(adapter, &addr_data, &detect); | ||
97 | } | ||
98 | |||
99 | static int detach(struct i2c_client *client) | ||
100 | { | ||
101 | int ret = i2c_detach_client(client); | ||
102 | kfree(client); | ||
103 | return ret; | ||
104 | } | ||
105 | |||
106 | /* makes a connection between the input-pin 'i' and the output-pin 'o' | 53 | /* makes a connection between the input-pin 'i' and the output-pin 'o' |
107 | for the tea6415c-client 'client' */ | 54 | for the tea6415c-client 'client' */ |
108 | static int switch_matrix(struct i2c_client *client, int i, int o) | 55 | static int switch_matrix(struct i2c_client *client, int i, int o) |
@@ -110,7 +57,7 @@ static int switch_matrix(struct i2c_client *client, int i, int o) | |||
110 | u8 byte = 0; | 57 | u8 byte = 0; |
111 | int ret; | 58 | int ret; |
112 | 59 | ||
113 | dprintk("adr:0x%02x, i:%d, o:%d\n", client->addr, i, o); | 60 | v4l_dbg(1, debug, client, "i=%d, o=%d\n", i, o); |
114 | 61 | ||
115 | /* check if the pins are valid */ | 62 | /* check if the pins are valid */ |
116 | if (0 == ((1 == i || 3 == i || 5 == i || 6 == i || 8 == i || 10 == i || 20 == i || 11 == i) | 63 | if (0 == ((1 == i || 3 == i || 5 == i || 6 == i || 8 == i || 10 == i || 20 == i || 11 == i) |
@@ -168,14 +115,14 @@ static int switch_matrix(struct i2c_client *client, int i, int o) | |||
168 | 115 | ||
169 | ret = i2c_smbus_write_byte(client, byte); | 116 | ret = i2c_smbus_write_byte(client, byte); |
170 | if (ret) { | 117 | if (ret) { |
171 | dprintk("i2c_smbus_write_byte() failed, ret:%d\n", ret); | 118 | v4l_dbg(1, debug, client, |
119 | "i2c_smbus_write_byte() failed, ret:%d\n", ret); | ||
172 | return -EIO; | 120 | return -EIO; |
173 | } | 121 | } |
174 | |||
175 | return ret; | 122 | return ret; |
176 | } | 123 | } |
177 | 124 | ||
178 | static int command(struct i2c_client *client, unsigned int cmd, void *arg) | 125 | static int tea6415c_command(struct i2c_client *client, unsigned cmd, void *arg) |
179 | { | 126 | { |
180 | struct tea6415c_multiplex *v = (struct tea6415c_multiplex *)arg; | 127 | struct tea6415c_multiplex *v = (struct tea6415c_multiplex *)arg; |
181 | int result = 0; | 128 | int result = 0; |
@@ -187,38 +134,40 @@ static int command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
187 | default: | 134 | default: |
188 | return -ENOIOCTLCMD; | 135 | return -ENOIOCTLCMD; |
189 | } | 136 | } |
190 | |||
191 | return result; | 137 | return result; |
192 | } | 138 | } |
193 | 139 | ||
194 | static struct i2c_driver driver = { | 140 | /* this function is called by i2c_probe */ |
195 | .driver = { | 141 | static int tea6415c_probe(struct i2c_client *client, |
196 | .name = "tea6415c", | 142 | const struct i2c_device_id *id) |
197 | }, | ||
198 | .id = I2C_DRIVERID_TEA6415C, | ||
199 | .attach_adapter = attach, | ||
200 | .detach_client = detach, | ||
201 | .command = command, | ||
202 | }; | ||
203 | |||
204 | static struct i2c_client client_template = { | ||
205 | .name = "tea6415c", | ||
206 | .driver = &driver, | ||
207 | }; | ||
208 | |||
209 | static int __init this_module_init(void) | ||
210 | { | 143 | { |
211 | return i2c_add_driver(&driver); | 144 | /* let's see whether this adapter can support what we need */ |
145 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) | ||
146 | return 0; | ||
147 | |||
148 | v4l_info(client, "chip found @ 0x%x (%s)\n", | ||
149 | client->addr << 1, client->adapter->name); | ||
150 | return 0; | ||
212 | } | 151 | } |
213 | 152 | ||
214 | static void __exit this_module_exit(void) | 153 | static int tea6415c_legacy_probe(struct i2c_adapter *adapter) |
215 | { | 154 | { |
216 | i2c_del_driver(&driver); | 155 | /* Let's see whether this is a known adapter we can attach to. |
156 | Prevents conflicts with tvaudio.c. */ | ||
157 | return adapter->id == I2C_HW_SAA7146; | ||
217 | } | 158 | } |
218 | 159 | ||
219 | module_init(this_module_init); | 160 | static const struct i2c_device_id tea6415c_id[] = { |
220 | module_exit(this_module_exit); | 161 | { "tea6415c", 0 }, |
162 | { } | ||
163 | }; | ||
164 | MODULE_DEVICE_TABLE(i2c, tea6415c_id); | ||
221 | 165 | ||
222 | MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); | 166 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { |
223 | MODULE_DESCRIPTION("tea6415c driver"); | 167 | .name = "tea6415c", |
224 | MODULE_LICENSE("GPL"); | 168 | .driverid = I2C_DRIVERID_TEA6415C, |
169 | .command = tea6415c_command, | ||
170 | .probe = tea6415c_probe, | ||
171 | .legacy_probe = tea6415c_legacy_probe, | ||
172 | .id_table = tea6415c_id, | ||
173 | }; | ||
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c index b5c8957d130e..e50820969e64 100644 --- a/drivers/media/video/tea6420.c +++ b/drivers/media/video/tea6420.c | |||
@@ -2,6 +2,7 @@ | |||
2 | tea6420 - i2c-driver for the tea6420 by SGS Thomson | 2 | tea6420 - i2c-driver for the tea6420 by SGS Thomson |
3 | 3 | ||
4 | Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de> | 4 | Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de> |
5 | Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl> | ||
5 | 6 | ||
6 | The tea6420 is a bus controlled audio-matrix with 5 stereo inputs, | 7 | The tea6420 is a bus controlled audio-matrix with 5 stereo inputs, |
7 | 4 stereo outputs and gain control for each output. | 8 | 4 stereo outputs and gain control for each output. |
@@ -30,15 +31,18 @@ | |||
30 | #include <linux/module.h> | 31 | #include <linux/module.h> |
31 | #include <linux/ioctl.h> | 32 | #include <linux/ioctl.h> |
32 | #include <linux/i2c.h> | 33 | #include <linux/i2c.h> |
33 | 34 | #include <media/v4l2-common.h> | |
35 | #include <media/v4l2-i2c-drv-legacy.h> | ||
34 | #include "tea6420.h" | 36 | #include "tea6420.h" |
35 | 37 | ||
36 | static int debug; /* insmod parameter */ | 38 | MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); |
39 | MODULE_DESCRIPTION("tea6420 driver"); | ||
40 | MODULE_LICENSE("GPL"); | ||
41 | |||
42 | static int debug; | ||
37 | module_param(debug, int, 0644); | 43 | module_param(debug, int, 0644); |
38 | MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); | ||
39 | 44 | ||
40 | #define dprintk(args...) \ | 45 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
41 | do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __func__, __LINE__); printk(args); } } while (0) | ||
42 | 46 | ||
43 | /* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */ | 47 | /* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */ |
44 | static unsigned short normal_i2c[] = { I2C_ADDR_TEA6420_1, I2C_ADDR_TEA6420_2, I2C_CLIENT_END }; | 48 | static unsigned short normal_i2c[] = { I2C_ADDR_TEA6420_1, I2C_ADDR_TEA6420_2, I2C_CLIENT_END }; |
@@ -46,23 +50,20 @@ static unsigned short normal_i2c[] = { I2C_ADDR_TEA6420_1, I2C_ADDR_TEA6420_2, I | |||
46 | /* magic definition of all other variables and things */ | 50 | /* magic definition of all other variables and things */ |
47 | I2C_CLIENT_INSMOD; | 51 | I2C_CLIENT_INSMOD; |
48 | 52 | ||
49 | static struct i2c_driver driver; | ||
50 | static struct i2c_client client_template; | ||
51 | |||
52 | /* make a connection between the input 'i' and the output 'o' | 53 | /* make a connection between the input 'i' and the output 'o' |
53 | with gain 'g' for the tea6420-client 'client' (note: i = 6 means 'mute') */ | 54 | with gain 'g' for the tea6420-client 'client' (note: i = 6 means 'mute') */ |
54 | static int tea6420_switch(struct i2c_client *client, int i, int o, int g) | 55 | static int tea6420_switch(struct i2c_client *client, int i, int o, int g) |
55 | { | 56 | { |
56 | u8 byte = 0; | 57 | u8 byte; |
57 | int ret; | 58 | int ret; |
58 | 59 | ||
59 | dprintk("adr:0x%02x, i:%d, o:%d, g:%d\n", client->addr, i, o, g); | 60 | v4l_dbg(1, debug, client, "i=%d, o=%d, g=%d\n", i, o, g); |
60 | 61 | ||
61 | /* check if the parameters are valid */ | 62 | /* check if the parameters are valid */ |
62 | if (i < 1 || i > 6 || o < 1 || o > 4 || g < 0 || g > 6 || g % 2 != 0) | 63 | if (i < 1 || i > 6 || o < 1 || o > 4 || g < 0 || g > 6 || g % 2 != 0) |
63 | return -1; | 64 | return -1; |
64 | 65 | ||
65 | byte = ((o - 1) << 5); | 66 | byte = ((o - 1) << 5); |
66 | byte |= (i - 1); | 67 | byte |= (i - 1); |
67 | 68 | ||
68 | /* to understand this, have a look at the tea6420-specs (p.5) */ | 69 | /* to understand this, have a look at the tea6420-specs (p.5) */ |
@@ -82,40 +83,41 @@ static int tea6420_switch(struct i2c_client *client, int i, int o, int g) | |||
82 | 83 | ||
83 | ret = i2c_smbus_write_byte(client, byte); | 84 | ret = i2c_smbus_write_byte(client, byte); |
84 | if (ret) { | 85 | if (ret) { |
85 | dprintk("i2c_smbus_write_byte() failed, ret:%d\n", ret); | 86 | v4l_dbg(1, debug, client, |
87 | "i2c_smbus_write_byte() failed, ret:%d\n", ret); | ||
86 | return -EIO; | 88 | return -EIO; |
87 | } | 89 | } |
88 | |||
89 | return 0; | 90 | return 0; |
90 | } | 91 | } |
91 | 92 | ||
92 | /* this function is called by i2c_probe */ | 93 | static int tea6420_command(struct i2c_client *client, unsigned cmd, void *arg) |
93 | static int tea6420_detect(struct i2c_adapter *adapter, int address, int kind) | ||
94 | { | 94 | { |
95 | struct i2c_client *client; | 95 | struct tea6420_multiplex *a = (struct tea6420_multiplex *)arg; |
96 | int err = 0, i = 0; | 96 | int result = 0; |
97 | 97 | ||
98 | /* let's see whether this adapter can support what we need */ | 98 | switch (cmd) { |
99 | if (0 == i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) { | 99 | case TEA6420_SWITCH: |
100 | return 0; | 100 | result = tea6420_switch(client, a->in, a->out, a->gain); |
101 | break; | ||
102 | default: | ||
103 | return -ENOIOCTLCMD; | ||
101 | } | 104 | } |
102 | 105 | ||
103 | /* allocate memory for client structure */ | 106 | return result; |
104 | client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | 107 | } |
105 | if (!client) { | ||
106 | return -ENOMEM; | ||
107 | } | ||
108 | 108 | ||
109 | /* fill client structure */ | 109 | /* this function is called by i2c_probe */ |
110 | memcpy(client, &client_template, sizeof(struct i2c_client)); | 110 | static int tea6420_probe(struct i2c_client *client, |
111 | client->addr = address; | 111 | const struct i2c_device_id *id) |
112 | client->adapter = adapter; | 112 | { |
113 | int err, i; | ||
113 | 114 | ||
114 | /* tell the i2c layer a new client has arrived */ | 115 | /* let's see whether this adapter can support what we need */ |
115 | if (0 != (err = i2c_attach_client(client))) { | 116 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) |
116 | kfree(client); | 117 | return -EIO; |
117 | return err; | 118 | |
118 | } | 119 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
120 | client->addr << 1, client->adapter->name); | ||
119 | 121 | ||
120 | /* set initial values: set "mute"-input to all outputs at gain 0 */ | 122 | /* set initial values: set "mute"-input to all outputs at gain 0 */ |
121 | err = 0; | 123 | err = 0; |
@@ -123,78 +125,31 @@ static int tea6420_detect(struct i2c_adapter *adapter, int address, int kind) | |||
123 | err += tea6420_switch(client, 6, i, 0); | 125 | err += tea6420_switch(client, 6, i, 0); |
124 | } | 126 | } |
125 | if (err) { | 127 | if (err) { |
126 | dprintk("could not initialize tea6420\n"); | 128 | v4l_dbg(1, debug, client, "could not initialize tea6420\n"); |
127 | kfree(client); | 129 | kfree(client); |
128 | return -ENODEV; | 130 | return -ENODEV; |
129 | } | 131 | } |
130 | |||
131 | printk("tea6420: detected @ 0x%02x on adapter %s\n", address, &client->adapter->name[0]); | ||
132 | |||
133 | return 0; | 132 | return 0; |
134 | } | 133 | } |
135 | 134 | ||
136 | static int attach(struct i2c_adapter *adapter) | 135 | static int tea6420_legacy_probe(struct i2c_adapter *adapter) |
137 | { | 136 | { |
138 | /* let's see whether this is a know adapter we can attach to */ | 137 | /* Let's see whether this is a known adapter we can attach to. |
139 | if (adapter->id != I2C_HW_SAA7146) { | 138 | Prevents conflicts with tvaudio.c. */ |
140 | dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id); | 139 | return adapter->id == I2C_HW_SAA7146; |
141 | return -ENODEV; | ||
142 | } | ||
143 | |||
144 | return i2c_probe(adapter, &addr_data, &tea6420_detect); | ||
145 | } | ||
146 | |||
147 | static int detach(struct i2c_client *client) | ||
148 | { | ||
149 | int ret = i2c_detach_client(client); | ||
150 | kfree(client); | ||
151 | return ret; | ||
152 | } | ||
153 | |||
154 | static int command(struct i2c_client *client, unsigned int cmd, void *arg) | ||
155 | { | ||
156 | struct tea6420_multiplex *a = (struct tea6420_multiplex *)arg; | ||
157 | int result = 0; | ||
158 | |||
159 | switch (cmd) { | ||
160 | case TEA6420_SWITCH: | ||
161 | result = tea6420_switch(client, a->in, a->out, a->gain); | ||
162 | break; | ||
163 | default: | ||
164 | return -ENOIOCTLCMD; | ||
165 | } | ||
166 | |||
167 | return result; | ||
168 | } | 140 | } |
169 | 141 | ||
170 | static struct i2c_driver driver = { | 142 | static const struct i2c_device_id tea6420_id[] = { |
171 | .driver = { | 143 | { "tea6420", 0 }, |
172 | .name = "tea6420", | 144 | { } |
173 | }, | ||
174 | .id = I2C_DRIVERID_TEA6420, | ||
175 | .attach_adapter = attach, | ||
176 | .detach_client = detach, | ||
177 | .command = command, | ||
178 | }; | 145 | }; |
146 | MODULE_DEVICE_TABLE(i2c, tea6420_id); | ||
179 | 147 | ||
180 | static struct i2c_client client_template = { | 148 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { |
181 | .name = "tea6420", | 149 | .name = "tea6420", |
182 | .driver = &driver, | 150 | .driverid = I2C_DRIVERID_TEA6420, |
151 | .command = tea6420_command, | ||
152 | .probe = tea6420_probe, | ||
153 | .legacy_probe = tea6420_legacy_probe, | ||
154 | .id_table = tea6420_id, | ||
183 | }; | 155 | }; |
184 | |||
185 | static int __init this_module_init(void) | ||
186 | { | ||
187 | return i2c_add_driver(&driver); | ||
188 | } | ||
189 | |||
190 | static void __exit this_module_exit(void) | ||
191 | { | ||
192 | i2c_del_driver(&driver); | ||
193 | } | ||
194 | |||
195 | module_init(this_module_init); | ||
196 | module_exit(this_module_exit); | ||
197 | |||
198 | MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); | ||
199 | MODULE_DESCRIPTION("tea6420 driver"); | ||
200 | MODULE_LICENSE("GPL"); | ||