aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/bt866.c
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2009-02-19 02:49:29 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:42:57 -0400
commit8e4e1d8054b037e867849162ba78cf9b153b0dcc (patch)
treee0232e6debf7df9438e699d436dd848b92d365fd /drivers/media/video/bt866.c
parent886fe23d1ce99e35f95449a004647d24508a3d63 (diff)
V4L/DVB (10718): bt866: 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/bt866.c')
-rw-r--r--drivers/media/video/bt866.c233
1 files changed, 123 insertions, 110 deletions
diff --git a/drivers/media/video/bt866.c b/drivers/media/video/bt866.c
index 1df24c8776f3..18d383877ece 100644
--- a/drivers/media/video/bt866.c
+++ b/drivers/media/video/bt866.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-866 video encoder driver"); 42MODULE_DESCRIPTION("Brooktree-866 video encoder driver");
@@ -47,21 +47,25 @@ 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
52struct bt866 { 56struct bt866 {
57 struct v4l2_subdev sd;
53 u8 reg[256]; 58 u8 reg[256];
54
55 v4l2_std_id norm;
56 int bright;
57 int contrast;
58 int hue;
59 int sat;
60}; 59};
61 60
62static int bt866_write(struct i2c_client *client, u8 subaddr, u8 data) 61static inline struct bt866 *to_bt866(struct v4l2_subdev *sd)
63{ 62{
64 struct bt866 *encoder = i2c_get_clientdata(client); 63 return container_of(sd, struct bt866, sd);
64}
65
66static int bt866_write(struct bt866 *encoder, u8 subaddr, u8 data)
67{
68 struct i2c_client *client = v4l2_get_subdevdata(&encoder->sd);
65 u8 buffer[2]; 69 u8 buffer[2];
66 int err; 70 int err;
67 71
@@ -88,119 +92,125 @@ static int bt866_write(struct i2c_client *client, u8 subaddr, u8 data)
88 return 0; 92 return 0;
89} 93}
90 94
91static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg) 95static int bt866_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
92{ 96{
93 struct bt866 *encoder = i2c_get_clientdata(client); 97 v4l2_dbg(1, debug, sd, "set norm %llx\n", std);
94
95 switch (cmd) {
96 case VIDIOC_INT_S_STD_OUTPUT:
97 {
98 v4l2_std_id *iarg = arg;
99
100 v4l_dbg(1, debug, client, "set norm %llx\n", *iarg);
101 98
102 if (!(*iarg & (V4L2_STD_NTSC | V4L2_STD_PAL))) 99 /* Only PAL supported by this driver at the moment! */
103 return -EINVAL; 100 if (!(std & V4L2_STD_NTSC))
104 encoder->norm = *iarg; 101 return -EINVAL;
105 break; 102 return 0;
106 } 103}
107 104
108 case VIDIOC_INT_S_VIDEO_ROUTING: 105static int bt866_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
109 { 106{
110 struct v4l2_routing *route = arg; 107 static const __u8 init[] = {
111 static const __u8 init[] = { 108 0xc8, 0xcc, /* CRSCALE */
112 0xc8, 0xcc, /* CRSCALE */ 109 0xca, 0x91, /* CBSCALE */
113 0xca, 0x91, /* CBSCALE */ 110 0xcc, 0x24, /* YC16 | OSDNUM */
114 0xcc, 0x24, /* YC16 | OSDNUM */ 111 0xda, 0x00, /* */
115 0xda, 0x00, /* */ 112 0xdc, 0x24, /* SETMODE | PAL */
116 0xdc, 0x24, /* SETMODE | PAL */ 113 0xde, 0x02, /* EACTIVE */
117 0xde, 0x02, /* EACTIVE */ 114
118 115 /* overlay colors */
119 /* overlay colors */ 116 0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */
120 0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */ 117 0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */
121 0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */ 118 0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */
122 0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */ 119 0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */
123 0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */ 120 0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */
124 0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */ 121 0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */
125 0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */ 122 0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */
126 0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */ 123 0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */
127 0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */ 124
128 125 0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */
129 0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */ 126 0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */
130 0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */ 127 0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */
131 0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */ 128 0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */
132 0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */ 129 0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */
133 0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */ 130 0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */
134 0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */ 131 0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */
135 0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */ 132 0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */
136 0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */ 133 };
137 }; 134 struct bt866 *encoder = to_bt866(sd);
138 int i; 135 u8 val;
139 u8 val; 136 int i;
140 137
141 for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2) 138 for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2)
142 bt866_write(client, init[i], init[i+1]); 139 bt866_write(encoder, init[i], init[i+1]);
143 140
144 val = encoder->reg[0xdc]; 141 val = encoder->reg[0xdc];
145 142
146 if (route->input == 0) 143 if (route->input == 0)
147 val |= 0x40; /* CBSWAP */ 144 val |= 0x40; /* CBSWAP */
148 else 145 else
149 val &= ~0x40; /* !CBSWAP */ 146 val &= ~0x40; /* !CBSWAP */
150 147
151 bt866_write(client, 0xdc, val); 148 bt866_write(encoder, 0xdc, val);
152 149
153 val = encoder->reg[0xcc]; 150 val = encoder->reg[0xcc];
154 if (route->input == 2) 151 if (route->input == 2)
155 val |= 0x01; /* OSDBAR */ 152 val |= 0x01; /* OSDBAR */
156 else 153 else
157 val &= ~0x01; /* !OSDBAR */ 154 val &= ~0x01; /* !OSDBAR */
158 bt866_write(client, 0xcc, val); 155 bt866_write(encoder, 0xcc, val);
159 156
160 v4l_dbg(1, debug, client, "set input %d\n", route->input); 157 v4l2_dbg(1, debug, sd, "set input %d\n", route->input);
161 158
162 switch (route->input) { 159 switch (route->input) {
163 case 0: 160 case 0:
164 break; 161 case 1:
165 case 1: 162 case 2:
166 break;
167 default:
168 return -EINVAL;
169 }
170 break; 163 break;
164 default:
165 return -EINVAL;
171 } 166 }
167 return 0;
168}
172 169
173 case 4711: 170#if 0
174 { 171/* Code to setup square pixels, might be of some use in the future,
175 int *iarg = arg; 172 but is currently unused. */
176 __u8 val; 173 val = encoder->reg[0xdc];
174 if (*iarg)
175 val |= 1; /* SQUARE */
176 else
177 val &= ~1; /* !SQUARE */
178 bt866_write(client, 0xdc, val);
179#endif
180
181static int bt866_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
182{
183 struct i2c_client *client = v4l2_get_subdevdata(sd);
177 184
178 v4l_dbg(1, debug, client, "square %d\n", *iarg); 185 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_BT866, 0);
186}
179 187
180 val = encoder->reg[0xdc]; 188static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg)
181 if (*iarg) 189{
182 val |= 1; /* SQUARE */ 190 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
183 else 191}
184 val &= ~1; /* !SQUARE */
185 bt866_write(client, 0xdc, val);
186 break;
187 }
188 192
189 default: 193/* ----------------------------------------------------------------------- */
190 return -EINVAL;
191 }
192 194
193 return 0; 195static const struct v4l2_subdev_core_ops bt866_core_ops = {
194} 196 .g_chip_ident = bt866_g_chip_ident,
197};
195 198
196static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; 199static const struct v4l2_subdev_video_ops bt866_video_ops = {
200 .s_std_output = bt866_s_std_output,
201 .s_routing = bt866_s_routing,
202};
197 203
198I2C_CLIENT_INSMOD; 204static const struct v4l2_subdev_ops bt866_ops = {
205 .core = &bt866_core_ops,
206 .video = &bt866_video_ops,
207};
199 208
200static int bt866_probe(struct i2c_client *client, 209static int bt866_probe(struct i2c_client *client,
201 const struct i2c_device_id *id) 210 const struct i2c_device_id *id)
202{ 211{
203 struct bt866 *encoder; 212 struct bt866 *encoder;
213 struct v4l2_subdev *sd;
204 214
205 v4l_info(client, "chip found @ 0x%x (%s)\n", 215 v4l_info(client, "chip found @ 0x%x (%s)\n",
206 client->addr << 1, client->adapter->name); 216 client->addr << 1, client->adapter->name);
@@ -208,14 +218,17 @@ static int bt866_probe(struct i2c_client *client,
208 encoder = kzalloc(sizeof(*encoder), GFP_KERNEL); 218 encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
209 if (encoder == NULL) 219 if (encoder == NULL)
210 return -ENOMEM; 220 return -ENOMEM;
211 221 sd = &encoder->sd;
212 i2c_set_clientdata(client, encoder); 222 v4l2_i2c_subdev_init(sd, client, &bt866_ops);
213 return 0; 223 return 0;
214} 224}
215 225
216static int bt866_remove(struct i2c_client *client) 226static int bt866_remove(struct i2c_client *client)
217{ 227{
218 kfree(i2c_get_clientdata(client)); 228 struct v4l2_subdev *sd = i2c_get_clientdata(client);
229
230 v4l2_device_unregister_subdev(sd);
231 kfree(to_bt866(sd));
219 return 0; 232 return 0;
220} 233}
221 234