diff options
Diffstat (limited to 'drivers/media/video/vp27smpx.c')
-rw-r--r-- | drivers/media/video/vp27smpx.c | 71 |
1 files changed, 13 insertions, 58 deletions
diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/video/vp27smpx.c index 63002e0ac764..24a942315042 100644 --- a/drivers/media/video/vp27smpx.c +++ b/drivers/media/video/vp27smpx.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/videodev.h> | 30 | #include <linux/videodev.h> |
31 | #include <media/v4l2-common.h> | 31 | #include <media/v4l2-common.h> |
32 | #include <media/v4l2-chip-ident.h> | 32 | #include <media/v4l2-chip-ident.h> |
33 | #include <media/v4l2-i2c-drv-legacy.h> | ||
33 | 34 | ||
34 | MODULE_DESCRIPTION("vp27smpx driver"); | 35 | MODULE_DESCRIPTION("vp27smpx driver"); |
35 | MODULE_AUTHOR("Hans Verkuil"); | 36 | MODULE_AUTHOR("Hans Verkuil"); |
@@ -73,8 +74,7 @@ static void vp27smpx_set_audmode(struct i2c_client *client, u32 audmode) | |||
73 | } | 74 | } |
74 | } | 75 | } |
75 | 76 | ||
76 | static int vp27smpx_command(struct i2c_client *client, unsigned int cmd, | 77 | static int vp27smpx_command(struct i2c_client *client, unsigned int cmd, void *arg) |
77 | void *arg) | ||
78 | { | 78 | { |
79 | struct vp27smpx_state *state = i2c_get_clientdata(client); | 79 | struct vp27smpx_state *state = i2c_get_clientdata(client); |
80 | struct v4l2_tuner *vt = arg; | 80 | struct v4l2_tuner *vt = arg; |
@@ -125,31 +125,20 @@ static int vp27smpx_command(struct i2c_client *client, unsigned int cmd, | |||
125 | * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' | 125 | * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' |
126 | */ | 126 | */ |
127 | 127 | ||
128 | static struct i2c_driver i2c_driver; | 128 | static int vp27smpx_probe(struct i2c_client *client) |
129 | |||
130 | static int vp27smpx_attach(struct i2c_adapter *adapter, int address, int kind) | ||
131 | { | 129 | { |
132 | struct i2c_client *client; | ||
133 | struct vp27smpx_state *state; | 130 | struct vp27smpx_state *state; |
134 | 131 | ||
135 | /* Check if the adapter supports the needed features */ | 132 | /* Check if the adapter supports the needed features */ |
136 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 133 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
137 | return 0; | 134 | return 0; |
138 | 135 | ||
139 | client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
140 | if (client == 0) | ||
141 | return -ENOMEM; | ||
142 | |||
143 | client->addr = address; | ||
144 | client->adapter = adapter; | ||
145 | client->driver = &i2c_driver; | ||
146 | snprintf(client->name, sizeof(client->name) - 1, "vp27smpx"); | 136 | snprintf(client->name, sizeof(client->name) - 1, "vp27smpx"); |
147 | 137 | ||
148 | v4l_info(client, "chip found @ 0x%x (%s)\n", address << 1, adapter->name); | 138 | v4l_info(client, "chip found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); |
149 | 139 | ||
150 | state = kzalloc(sizeof(struct vp27smpx_state), GFP_KERNEL); | 140 | state = kzalloc(sizeof(struct vp27smpx_state), GFP_KERNEL); |
151 | if (state == NULL) { | 141 | if (state == NULL) { |
152 | kfree(client); | ||
153 | return -ENOMEM; | 142 | return -ENOMEM; |
154 | } | 143 | } |
155 | state->audmode = V4L2_TUNER_MODE_STEREO; | 144 | state->audmode = V4L2_TUNER_MODE_STEREO; |
@@ -157,56 +146,22 @@ static int vp27smpx_attach(struct i2c_adapter *adapter, int address, int kind) | |||
157 | 146 | ||
158 | /* initialize vp27smpx */ | 147 | /* initialize vp27smpx */ |
159 | vp27smpx_set_audmode(client, state->audmode); | 148 | vp27smpx_set_audmode(client, state->audmode); |
160 | i2c_attach_client(client); | ||
161 | |||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static int vp27smpx_probe(struct i2c_adapter *adapter) | ||
166 | { | ||
167 | if (adapter->class & I2C_CLASS_TV_ANALOG) | ||
168 | return i2c_probe(adapter, &addr_data, vp27smpx_attach); | ||
169 | return 0; | 149 | return 0; |
170 | } | 150 | } |
171 | 151 | ||
172 | static int vp27smpx_detach(struct i2c_client *client) | 152 | static int vp27smpx_remove(struct i2c_client *client) |
173 | { | 153 | { |
174 | struct vp27smpx_state *state = i2c_get_clientdata(client); | 154 | kfree(i2c_get_clientdata(client)); |
175 | int err; | ||
176 | |||
177 | err = i2c_detach_client(client); | ||
178 | if (err) { | ||
179 | return err; | ||
180 | } | ||
181 | kfree(state); | ||
182 | kfree(client); | ||
183 | |||
184 | return 0; | 155 | return 0; |
185 | } | 156 | } |
186 | 157 | ||
187 | /* ----------------------------------------------------------------------- */ | 158 | /* ----------------------------------------------------------------------- */ |
188 | 159 | ||
189 | /* i2c implementation */ | 160 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { |
190 | static struct i2c_driver i2c_driver = { | 161 | .name = "vp27smpx", |
191 | .driver = { | 162 | .driverid = I2C_DRIVERID_VP27SMPX, |
192 | .name = "vp27smpx", | 163 | .command = vp27smpx_command, |
193 | }, | 164 | .probe = vp27smpx_probe, |
194 | .id = I2C_DRIVERID_VP27SMPX, | 165 | .remove = vp27smpx_remove, |
195 | .attach_adapter = vp27smpx_probe, | ||
196 | .detach_client = vp27smpx_detach, | ||
197 | .command = vp27smpx_command, | ||
198 | }; | 166 | }; |
199 | 167 | ||
200 | |||
201 | static int __init vp27smpx_init_module(void) | ||
202 | { | ||
203 | return i2c_add_driver(&i2c_driver); | ||
204 | } | ||
205 | |||
206 | static void __exit vp27smpx_cleanup_module(void) | ||
207 | { | ||
208 | i2c_del_driver(&i2c_driver); | ||
209 | } | ||
210 | |||
211 | module_init(vp27smpx_init_module); | ||
212 | module_exit(vp27smpx_cleanup_module); | ||