diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2008-07-25 09:31:23 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-10-12 07:36:47 -0400 |
commit | a832781cd383e70929c0ceece23f8a5b62e2152b (patch) | |
tree | 966f4f97ee68a0d62c59c431d7a00d63c4ac1a19 /drivers/media/video/tda9840.c | |
parent | 7d341a6a52f115512d60b2de89b2ebde54da8eff (diff) |
V4L/DVB (8630): First mxb cleanup phase
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/tda9840.c')
-rw-r--r-- | drivers/media/video/tda9840.c | 166 |
1 files changed, 58 insertions, 108 deletions
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"); | ||