aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/tea6420.c
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2009-02-07 09:18:05 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:42:42 -0400
commit1b8dac150a01e2312d8e3fedd6462a0ec34c96d0 (patch)
treeba8fd678a4afb4bd72960e1737f857991fd00a19 /drivers/media/video/tea6420.c
parentd30e21ddcdc948ecedfb46a0ed021d57f310a6f3 (diff)
V4L/DVB (10499): saa7146: convert saa7146 and mxb in particular to v4l2_subdev.
Modified mxb to load the i2c modules through v4l2_subdev. So no more probing. Modified tea6415c and tea6420 to use the standard routing ops to do the routing, rather than using private commands. Dropped the private commands from tda9840 (they were never used except during initialization of the module). Added saa7146 support for VIDIOC_DBG_G_CHIP_IDENT. Converted saa5246a and saa5249 to v4l2_subdev. Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/tea6420.c')
-rw-r--r--drivers/media/video/tea6420.c68
1 files changed, 30 insertions, 38 deletions
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c
index 7546509c8282..34922232402a 100644
--- a/drivers/media/video/tea6420.c
+++ b/drivers/media/video/tea6420.c
@@ -32,7 +32,8 @@
32#include <linux/ioctl.h> 32#include <linux/ioctl.h>
33#include <linux/i2c.h> 33#include <linux/i2c.h>
34#include <media/v4l2-device.h> 34#include <media/v4l2-device.h>
35#include <media/v4l2-i2c-drv-legacy.h> 35#include <media/v4l2-chip-ident.h>
36#include <media/v4l2-i2c-drv.h>
36#include "tea6420.h" 37#include "tea6420.h"
37 38
38MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); 39MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
@@ -44,24 +45,23 @@ module_param(debug, int, 0644);
44 45
45MODULE_PARM_DESC(debug, "Debug level (0-1)"); 46MODULE_PARM_DESC(debug, "Debug level (0-1)");
46 47
47/* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */
48static unsigned short normal_i2c[] = { I2C_ADDR_TEA6420_1, I2C_ADDR_TEA6420_2, I2C_CLIENT_END };
49
50/* magic definition of all other variables and things */
51I2C_CLIENT_INSMOD;
52 48
53/* make a connection between the input 'i' and the output 'o' 49/* make a connection between the input 'i' and the output 'o'
54 with gain 'g' for the tea6420-client 'client' (note: i = 6 means 'mute') */ 50 with gain 'g' (note: i = 6 means 'mute') */
55static int tea6420_switch(struct i2c_client *client, int i, int o, int g) 51static int tea6420_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
56{ 52{
53 struct i2c_client *client = v4l2_get_subdevdata(sd);
54 int i = route->input;
55 int o = route->output & 0xf;
56 int g = (route->output >> 4) & 0xf;
57 u8 byte; 57 u8 byte;
58 int ret; 58 int ret;
59 59
60 v4l_dbg(1, debug, client, "i=%d, o=%d, g=%d\n", i, o, g); 60 v4l2_dbg(1, debug, sd, "i=%d, o=%d, g=%d\n", i, o, g);
61 61
62 /* check if the parameters are valid */ 62 /* check if the parameters are valid */
63 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)
64 return -1; 64 return -EINVAL;
65 65
66 byte = ((o - 1) << 5); 66 byte = ((o - 1) << 5);
67 byte |= (i - 1); 67 byte |= (i - 1);
@@ -83,37 +83,33 @@ static int tea6420_switch(struct i2c_client *client, int i, int o, int g)
83 83
84 ret = i2c_smbus_write_byte(client, byte); 84 ret = i2c_smbus_write_byte(client, byte);
85 if (ret) { 85 if (ret) {
86 v4l_dbg(1, debug, client, 86 v4l2_dbg(1, debug, sd,
87 "i2c_smbus_write_byte() failed, ret:%d\n", ret); 87 "i2c_smbus_write_byte() failed, ret:%d\n", ret);
88 return -EIO; 88 return -EIO;
89 } 89 }
90 return 0; 90 return 0;
91} 91}
92 92
93static long tea6420_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg) 93static int tea6420_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
94{ 94{
95 if (cmd == TEA6420_SWITCH) { 95 struct i2c_client *client = v4l2_get_subdevdata(sd);
96 struct i2c_client *client = v4l2_get_subdevdata(sd);
97 struct tea6420_multiplex *a = (struct tea6420_multiplex *)arg;
98 96
99 return tea6420_switch(client, a->in, a->out, a->gain); 97 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEA6420, 0);
100 }
101 return -ENOIOCTLCMD;
102}
103
104static int tea6420_command(struct i2c_client *client, unsigned cmd, void *arg)
105{
106 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
107} 98}
108 99
109/* ----------------------------------------------------------------------- */ 100/* ----------------------------------------------------------------------- */
110 101
111static const struct v4l2_subdev_core_ops tea6420_core_ops = { 102static const struct v4l2_subdev_core_ops tea6420_core_ops = {
112 .ioctl = tea6420_ioctl, 103 .g_chip_ident = tea6420_g_chip_ident,
104};
105
106static const struct v4l2_subdev_audio_ops tea6420_audio_ops = {
107 .s_routing = tea6420_s_routing,
113}; 108};
114 109
115static const struct v4l2_subdev_ops tea6420_ops = { 110static const struct v4l2_subdev_ops tea6420_ops = {
116 .core = &tea6420_core_ops, 111 .core = &tea6420_core_ops,
112 .audio = &tea6420_audio_ops,
117}; 113};
118 114
119/* this function is called by i2c_probe */ 115/* this function is called by i2c_probe */
@@ -130,20 +126,24 @@ static int tea6420_probe(struct i2c_client *client,
130 v4l_info(client, "chip found @ 0x%x (%s)\n", 126 v4l_info(client, "chip found @ 0x%x (%s)\n",
131 client->addr << 1, client->adapter->name); 127 client->addr << 1, client->adapter->name);
132 128
129 sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
130 if (sd == NULL)
131 return -ENOMEM;
132 v4l2_i2c_subdev_init(sd, client, &tea6420_ops);
133
133 /* set initial values: set "mute"-input to all outputs at gain 0 */ 134 /* set initial values: set "mute"-input to all outputs at gain 0 */
134 err = 0; 135 err = 0;
135 for (i = 1; i < 5; i++) { 136 for (i = 1; i < 5; i++) {
136 err += tea6420_switch(client, 6, i, 0); 137 struct v4l2_routing route;
138
139 route.input = 6;
140 route.output = i;
141 err += tea6420_s_routing(sd, &route);
137 } 142 }
138 if (err) { 143 if (err) {
139 v4l_dbg(1, debug, client, "could not initialize tea6420\n"); 144 v4l_dbg(1, debug, client, "could not initialize tea6420\n");
140 return -ENODEV; 145 return -ENODEV;
141 } 146 }
142
143 sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
144 if (sd == NULL)
145 return -ENOMEM;
146 v4l2_i2c_subdev_init(sd, client, &tea6420_ops);
147 return 0; 147 return 0;
148} 148}
149 149
@@ -156,12 +156,6 @@ static int tea6420_remove(struct i2c_client *client)
156 return 0; 156 return 0;
157} 157}
158 158
159static int tea6420_legacy_probe(struct i2c_adapter *adapter)
160{
161 /* Let's see whether this is a known adapter we can attach to.
162 Prevents conflicts with tvaudio.c. */
163 return adapter->id == I2C_HW_SAA7146;
164}
165 159
166static const struct i2c_device_id tea6420_id[] = { 160static const struct i2c_device_id tea6420_id[] = {
167 { "tea6420", 0 }, 161 { "tea6420", 0 },
@@ -171,9 +165,7 @@ MODULE_DEVICE_TABLE(i2c, tea6420_id);
171 165
172static struct v4l2_i2c_driver_data v4l2_i2c_data = { 166static struct v4l2_i2c_driver_data v4l2_i2c_data = {
173 .name = "tea6420", 167 .name = "tea6420",
174 .command = tea6420_command,
175 .probe = tea6420_probe, 168 .probe = tea6420_probe,
176 .remove = tea6420_remove, 169 .remove = tea6420_remove,
177 .legacy_probe = tea6420_legacy_probe,
178 .id_table = tea6420_id, 170 .id_table = tea6420_id,
179}; 171};