aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/bt856.c
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2009-02-19 06:54:36 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:42:57 -0400
commita91f56e7ebe8f33861c613f03faee0b354bea6c1 (patch)
treedb2b8baa9a78a5190b8bcfb28d7ca95c398a80f5 /drivers/media/video/bt856.c
parent2883913c5e06a04d04eeeae9ad7ff9b737559355 (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.c243
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
42MODULE_DESCRIPTION("Brooktree-856A video encoder driver"); 42MODULE_DESCRIPTION("Brooktree-856A video encoder driver");
@@ -47,42 +47,49 @@ static int debug;
47module_param(debug, int, 0); 47module_param(debug, int, 0);
48MODULE_PARM_DESC(debug, "Debug level (0-1)"); 48MODULE_PARM_DESC(debug, "Debug level (0-1)");
49 49
50static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
51
52I2C_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
55struct bt856 { 59struct 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
66static inline struct bt856 *to_bt856(struct v4l2_subdev *sd)
67{
68 return container_of(sd, struct bt856, sd);
69}
70
61/* ----------------------------------------------------------------------- */ 71/* ----------------------------------------------------------------------- */
62 72
63static inline int bt856_write(struct i2c_client *client, u8 reg, u8 value) 73static 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
71static inline int bt856_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value) 81static 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
80static void bt856_dump(struct i2c_client *client) 88static 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
93static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg) 100static 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); 127static 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
148static 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
183static 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
190static 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
186static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; 197static const struct v4l2_subdev_core_ops bt856_core_ops = {
198 .g_chip_ident = bt856_g_chip_ident,
199 .init = bt856_init,
200};
187 201
188I2C_CLIENT_INSMOD; 202static 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
207static const struct v4l2_subdev_ops bt856_ops = {
208 .core = &bt856_core_ops,
209 .video = &bt856_video_ops,
210};
211
212/* ----------------------------------------------------------------------- */
189 213
190static int bt856_probe(struct i2c_client *client, 214static 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
230static int bt856_remove(struct i2c_client *client) 256static 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