diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2009-02-19 06:54:36 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 11:42:57 -0400 |
commit | a91f56e7ebe8f33861c613f03faee0b354bea6c1 (patch) | |
tree | db2b8baa9a78a5190b8bcfb28d7ca95c398a80f5 /drivers/media/video/bt856.c | |
parent | 2883913c5e06a04d04eeeae9ad7ff9b737559355 (diff) |
V4L/DVB (10721): bt856: convert 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/bt856.c')
-rw-r--r-- | drivers/media/video/bt856.c | 243 |
1 files changed, 136 insertions, 107 deletions
diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c index 3e042c5ddaa7..182da6ab3845 100644 --- a/drivers/media/video/bt856.c +++ b/drivers/media/video/bt856.c | |||
@@ -34,9 +34,9 @@ | |||
34 | #include <asm/uaccess.h> | 34 | #include <asm/uaccess.h> |
35 | #include <linux/i2c.h> | 35 | #include <linux/i2c.h> |
36 | #include <linux/i2c-id.h> | 36 | #include <linux/i2c-id.h> |
37 | #include <linux/videodev.h> | 37 | #include <linux/videodev2.h> |
38 | #include <linux/video_encoder.h> | 38 | #include <media/v4l2-device.h> |
39 | #include <media/v4l2-common.h> | 39 | #include <media/v4l2-chip-ident.h> |
40 | #include <media/v4l2-i2c-drv-legacy.h> | 40 | #include <media/v4l2-i2c-drv-legacy.h> |
41 | 41 | ||
42 | MODULE_DESCRIPTION("Brooktree-856A video encoder driver"); | 42 | MODULE_DESCRIPTION("Brooktree-856A video encoder driver"); |
@@ -47,42 +47,49 @@ static int debug; | |||
47 | module_param(debug, int, 0); | 47 | module_param(debug, int, 0); |
48 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 48 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
49 | 49 | ||
50 | static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; | ||
51 | |||
52 | I2C_CLIENT_INSMOD; | ||
53 | |||
50 | /* ----------------------------------------------------------------------- */ | 54 | /* ----------------------------------------------------------------------- */ |
51 | 55 | ||
52 | #define BT856_REG_OFFSET 0xDA | 56 | #define BT856_REG_OFFSET 0xDA |
53 | #define BT856_NR_REG 6 | 57 | #define BT856_NR_REG 6 |
54 | 58 | ||
55 | struct bt856 { | 59 | struct bt856 { |
60 | struct v4l2_subdev sd; | ||
56 | unsigned char reg[BT856_NR_REG]; | 61 | unsigned char reg[BT856_NR_REG]; |
57 | 62 | ||
58 | v4l2_std_id norm; | 63 | v4l2_std_id norm; |
59 | }; | 64 | }; |
60 | 65 | ||
66 | static inline struct bt856 *to_bt856(struct v4l2_subdev *sd) | ||
67 | { | ||
68 | return container_of(sd, struct bt856, sd); | ||
69 | } | ||
70 | |||
61 | /* ----------------------------------------------------------------------- */ | 71 | /* ----------------------------------------------------------------------- */ |
62 | 72 | ||
63 | static inline int bt856_write(struct i2c_client *client, u8 reg, u8 value) | 73 | static inline int bt856_write(struct bt856 *encoder, u8 reg, u8 value) |
64 | { | 74 | { |
65 | struct bt856 *encoder = i2c_get_clientdata(client); | 75 | struct i2c_client *client = v4l2_get_subdevdata(&encoder->sd); |
66 | 76 | ||
67 | encoder->reg[reg - BT856_REG_OFFSET] = value; | 77 | encoder->reg[reg - BT856_REG_OFFSET] = value; |
68 | return i2c_smbus_write_byte_data(client, reg, value); | 78 | return i2c_smbus_write_byte_data(client, reg, value); |
69 | } | 79 | } |
70 | 80 | ||
71 | static inline int bt856_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value) | 81 | static inline int bt856_setbit(struct bt856 *encoder, u8 reg, u8 bit, u8 value) |
72 | { | 82 | { |
73 | struct bt856 *encoder = i2c_get_clientdata(client); | 83 | return bt856_write(encoder, reg, |
74 | |||
75 | return bt856_write(client, reg, | ||
76 | (encoder->reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) | | 84 | (encoder->reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) | |
77 | (value ? (1 << bit) : 0)); | 85 | (value ? (1 << bit) : 0)); |
78 | } | 86 | } |
79 | 87 | ||
80 | static void bt856_dump(struct i2c_client *client) | 88 | static void bt856_dump(struct bt856 *encoder) |
81 | { | 89 | { |
82 | int i; | 90 | int i; |
83 | struct bt856 *encoder = i2c_get_clientdata(client); | ||
84 | 91 | ||
85 | v4l_info(client, "register dump:\n"); | 92 | v4l2_info(&encoder->sd, "register dump:\n"); |
86 | for (i = 0; i < BT856_NR_REG; i += 2) | 93 | for (i = 0; i < BT856_NR_REG; i += 2) |
87 | printk(KERN_CONT " %02x", encoder->reg[i]); | 94 | printk(KERN_CONT " %02x", encoder->reg[i]); |
88 | printk(KERN_CONT "\n"); | 95 | printk(KERN_CONT "\n"); |
@@ -90,107 +97,125 @@ static void bt856_dump(struct i2c_client *client) | |||
90 | 97 | ||
91 | /* ----------------------------------------------------------------------- */ | 98 | /* ----------------------------------------------------------------------- */ |
92 | 99 | ||
93 | static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg) | 100 | static int bt856_init(struct v4l2_subdev *sd, u32 arg) |
94 | { | 101 | { |
95 | struct bt856 *encoder = i2c_get_clientdata(client); | 102 | struct bt856 *encoder = to_bt856(sd); |
96 | |||
97 | switch (cmd) { | ||
98 | case VIDIOC_INT_INIT: | ||
99 | /* This is just for testing!!! */ | ||
100 | v4l_dbg(1, debug, client, "init\n"); | ||
101 | bt856_write(client, 0xdc, 0x18); | ||
102 | bt856_write(client, 0xda, 0); | ||
103 | bt856_write(client, 0xde, 0); | ||
104 | |||
105 | bt856_setbit(client, 0xdc, 3, 1); | ||
106 | //bt856_setbit(client, 0xdc, 6, 0); | ||
107 | bt856_setbit(client, 0xdc, 4, 1); | ||
108 | |||
109 | if (encoder->norm & V4L2_STD_NTSC) | ||
110 | bt856_setbit(client, 0xdc, 2, 0); | ||
111 | else | ||
112 | bt856_setbit(client, 0xdc, 2, 1); | ||
113 | |||
114 | bt856_setbit(client, 0xdc, 1, 1); | ||
115 | bt856_setbit(client, 0xde, 4, 0); | ||
116 | bt856_setbit(client, 0xde, 3, 1); | ||
117 | if (debug != 0) | ||
118 | bt856_dump(client); | ||
119 | break; | ||
120 | 103 | ||
121 | case VIDIOC_INT_S_STD_OUTPUT: | 104 | /* This is just for testing!!! */ |
122 | { | 105 | v4l2_dbg(1, debug, sd, "init\n"); |
123 | v4l2_std_id *iarg = arg; | 106 | bt856_write(encoder, 0xdc, 0x18); |
124 | 107 | bt856_write(encoder, 0xda, 0); | |
125 | v4l_dbg(1, debug, client, "set norm %llx\n", *iarg); | 108 | bt856_write(encoder, 0xde, 0); |
126 | |||
127 | if (*iarg & V4L2_STD_NTSC) { | ||
128 | bt856_setbit(client, 0xdc, 2, 0); | ||
129 | } else if (*iarg & V4L2_STD_PAL) { | ||
130 | bt856_setbit(client, 0xdc, 2, 1); | ||
131 | bt856_setbit(client, 0xda, 0, 0); | ||
132 | //bt856_setbit(client, 0xda, 0, 1); | ||
133 | } else { | ||
134 | return -EINVAL; | ||
135 | } | ||
136 | encoder->norm = *iarg; | ||
137 | if (debug != 0) | ||
138 | bt856_dump(client); | ||
139 | break; | ||
140 | } | ||
141 | 109 | ||
142 | case VIDIOC_INT_S_VIDEO_ROUTING: | 110 | bt856_setbit(encoder, 0xdc, 3, 1); |
143 | { | 111 | /*bt856_setbit(encoder, 0xdc, 6, 0);*/ |
144 | struct v4l2_routing *route = arg; | 112 | bt856_setbit(encoder, 0xdc, 4, 1); |
145 | 113 | ||
146 | v4l_dbg(1, debug, client, "set input %d\n", route->input); | 114 | if (encoder->norm & V4L2_STD_NTSC) |
147 | 115 | bt856_setbit(encoder, 0xdc, 2, 0); | |
148 | /* We only have video bus. | 116 | else |
149 | * route->input= 0: input is from bt819 | 117 | bt856_setbit(encoder, 0xdc, 2, 1); |
150 | * route->input= 1: input is from ZR36060 */ | 118 | |
151 | switch (route->input) { | 119 | bt856_setbit(encoder, 0xdc, 1, 1); |
152 | case 0: | 120 | bt856_setbit(encoder, 0xde, 4, 0); |
153 | bt856_setbit(client, 0xde, 4, 0); | 121 | bt856_setbit(encoder, 0xde, 3, 1); |
154 | bt856_setbit(client, 0xde, 3, 1); | 122 | if (debug != 0) |
155 | bt856_setbit(client, 0xdc, 3, 1); | 123 | bt856_dump(encoder); |
156 | bt856_setbit(client, 0xdc, 6, 0); | 124 | return 0; |
157 | break; | 125 | } |
158 | case 1: | 126 | |
159 | bt856_setbit(client, 0xde, 4, 0); | 127 | static int bt856_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std) |
160 | bt856_setbit(client, 0xde, 3, 1); | 128 | { |
161 | bt856_setbit(client, 0xdc, 3, 1); | 129 | struct bt856 *encoder = to_bt856(sd); |
162 | bt856_setbit(client, 0xdc, 6, 1); | 130 | |
163 | break; | 131 | v4l2_dbg(1, debug, sd, "set norm %llx\n", std); |
164 | case 2: // Color bar | 132 | |
165 | bt856_setbit(client, 0xdc, 3, 0); | 133 | if (std & V4L2_STD_NTSC) { |
166 | bt856_setbit(client, 0xde, 4, 1); | 134 | bt856_setbit(encoder, 0xdc, 2, 0); |
167 | break; | 135 | } else if (std & V4L2_STD_PAL) { |
168 | default: | 136 | bt856_setbit(encoder, 0xdc, 2, 1); |
169 | return -EINVAL; | 137 | bt856_setbit(encoder, 0xda, 0, 0); |
170 | } | 138 | /*bt856_setbit(encoder, 0xda, 0, 1);*/ |
171 | 139 | } else { | |
172 | if (debug != 0) | 140 | return -EINVAL; |
173 | bt856_dump(client); | ||
174 | break; | ||
175 | } | 141 | } |
142 | encoder->norm = std; | ||
143 | if (debug != 0) | ||
144 | bt856_dump(encoder); | ||
145 | return 0; | ||
146 | } | ||
176 | 147 | ||
148 | static int bt856_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route) | ||
149 | { | ||
150 | struct bt856 *encoder = to_bt856(sd); | ||
151 | |||
152 | v4l2_dbg(1, debug, sd, "set input %d\n", route->input); | ||
153 | |||
154 | /* We only have video bus. | ||
155 | * route->input= 0: input is from bt819 | ||
156 | * route->input= 1: input is from ZR36060 */ | ||
157 | switch (route->input) { | ||
158 | case 0: | ||
159 | bt856_setbit(encoder, 0xde, 4, 0); | ||
160 | bt856_setbit(encoder, 0xde, 3, 1); | ||
161 | bt856_setbit(encoder, 0xdc, 3, 1); | ||
162 | bt856_setbit(encoder, 0xdc, 6, 0); | ||
163 | break; | ||
164 | case 1: | ||
165 | bt856_setbit(encoder, 0xde, 4, 0); | ||
166 | bt856_setbit(encoder, 0xde, 3, 1); | ||
167 | bt856_setbit(encoder, 0xdc, 3, 1); | ||
168 | bt856_setbit(encoder, 0xdc, 6, 1); | ||
169 | break; | ||
170 | case 2: /* Color bar */ | ||
171 | bt856_setbit(encoder, 0xdc, 3, 0); | ||
172 | bt856_setbit(encoder, 0xde, 4, 1); | ||
173 | break; | ||
177 | default: | 174 | default: |
178 | return -EINVAL; | 175 | return -EINVAL; |
179 | } | 176 | } |
180 | 177 | ||
178 | if (debug != 0) | ||
179 | bt856_dump(encoder); | ||
181 | return 0; | 180 | return 0; |
182 | } | 181 | } |
183 | 182 | ||
183 | static int bt856_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) | ||
184 | { | ||
185 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
186 | |||
187 | return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_BT856, 0); | ||
188 | } | ||
189 | |||
190 | static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg) | ||
191 | { | ||
192 | return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); | ||
193 | } | ||
194 | |||
184 | /* ----------------------------------------------------------------------- */ | 195 | /* ----------------------------------------------------------------------- */ |
185 | 196 | ||
186 | static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; | 197 | static const struct v4l2_subdev_core_ops bt856_core_ops = { |
198 | .g_chip_ident = bt856_g_chip_ident, | ||
199 | .init = bt856_init, | ||
200 | }; | ||
187 | 201 | ||
188 | I2C_CLIENT_INSMOD; | 202 | static const struct v4l2_subdev_video_ops bt856_video_ops = { |
203 | .s_std_output = bt856_s_std_output, | ||
204 | .s_routing = bt856_s_routing, | ||
205 | }; | ||
206 | |||
207 | static const struct v4l2_subdev_ops bt856_ops = { | ||
208 | .core = &bt856_core_ops, | ||
209 | .video = &bt856_video_ops, | ||
210 | }; | ||
211 | |||
212 | /* ----------------------------------------------------------------------- */ | ||
189 | 213 | ||
190 | static int bt856_probe(struct i2c_client *client, | 214 | static int bt856_probe(struct i2c_client *client, |
191 | const struct i2c_device_id *id) | 215 | const struct i2c_device_id *id) |
192 | { | 216 | { |
193 | struct bt856 *encoder; | 217 | struct bt856 *encoder; |
218 | struct v4l2_subdev *sd; | ||
194 | 219 | ||
195 | /* Check if the adapter supports the needed features */ | 220 | /* Check if the adapter supports the needed features */ |
196 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 221 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
@@ -202,34 +227,38 @@ static int bt856_probe(struct i2c_client *client, | |||
202 | encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL); | 227 | encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL); |
203 | if (encoder == NULL) | 228 | if (encoder == NULL) |
204 | return -ENOMEM; | 229 | return -ENOMEM; |
230 | sd = &encoder->sd; | ||
231 | v4l2_i2c_subdev_init(sd, client, &bt856_ops); | ||
205 | encoder->norm = V4L2_STD_NTSC; | 232 | encoder->norm = V4L2_STD_NTSC; |
206 | i2c_set_clientdata(client, encoder); | ||
207 | 233 | ||
208 | bt856_write(client, 0xdc, 0x18); | 234 | bt856_write(encoder, 0xdc, 0x18); |
209 | bt856_write(client, 0xda, 0); | 235 | bt856_write(encoder, 0xda, 0); |
210 | bt856_write(client, 0xde, 0); | 236 | bt856_write(encoder, 0xde, 0); |
211 | 237 | ||
212 | bt856_setbit(client, 0xdc, 3, 1); | 238 | bt856_setbit(encoder, 0xdc, 3, 1); |
213 | //bt856_setbit(client, 0xdc, 6, 0); | 239 | /*bt856_setbit(encoder, 0xdc, 6, 0);*/ |
214 | bt856_setbit(client, 0xdc, 4, 1); | 240 | bt856_setbit(encoder, 0xdc, 4, 1); |
215 | 241 | ||
216 | if (encoder->norm & V4L2_STD_NTSC) | 242 | if (encoder->norm & V4L2_STD_NTSC) |
217 | bt856_setbit(client, 0xdc, 2, 0); | 243 | bt856_setbit(encoder, 0xdc, 2, 0); |
218 | else | 244 | else |
219 | bt856_setbit(client, 0xdc, 2, 1); | 245 | bt856_setbit(encoder, 0xdc, 2, 1); |
220 | 246 | ||
221 | bt856_setbit(client, 0xdc, 1, 1); | 247 | bt856_setbit(encoder, 0xdc, 1, 1); |
222 | bt856_setbit(client, 0xde, 4, 0); | 248 | bt856_setbit(encoder, 0xde, 4, 0); |
223 | bt856_setbit(client, 0xde, 3, 1); | 249 | bt856_setbit(encoder, 0xde, 3, 1); |
224 | 250 | ||
225 | if (debug != 0) | 251 | if (debug != 0) |
226 | bt856_dump(client); | 252 | bt856_dump(encoder); |
227 | return 0; | 253 | return 0; |
228 | } | 254 | } |
229 | 255 | ||
230 | static int bt856_remove(struct i2c_client *client) | 256 | static int bt856_remove(struct i2c_client *client) |
231 | { | 257 | { |
232 | kfree(i2c_get_clientdata(client)); | 258 | struct v4l2_subdev *sd = i2c_get_clientdata(client); |
259 | |||
260 | v4l2_device_unregister_subdev(sd); | ||
261 | kfree(to_bt856(sd)); | ||
233 | return 0; | 262 | return 0; |
234 | } | 263 | } |
235 | 264 | ||