diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2009-02-19 02:49:29 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 11:42:57 -0400 |
commit | 8e4e1d8054b037e867849162ba78cf9b153b0dcc (patch) | |
tree | e0232e6debf7df9438e699d436dd848b92d365fd | |
parent | 886fe23d1ce99e35f95449a004647d24508a3d63 (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>
-rw-r--r-- | drivers/media/video/bt866.c | 233 | ||||
-rw-r--r-- | include/media/v4l2-chip-ident.h | 3 |
2 files changed, 126 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 | ||
42 | MODULE_DESCRIPTION("Brooktree-866 video encoder driver"); | 42 | MODULE_DESCRIPTION("Brooktree-866 video encoder driver"); |
@@ -47,21 +47,25 @@ 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 | struct bt866 { | 56 | struct 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 | ||
62 | static int bt866_write(struct i2c_client *client, u8 subaddr, u8 data) | 61 | static 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 | |||
66 | static 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 | ||
91 | static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg) | 95 | static 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: | 105 | static 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 | |||
181 | static 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]; | 188 | static 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; | 195 | static const struct v4l2_subdev_core_ops bt866_core_ops = { |
194 | } | 196 | .g_chip_ident = bt866_g_chip_ident, |
197 | }; | ||
195 | 198 | ||
196 | static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; | 199 | static 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 | ||
198 | I2C_CLIENT_INSMOD; | 204 | static const struct v4l2_subdev_ops bt866_ops = { |
205 | .core = &bt866_core_ops, | ||
206 | .video = &bt866_video_ops, | ||
207 | }; | ||
199 | 208 | ||
200 | static int bt866_probe(struct i2c_client *client, | 209 | static 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 | ||
216 | static int bt866_remove(struct i2c_client *client) | 226 | static 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 | ||
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h index bbe2bb6a596a..cfb236e5a1cc 100644 --- a/include/media/v4l2-chip-ident.h +++ b/include/media/v4l2-chip-ident.h | |||
@@ -71,6 +71,9 @@ enum { | |||
71 | V4L2_IDENT_CX23416 = 416, | 71 | V4L2_IDENT_CX23416 = 416, |
72 | V4L2_IDENT_CX23418 = 418, | 72 | V4L2_IDENT_CX23418 = 418, |
73 | 73 | ||
74 | /* module bt866: just ident 866 */ | ||
75 | V4L2_IDENT_BT866 = 866, | ||
76 | |||
74 | /* module vp27smpx: just ident 2700 */ | 77 | /* module vp27smpx: just ident 2700 */ |
75 | V4L2_IDENT_VP27SMPX = 2700, | 78 | V4L2_IDENT_VP27SMPX = 2700, |
76 | 79 | ||