diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/tvp5150.c | 830 |
1 files changed, 387 insertions, 443 deletions
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c index e8f701a412ab..e8a4637350ec 100644 --- a/drivers/media/video/tvp5150.c +++ b/drivers/media/video/tvp5150.c | |||
@@ -9,8 +9,9 @@ | |||
9 | #include <linux/videodev2.h> | 9 | #include <linux/videodev2.h> |
10 | #include <linux/delay.h> | 10 | #include <linux/delay.h> |
11 | #include <linux/video_decoder.h> | 11 | #include <linux/video_decoder.h> |
12 | #include <media/v4l2-common.h> | 12 | #include <media/v4l2-device.h> |
13 | #include <media/tvp5150.h> | 13 | #include <media/tvp5150.h> |
14 | #include <media/v4l2-i2c-drv-legacy.h> | ||
14 | 15 | ||
15 | #include "tvp5150_reg.h" | 16 | #include "tvp5150_reg.h" |
16 | 17 | ||
@@ -29,21 +30,7 @@ I2C_CLIENT_INSMOD; | |||
29 | 30 | ||
30 | static int debug; | 31 | static int debug; |
31 | module_param(debug, int, 0); | 32 | module_param(debug, int, 0); |
32 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 33 | MODULE_PARM_DESC(debug, "Debug level (0-2)"); |
33 | |||
34 | #define tvp5150_err(fmt, arg...) do { \ | ||
35 | printk(KERN_ERR "%s %d-%04x: " fmt, c->driver->driver.name, \ | ||
36 | i2c_adapter_id(c->adapter), c->addr , ## arg); } while (0) | ||
37 | #define tvp5150_info(fmt, arg...) do { \ | ||
38 | printk(KERN_INFO "%s %d-%04x: " fmt, c->driver->driver.name, \ | ||
39 | i2c_adapter_id(c->adapter), c->addr , ## arg); } while (0) | ||
40 | #define tvp5150_dbg(num, fmt, arg...) \ | ||
41 | do { \ | ||
42 | if (debug >= num) \ | ||
43 | printk(KERN_DEBUG "%s debug %d-%04x: " fmt,\ | ||
44 | c->driver->driver.name, \ | ||
45 | i2c_adapter_id(c->adapter), \ | ||
46 | c->addr , ## arg); } while (0) | ||
47 | 34 | ||
48 | /* supported controls */ | 35 | /* supported controls */ |
49 | static struct v4l2_queryctrl tvp5150_qctrl[] = { | 36 | static struct v4l2_queryctrl tvp5150_qctrl[] = { |
@@ -87,7 +74,7 @@ static struct v4l2_queryctrl tvp5150_qctrl[] = { | |||
87 | }; | 74 | }; |
88 | 75 | ||
89 | struct tvp5150 { | 76 | struct tvp5150 { |
90 | struct i2c_client *client; | 77 | struct v4l2_subdev sd; |
91 | 78 | ||
92 | v4l2_std_id norm; /* Current set standard */ | 79 | v4l2_std_id norm; /* Current set standard */ |
93 | struct v4l2_routing route; | 80 | struct v4l2_routing route; |
@@ -98,49 +85,57 @@ struct tvp5150 { | |||
98 | int sat; | 85 | int sat; |
99 | }; | 86 | }; |
100 | 87 | ||
101 | static int tvp5150_read(struct i2c_client *c, unsigned char addr) | 88 | static inline struct tvp5150 *to_tvp5150(struct v4l2_subdev *sd) |
102 | { | 89 | { |
90 | return container_of(sd, struct tvp5150, sd); | ||
91 | } | ||
92 | |||
93 | static int tvp5150_read(struct v4l2_subdev *sd, unsigned char addr) | ||
94 | { | ||
95 | struct i2c_client *c = v4l2_get_subdevdata(sd); | ||
103 | unsigned char buffer[1]; | 96 | unsigned char buffer[1]; |
104 | int rc; | 97 | int rc; |
105 | 98 | ||
106 | buffer[0] = addr; | 99 | buffer[0] = addr; |
107 | if (1 != (rc = i2c_master_send(c, buffer, 1))) | 100 | if (1 != (rc = i2c_master_send(c, buffer, 1))) |
108 | tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 1)\n", rc); | 101 | v4l2_dbg(0, debug, sd, "i2c i/o error: rc == %d (should be 1)\n", rc); |
109 | 102 | ||
110 | msleep(10); | 103 | msleep(10); |
111 | 104 | ||
112 | if (1 != (rc = i2c_master_recv(c, buffer, 1))) | 105 | if (1 != (rc = i2c_master_recv(c, buffer, 1))) |
113 | tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 1)\n", rc); | 106 | v4l2_dbg(0, debug, sd, "i2c i/o error: rc == %d (should be 1)\n", rc); |
114 | 107 | ||
115 | tvp5150_dbg(2, "tvp5150: read 0x%02x = 0x%02x\n", addr, buffer[0]); | 108 | v4l2_dbg(2, debug, sd, "tvp5150: read 0x%02x = 0x%02x\n", addr, buffer[0]); |
116 | 109 | ||
117 | return (buffer[0]); | 110 | return (buffer[0]); |
118 | } | 111 | } |
119 | 112 | ||
120 | static inline void tvp5150_write(struct i2c_client *c, unsigned char addr, | 113 | static inline void tvp5150_write(struct v4l2_subdev *sd, unsigned char addr, |
121 | unsigned char value) | 114 | unsigned char value) |
122 | { | 115 | { |
116 | struct i2c_client *c = v4l2_get_subdevdata(sd); | ||
123 | unsigned char buffer[2]; | 117 | unsigned char buffer[2]; |
124 | int rc; | 118 | int rc; |
125 | 119 | ||
126 | buffer[0] = addr; | 120 | buffer[0] = addr; |
127 | buffer[1] = value; | 121 | buffer[1] = value; |
128 | tvp5150_dbg(2, "tvp5150: writing 0x%02x 0x%02x\n", buffer[0], buffer[1]); | 122 | v4l2_dbg(2, debug, sd, "tvp5150: writing 0x%02x 0x%02x\n", buffer[0], buffer[1]); |
129 | if (2 != (rc = i2c_master_send(c, buffer, 2))) | 123 | if (2 != (rc = i2c_master_send(c, buffer, 2))) |
130 | tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 2)\n", rc); | 124 | v4l2_dbg(0, debug, sd, "i2c i/o error: rc == %d (should be 2)\n", rc); |
131 | } | 125 | } |
132 | 126 | ||
133 | static void dump_reg_range(struct i2c_client *c, char *s, u8 init, const u8 end,int max_line) | 127 | static void dump_reg_range(struct v4l2_subdev *sd, char *s, u8 init, |
128 | const u8 end, int max_line) | ||
134 | { | 129 | { |
135 | int i=0; | 130 | int i = 0; |
136 | 131 | ||
137 | while (init!=(u8)(end+1)) { | 132 | while (init != (u8)(end + 1)) { |
138 | if ((i%max_line) == 0) { | 133 | if ((i % max_line) == 0) { |
139 | if (i>0) | 134 | if (i > 0) |
140 | printk("\n"); | 135 | printk("\n"); |
141 | printk("tvp5150: %s reg 0x%02x = ",s,init); | 136 | printk("tvp5150: %s reg 0x%02x = ", s, init); |
142 | } | 137 | } |
143 | printk("%02x ",tvp5150_read(c, init)); | 138 | printk("%02x ", tvp5150_read(sd, init)); |
144 | 139 | ||
145 | init++; | 140 | init++; |
146 | i++; | 141 | i++; |
@@ -148,147 +143,148 @@ static void dump_reg_range(struct i2c_client *c, char *s, u8 init, const u8 end, | |||
148 | printk("\n"); | 143 | printk("\n"); |
149 | } | 144 | } |
150 | 145 | ||
151 | static void dump_reg(struct i2c_client *c) | 146 | static int tvp5150_log_status(struct v4l2_subdev *sd) |
152 | { | 147 | { |
153 | printk("tvp5150: Video input source selection #1 = 0x%02x\n", | 148 | printk("tvp5150: Video input source selection #1 = 0x%02x\n", |
154 | tvp5150_read(c, TVP5150_VD_IN_SRC_SEL_1)); | 149 | tvp5150_read(sd, TVP5150_VD_IN_SRC_SEL_1)); |
155 | printk("tvp5150: Analog channel controls = 0x%02x\n", | 150 | printk("tvp5150: Analog channel controls = 0x%02x\n", |
156 | tvp5150_read(c, TVP5150_ANAL_CHL_CTL)); | 151 | tvp5150_read(sd, TVP5150_ANAL_CHL_CTL)); |
157 | printk("tvp5150: Operation mode controls = 0x%02x\n", | 152 | printk("tvp5150: Operation mode controls = 0x%02x\n", |
158 | tvp5150_read(c, TVP5150_OP_MODE_CTL)); | 153 | tvp5150_read(sd, TVP5150_OP_MODE_CTL)); |
159 | printk("tvp5150: Miscellaneous controls = 0x%02x\n", | 154 | printk("tvp5150: Miscellaneous controls = 0x%02x\n", |
160 | tvp5150_read(c, TVP5150_MISC_CTL)); | 155 | tvp5150_read(sd, TVP5150_MISC_CTL)); |
161 | printk("tvp5150: Autoswitch mask= 0x%02x\n", | 156 | printk("tvp5150: Autoswitch mask= 0x%02x\n", |
162 | tvp5150_read(c, TVP5150_AUTOSW_MSK)); | 157 | tvp5150_read(sd, TVP5150_AUTOSW_MSK)); |
163 | printk("tvp5150: Color killer threshold control = 0x%02x\n", | 158 | printk("tvp5150: Color killer threshold control = 0x%02x\n", |
164 | tvp5150_read(c, TVP5150_COLOR_KIL_THSH_CTL)); | 159 | tvp5150_read(sd, TVP5150_COLOR_KIL_THSH_CTL)); |
165 | printk("tvp5150: Luminance processing controls #1 #2 and #3 = %02x %02x %02x\n", | 160 | printk("tvp5150: Luminance processing controls #1 #2 and #3 = %02x %02x %02x\n", |
166 | tvp5150_read(c, TVP5150_LUMA_PROC_CTL_1), | 161 | tvp5150_read(sd, TVP5150_LUMA_PROC_CTL_1), |
167 | tvp5150_read(c, TVP5150_LUMA_PROC_CTL_2), | 162 | tvp5150_read(sd, TVP5150_LUMA_PROC_CTL_2), |
168 | tvp5150_read(c, TVP5150_LUMA_PROC_CTL_3)); | 163 | tvp5150_read(sd, TVP5150_LUMA_PROC_CTL_3)); |
169 | printk("tvp5150: Brightness control = 0x%02x\n", | 164 | printk("tvp5150: Brightness control = 0x%02x\n", |
170 | tvp5150_read(c, TVP5150_BRIGHT_CTL)); | 165 | tvp5150_read(sd, TVP5150_BRIGHT_CTL)); |
171 | printk("tvp5150: Color saturation control = 0x%02x\n", | 166 | printk("tvp5150: Color saturation control = 0x%02x\n", |
172 | tvp5150_read(c, TVP5150_SATURATION_CTL)); | 167 | tvp5150_read(sd, TVP5150_SATURATION_CTL)); |
173 | printk("tvp5150: Hue control = 0x%02x\n", | 168 | printk("tvp5150: Hue control = 0x%02x\n", |
174 | tvp5150_read(c, TVP5150_HUE_CTL)); | 169 | tvp5150_read(sd, TVP5150_HUE_CTL)); |
175 | printk("tvp5150: Contrast control = 0x%02x\n", | 170 | printk("tvp5150: Contrast control = 0x%02x\n", |
176 | tvp5150_read(c, TVP5150_CONTRAST_CTL)); | 171 | tvp5150_read(sd, TVP5150_CONTRAST_CTL)); |
177 | printk("tvp5150: Outputs and data rates select = 0x%02x\n", | 172 | printk("tvp5150: Outputs and data rates select = 0x%02x\n", |
178 | tvp5150_read(c, TVP5150_DATA_RATE_SEL)); | 173 | tvp5150_read(sd, TVP5150_DATA_RATE_SEL)); |
179 | printk("tvp5150: Configuration shared pins = 0x%02x\n", | 174 | printk("tvp5150: Configuration shared pins = 0x%02x\n", |
180 | tvp5150_read(c, TVP5150_CONF_SHARED_PIN)); | 175 | tvp5150_read(sd, TVP5150_CONF_SHARED_PIN)); |
181 | printk("tvp5150: Active video cropping start = 0x%02x%02x\n", | 176 | printk("tvp5150: Active video cropping start = 0x%02x%02x\n", |
182 | tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_MSB), | 177 | tvp5150_read(sd, TVP5150_ACT_VD_CROP_ST_MSB), |
183 | tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_LSB)); | 178 | tvp5150_read(sd, TVP5150_ACT_VD_CROP_ST_LSB)); |
184 | printk("tvp5150: Active video cropping stop = 0x%02x%02x\n", | 179 | printk("tvp5150: Active video cropping stop = 0x%02x%02x\n", |
185 | tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_MSB), | 180 | tvp5150_read(sd, TVP5150_ACT_VD_CROP_STP_MSB), |
186 | tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_LSB)); | 181 | tvp5150_read(sd, TVP5150_ACT_VD_CROP_STP_LSB)); |
187 | printk("tvp5150: Genlock/RTC = 0x%02x\n", | 182 | printk("tvp5150: Genlock/RTC = 0x%02x\n", |
188 | tvp5150_read(c, TVP5150_GENLOCK)); | 183 | tvp5150_read(sd, TVP5150_GENLOCK)); |
189 | printk("tvp5150: Horizontal sync start = 0x%02x\n", | 184 | printk("tvp5150: Horizontal sync start = 0x%02x\n", |
190 | tvp5150_read(c, TVP5150_HORIZ_SYNC_START)); | 185 | tvp5150_read(sd, TVP5150_HORIZ_SYNC_START)); |
191 | printk("tvp5150: Vertical blanking start = 0x%02x\n", | 186 | printk("tvp5150: Vertical blanking start = 0x%02x\n", |
192 | tvp5150_read(c, TVP5150_VERT_BLANKING_START)); | 187 | tvp5150_read(sd, TVP5150_VERT_BLANKING_START)); |
193 | printk("tvp5150: Vertical blanking stop = 0x%02x\n", | 188 | printk("tvp5150: Vertical blanking stop = 0x%02x\n", |
194 | tvp5150_read(c, TVP5150_VERT_BLANKING_STOP)); | 189 | tvp5150_read(sd, TVP5150_VERT_BLANKING_STOP)); |
195 | printk("tvp5150: Chrominance processing control #1 and #2 = %02x %02x\n", | 190 | printk("tvp5150: Chrominance processing control #1 and #2 = %02x %02x\n", |
196 | tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_1), | 191 | tvp5150_read(sd, TVP5150_CHROMA_PROC_CTL_1), |
197 | tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_2)); | 192 | tvp5150_read(sd, TVP5150_CHROMA_PROC_CTL_2)); |
198 | printk("tvp5150: Interrupt reset register B = 0x%02x\n", | 193 | printk("tvp5150: Interrupt reset register B = 0x%02x\n", |
199 | tvp5150_read(c, TVP5150_INT_RESET_REG_B)); | 194 | tvp5150_read(sd, TVP5150_INT_RESET_REG_B)); |
200 | printk("tvp5150: Interrupt enable register B = 0x%02x\n", | 195 | printk("tvp5150: Interrupt enable register B = 0x%02x\n", |
201 | tvp5150_read(c, TVP5150_INT_ENABLE_REG_B)); | 196 | tvp5150_read(sd, TVP5150_INT_ENABLE_REG_B)); |
202 | printk("tvp5150: Interrupt configuration register B = 0x%02x\n", | 197 | printk("tvp5150: Interrupt configuration register B = 0x%02x\n", |
203 | tvp5150_read(c, TVP5150_INTT_CONFIG_REG_B)); | 198 | tvp5150_read(sd, TVP5150_INTT_CONFIG_REG_B)); |
204 | printk("tvp5150: Video standard = 0x%02x\n", | 199 | printk("tvp5150: Video standard = 0x%02x\n", |
205 | tvp5150_read(c, TVP5150_VIDEO_STD)); | 200 | tvp5150_read(sd, TVP5150_VIDEO_STD)); |
206 | printk("tvp5150: Chroma gain factor: Cb=0x%02x Cr=0x%02x\n", | 201 | printk("tvp5150: Chroma gain factor: Cb=0x%02x Cr=0x%02x\n", |
207 | tvp5150_read(c, TVP5150_CB_GAIN_FACT), | 202 | tvp5150_read(sd, TVP5150_CB_GAIN_FACT), |
208 | tvp5150_read(c, TVP5150_CR_GAIN_FACTOR)); | 203 | tvp5150_read(sd, TVP5150_CR_GAIN_FACTOR)); |
209 | printk("tvp5150: Macrovision on counter = 0x%02x\n", | 204 | printk("tvp5150: Macrovision on counter = 0x%02x\n", |
210 | tvp5150_read(c, TVP5150_MACROVISION_ON_CTR)); | 205 | tvp5150_read(sd, TVP5150_MACROVISION_ON_CTR)); |
211 | printk("tvp5150: Macrovision off counter = 0x%02x\n", | 206 | printk("tvp5150: Macrovision off counter = 0x%02x\n", |
212 | tvp5150_read(c, TVP5150_MACROVISION_OFF_CTR)); | 207 | tvp5150_read(sd, TVP5150_MACROVISION_OFF_CTR)); |
213 | printk("tvp5150: ITU-R BT.656.%d timing(TVP5150AM1 only)\n", | 208 | printk("tvp5150: ITU-R BT.656.%d timing(TVP5150AM1 only)\n", |
214 | (tvp5150_read(c, TVP5150_REV_SELECT)&1)?3:4); | 209 | (tvp5150_read(sd, TVP5150_REV_SELECT) & 1) ? 3 : 4); |
215 | printk("tvp5150: Device ID = %02x%02x\n", | 210 | printk("tvp5150: Device ID = %02x%02x\n", |
216 | tvp5150_read(c, TVP5150_MSB_DEV_ID), | 211 | tvp5150_read(sd, TVP5150_MSB_DEV_ID), |
217 | tvp5150_read(c, TVP5150_LSB_DEV_ID)); | 212 | tvp5150_read(sd, TVP5150_LSB_DEV_ID)); |
218 | printk("tvp5150: ROM version = (hex) %02x.%02x\n", | 213 | printk("tvp5150: ROM version = (hex) %02x.%02x\n", |
219 | tvp5150_read(c, TVP5150_ROM_MAJOR_VER), | 214 | tvp5150_read(sd, TVP5150_ROM_MAJOR_VER), |
220 | tvp5150_read(c, TVP5150_ROM_MINOR_VER)); | 215 | tvp5150_read(sd, TVP5150_ROM_MINOR_VER)); |
221 | printk("tvp5150: Vertical line count = 0x%02x%02x\n", | 216 | printk("tvp5150: Vertical line count = 0x%02x%02x\n", |
222 | tvp5150_read(c, TVP5150_VERT_LN_COUNT_MSB), | 217 | tvp5150_read(sd, TVP5150_VERT_LN_COUNT_MSB), |
223 | tvp5150_read(c, TVP5150_VERT_LN_COUNT_LSB)); | 218 | tvp5150_read(sd, TVP5150_VERT_LN_COUNT_LSB)); |
224 | printk("tvp5150: Interrupt status register B = 0x%02x\n", | 219 | printk("tvp5150: Interrupt status register B = 0x%02x\n", |
225 | tvp5150_read(c, TVP5150_INT_STATUS_REG_B)); | 220 | tvp5150_read(sd, TVP5150_INT_STATUS_REG_B)); |
226 | printk("tvp5150: Interrupt active register B = 0x%02x\n", | 221 | printk("tvp5150: Interrupt active register B = 0x%02x\n", |
227 | tvp5150_read(c, TVP5150_INT_ACTIVE_REG_B)); | 222 | tvp5150_read(sd, TVP5150_INT_ACTIVE_REG_B)); |
228 | printk("tvp5150: Status regs #1 to #5 = %02x %02x %02x %02x %02x\n", | 223 | printk("tvp5150: Status regs #1 to #5 = %02x %02x %02x %02x %02x\n", |
229 | tvp5150_read(c, TVP5150_STATUS_REG_1), | 224 | tvp5150_read(sd, TVP5150_STATUS_REG_1), |
230 | tvp5150_read(c, TVP5150_STATUS_REG_2), | 225 | tvp5150_read(sd, TVP5150_STATUS_REG_2), |
231 | tvp5150_read(c, TVP5150_STATUS_REG_3), | 226 | tvp5150_read(sd, TVP5150_STATUS_REG_3), |
232 | tvp5150_read(c, TVP5150_STATUS_REG_4), | 227 | tvp5150_read(sd, TVP5150_STATUS_REG_4), |
233 | tvp5150_read(c, TVP5150_STATUS_REG_5)); | 228 | tvp5150_read(sd, TVP5150_STATUS_REG_5)); |
234 | 229 | ||
235 | dump_reg_range(c,"Teletext filter 1", TVP5150_TELETEXT_FIL1_INI, | 230 | dump_reg_range(sd, "Teletext filter 1", TVP5150_TELETEXT_FIL1_INI, |
236 | TVP5150_TELETEXT_FIL1_END,8); | 231 | TVP5150_TELETEXT_FIL1_END, 8); |
237 | dump_reg_range(c,"Teletext filter 2", TVP5150_TELETEXT_FIL2_INI, | 232 | dump_reg_range(sd, "Teletext filter 2", TVP5150_TELETEXT_FIL2_INI, |
238 | TVP5150_TELETEXT_FIL2_END,8); | 233 | TVP5150_TELETEXT_FIL2_END, 8); |
239 | 234 | ||
240 | printk("tvp5150: Teletext filter enable = 0x%02x\n", | 235 | printk("tvp5150: Teletext filter enable = 0x%02x\n", |
241 | tvp5150_read(c, TVP5150_TELETEXT_FIL_ENA)); | 236 | tvp5150_read(sd, TVP5150_TELETEXT_FIL_ENA)); |
242 | printk("tvp5150: Interrupt status register A = 0x%02x\n", | 237 | printk("tvp5150: Interrupt status register A = 0x%02x\n", |
243 | tvp5150_read(c, TVP5150_INT_STATUS_REG_A)); | 238 | tvp5150_read(sd, TVP5150_INT_STATUS_REG_A)); |
244 | printk("tvp5150: Interrupt enable register A = 0x%02x\n", | 239 | printk("tvp5150: Interrupt enable register A = 0x%02x\n", |
245 | tvp5150_read(c, TVP5150_INT_ENABLE_REG_A)); | 240 | tvp5150_read(sd, TVP5150_INT_ENABLE_REG_A)); |
246 | printk("tvp5150: Interrupt configuration = 0x%02x\n", | 241 | printk("tvp5150: Interrupt configuration = 0x%02x\n", |
247 | tvp5150_read(c, TVP5150_INT_CONF)); | 242 | tvp5150_read(sd, TVP5150_INT_CONF)); |
248 | printk("tvp5150: VDP status register = 0x%02x\n", | 243 | printk("tvp5150: VDP status register = 0x%02x\n", |
249 | tvp5150_read(c, TVP5150_VDP_STATUS_REG)); | 244 | tvp5150_read(sd, TVP5150_VDP_STATUS_REG)); |
250 | printk("tvp5150: FIFO word count = 0x%02x\n", | 245 | printk("tvp5150: FIFO word count = 0x%02x\n", |
251 | tvp5150_read(c, TVP5150_FIFO_WORD_COUNT)); | 246 | tvp5150_read(sd, TVP5150_FIFO_WORD_COUNT)); |
252 | printk("tvp5150: FIFO interrupt threshold = 0x%02x\n", | 247 | printk("tvp5150: FIFO interrupt threshold = 0x%02x\n", |
253 | tvp5150_read(c, TVP5150_FIFO_INT_THRESHOLD)); | 248 | tvp5150_read(sd, TVP5150_FIFO_INT_THRESHOLD)); |
254 | printk("tvp5150: FIFO reset = 0x%02x\n", | 249 | printk("tvp5150: FIFO reset = 0x%02x\n", |
255 | tvp5150_read(c, TVP5150_FIFO_RESET)); | 250 | tvp5150_read(sd, TVP5150_FIFO_RESET)); |
256 | printk("tvp5150: Line number interrupt = 0x%02x\n", | 251 | printk("tvp5150: Line number interrupt = 0x%02x\n", |
257 | tvp5150_read(c, TVP5150_LINE_NUMBER_INT)); | 252 | tvp5150_read(sd, TVP5150_LINE_NUMBER_INT)); |
258 | printk("tvp5150: Pixel alignment register = 0x%02x%02x\n", | 253 | printk("tvp5150: Pixel alignment register = 0x%02x%02x\n", |
259 | tvp5150_read(c, TVP5150_PIX_ALIGN_REG_HIGH), | 254 | tvp5150_read(sd, TVP5150_PIX_ALIGN_REG_HIGH), |
260 | tvp5150_read(c, TVP5150_PIX_ALIGN_REG_LOW)); | 255 | tvp5150_read(sd, TVP5150_PIX_ALIGN_REG_LOW)); |
261 | printk("tvp5150: FIFO output control = 0x%02x\n", | 256 | printk("tvp5150: FIFO output control = 0x%02x\n", |
262 | tvp5150_read(c, TVP5150_FIFO_OUT_CTRL)); | 257 | tvp5150_read(sd, TVP5150_FIFO_OUT_CTRL)); |
263 | printk("tvp5150: Full field enable = 0x%02x\n", | 258 | printk("tvp5150: Full field enable = 0x%02x\n", |
264 | tvp5150_read(c, TVP5150_FULL_FIELD_ENA)); | 259 | tvp5150_read(sd, TVP5150_FULL_FIELD_ENA)); |
265 | printk("tvp5150: Full field mode register = 0x%02x\n", | 260 | printk("tvp5150: Full field mode register = 0x%02x\n", |
266 | tvp5150_read(c, TVP5150_FULL_FIELD_MODE_REG)); | 261 | tvp5150_read(sd, TVP5150_FULL_FIELD_MODE_REG)); |
267 | 262 | ||
268 | dump_reg_range(c,"CC data", TVP5150_CC_DATA_INI, | 263 | dump_reg_range(sd, "CC data", TVP5150_CC_DATA_INI, |
269 | TVP5150_CC_DATA_END,8); | 264 | TVP5150_CC_DATA_END, 8); |
270 | 265 | ||
271 | dump_reg_range(c,"WSS data", TVP5150_WSS_DATA_INI, | 266 | dump_reg_range(sd, "WSS data", TVP5150_WSS_DATA_INI, |
272 | TVP5150_WSS_DATA_END,8); | 267 | TVP5150_WSS_DATA_END, 8); |
273 | 268 | ||
274 | dump_reg_range(c,"VPS data", TVP5150_VPS_DATA_INI, | 269 | dump_reg_range(sd, "VPS data", TVP5150_VPS_DATA_INI, |
275 | TVP5150_VPS_DATA_END,8); | 270 | TVP5150_VPS_DATA_END, 8); |
276 | 271 | ||
277 | dump_reg_range(c,"VITC data", TVP5150_VITC_DATA_INI, | 272 | dump_reg_range(sd, "VITC data", TVP5150_VITC_DATA_INI, |
278 | TVP5150_VITC_DATA_END,10); | 273 | TVP5150_VITC_DATA_END, 10); |
279 | 274 | ||
280 | dump_reg_range(c,"Line mode", TVP5150_LINE_MODE_INI, | 275 | dump_reg_range(sd, "Line mode", TVP5150_LINE_MODE_INI, |
281 | TVP5150_LINE_MODE_END,8); | 276 | TVP5150_LINE_MODE_END, 8); |
277 | return 0; | ||
282 | } | 278 | } |
283 | 279 | ||
284 | /**************************************************************************** | 280 | /**************************************************************************** |
285 | Basic functions | 281 | Basic functions |
286 | ****************************************************************************/ | 282 | ****************************************************************************/ |
287 | 283 | ||
288 | static inline void tvp5150_selmux(struct i2c_client *c) | 284 | static inline void tvp5150_selmux(struct v4l2_subdev *sd) |
289 | { | 285 | { |
290 | int opmode=0; | 286 | int opmode=0; |
291 | struct tvp5150 *decoder = i2c_get_clientdata(c); | 287 | struct tvp5150 *decoder = to_tvp5150(sd); |
292 | int input = 0; | 288 | int input = 0; |
293 | unsigned char val; | 289 | unsigned char val; |
294 | 290 | ||
@@ -309,23 +305,23 @@ static inline void tvp5150_selmux(struct i2c_client *c) | |||
309 | break; | 305 | break; |
310 | } | 306 | } |
311 | 307 | ||
312 | tvp5150_dbg( 1, "Selecting video route: route input=%i, output=%i " | 308 | v4l2_dbg(1, debug, sd, "Selecting video route: route input=%i, output=%i " |
313 | "=> tvp5150 input=%i, opmode=%i\n", | 309 | "=> tvp5150 input=%i, opmode=%i\n", |
314 | decoder->route.input,decoder->route.output, | 310 | decoder->route.input,decoder->route.output, |
315 | input, opmode ); | 311 | input, opmode ); |
316 | 312 | ||
317 | tvp5150_write(c, TVP5150_OP_MODE_CTL, opmode); | 313 | tvp5150_write(sd, TVP5150_OP_MODE_CTL, opmode); |
318 | tvp5150_write(c, TVP5150_VD_IN_SRC_SEL_1, input); | 314 | tvp5150_write(sd, TVP5150_VD_IN_SRC_SEL_1, input); |
319 | 315 | ||
320 | /* Svideo should enable YCrCb output and disable GPCL output | 316 | /* Svideo should enable YCrCb output and disable GPCL output |
321 | * For Composite and TV, it should be the reverse | 317 | * For Composite and TV, it should be the reverse |
322 | */ | 318 | */ |
323 | val = tvp5150_read(c, TVP5150_MISC_CTL); | 319 | val = tvp5150_read(sd, TVP5150_MISC_CTL); |
324 | if (decoder->route.input == TVP5150_SVIDEO) | 320 | if (decoder->route.input == TVP5150_SVIDEO) |
325 | val = (val & ~0x40) | 0x10; | 321 | val = (val & ~0x40) | 0x10; |
326 | else | 322 | else |
327 | val = (val & ~0x10) | 0x40; | 323 | val = (val & ~0x10) | 0x40; |
328 | tvp5150_write(c, TVP5150_MISC_CTL, val); | 324 | tvp5150_write(sd, TVP5150_MISC_CTL, val); |
329 | }; | 325 | }; |
330 | 326 | ||
331 | struct i2c_reg_value { | 327 | struct i2c_reg_value { |
@@ -593,35 +589,35 @@ static struct i2c_vbi_ram_value vbi_ram_default[] = | |||
593 | { (u16)-1 } | 589 | { (u16)-1 } |
594 | }; | 590 | }; |
595 | 591 | ||
596 | static int tvp5150_write_inittab(struct i2c_client *c, | 592 | static int tvp5150_write_inittab(struct v4l2_subdev *sd, |
597 | const struct i2c_reg_value *regs) | 593 | const struct i2c_reg_value *regs) |
598 | { | 594 | { |
599 | while (regs->reg != 0xff) { | 595 | while (regs->reg != 0xff) { |
600 | tvp5150_write(c, regs->reg, regs->value); | 596 | tvp5150_write(sd, regs->reg, regs->value); |
601 | regs++; | 597 | regs++; |
602 | } | 598 | } |
603 | return 0; | 599 | return 0; |
604 | } | 600 | } |
605 | 601 | ||
606 | static int tvp5150_vdp_init(struct i2c_client *c, | 602 | static int tvp5150_vdp_init(struct v4l2_subdev *sd, |
607 | const struct i2c_vbi_ram_value *regs) | 603 | const struct i2c_vbi_ram_value *regs) |
608 | { | 604 | { |
609 | unsigned int i; | 605 | unsigned int i; |
610 | 606 | ||
611 | /* Disable Full Field */ | 607 | /* Disable Full Field */ |
612 | tvp5150_write(c, TVP5150_FULL_FIELD_ENA, 0); | 608 | tvp5150_write(sd, TVP5150_FULL_FIELD_ENA, 0); |
613 | 609 | ||
614 | /* Before programming, Line mode should be at 0xff */ | 610 | /* Before programming, Line mode should be at 0xff */ |
615 | for (i=TVP5150_LINE_MODE_INI; i<=TVP5150_LINE_MODE_END; i++) | 611 | for (i = TVP5150_LINE_MODE_INI; i <= TVP5150_LINE_MODE_END; i++) |
616 | tvp5150_write(c, i, 0xff); | 612 | tvp5150_write(sd, i, 0xff); |
617 | 613 | ||
618 | /* Load Ram Table */ | 614 | /* Load Ram Table */ |
619 | while (regs->reg != (u16)-1 ) { | 615 | while (regs->reg != (u16)-1) { |
620 | tvp5150_write(c, TVP5150_CONF_RAM_ADDR_HIGH,regs->reg>>8); | 616 | tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_HIGH, regs->reg >> 8); |
621 | tvp5150_write(c, TVP5150_CONF_RAM_ADDR_LOW,regs->reg); | 617 | tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_LOW, regs->reg); |
622 | 618 | ||
623 | for (i=0;i<16;i++) | 619 | for (i = 0; i < 16; i++) |
624 | tvp5150_write(c, TVP5150_VDP_CONF_RAM_DATA,regs->values[i]); | 620 | tvp5150_write(sd, TVP5150_VDP_CONF_RAM_DATA, regs->values[i]); |
625 | 621 | ||
626 | regs++; | 622 | regs++; |
627 | } | 623 | } |
@@ -629,11 +625,13 @@ static int tvp5150_vdp_init(struct i2c_client *c, | |||
629 | } | 625 | } |
630 | 626 | ||
631 | /* Fills VBI capabilities based on i2c_vbi_ram_value struct */ | 627 | /* Fills VBI capabilities based on i2c_vbi_ram_value struct */ |
632 | static void tvp5150_vbi_get_cap(const struct i2c_vbi_ram_value *regs, | 628 | static int tvp5150_g_sliced_vbi_cap(struct v4l2_subdev *sd, |
633 | struct v4l2_sliced_vbi_cap *cap) | 629 | struct v4l2_sliced_vbi_cap *cap) |
634 | { | 630 | { |
631 | const struct i2c_vbi_ram_value *regs = vbi_ram_default; | ||
635 | int line; | 632 | int line; |
636 | 633 | ||
634 | v4l2_dbg(1, debug, sd, "VIDIOC_G_SLICED_VBI_CAP\n"); | ||
637 | memset(cap, 0, sizeof *cap); | 635 | memset(cap, 0, sizeof *cap); |
638 | 636 | ||
639 | while (regs->reg != (u16)-1 ) { | 637 | while (regs->reg != (u16)-1 ) { |
@@ -644,6 +642,7 @@ static void tvp5150_vbi_get_cap(const struct i2c_vbi_ram_value *regs, | |||
644 | 642 | ||
645 | regs++; | 643 | regs++; |
646 | } | 644 | } |
645 | return 0; | ||
647 | } | 646 | } |
648 | 647 | ||
649 | /* Set vbi processing | 648 | /* Set vbi processing |
@@ -659,18 +658,18 @@ static void tvp5150_vbi_get_cap(const struct i2c_vbi_ram_value *regs, | |||
659 | * LSB = field1 | 658 | * LSB = field1 |
660 | * MSB = field2 | 659 | * MSB = field2 |
661 | */ | 660 | */ |
662 | static int tvp5150_set_vbi(struct i2c_client *c, | 661 | static int tvp5150_set_vbi(struct v4l2_subdev *sd, |
663 | const struct i2c_vbi_ram_value *regs, | 662 | const struct i2c_vbi_ram_value *regs, |
664 | unsigned int type,u8 flags, int line, | 663 | unsigned int type,u8 flags, int line, |
665 | const int fields) | 664 | const int fields) |
666 | { | 665 | { |
667 | struct tvp5150 *decoder = i2c_get_clientdata(c); | 666 | struct tvp5150 *decoder = to_tvp5150(sd); |
668 | v4l2_std_id std=decoder->norm; | 667 | v4l2_std_id std = decoder->norm; |
669 | u8 reg; | 668 | u8 reg; |
670 | int pos=0; | 669 | int pos=0; |
671 | 670 | ||
672 | if (std == V4L2_STD_ALL) { | 671 | if (std == V4L2_STD_ALL) { |
673 | tvp5150_err("VBI can't be configured without knowing number of lines\n"); | 672 | v4l2_err(sd, "VBI can't be configured without knowing number of lines\n"); |
674 | return 0; | 673 | return 0; |
675 | } else if (std & V4L2_STD_625_50) { | 674 | } else if (std & V4L2_STD_625_50) { |
676 | /* Don't follow NTSC Line number convension */ | 675 | /* Don't follow NTSC Line number convension */ |
@@ -698,163 +697,186 @@ static int tvp5150_set_vbi(struct i2c_client *c, | |||
698 | reg=((line-6)<<1)+TVP5150_LINE_MODE_INI; | 697 | reg=((line-6)<<1)+TVP5150_LINE_MODE_INI; |
699 | 698 | ||
700 | if (fields&1) { | 699 | if (fields&1) { |
701 | tvp5150_write(c, reg, type); | 700 | tvp5150_write(sd, reg, type); |
702 | } | 701 | } |
703 | 702 | ||
704 | if (fields&2) { | 703 | if (fields&2) { |
705 | tvp5150_write(c, reg+1, type); | 704 | tvp5150_write(sd, reg+1, type); |
706 | } | 705 | } |
707 | 706 | ||
708 | return type; | 707 | return type; |
709 | } | 708 | } |
710 | 709 | ||
711 | static int tvp5150_get_vbi(struct i2c_client *c, | 710 | static int tvp5150_get_vbi(struct v4l2_subdev *sd, |
712 | const struct i2c_vbi_ram_value *regs, int line) | 711 | const struct i2c_vbi_ram_value *regs, int line) |
713 | { | 712 | { |
714 | struct tvp5150 *decoder = i2c_get_clientdata(c); | 713 | struct tvp5150 *decoder = to_tvp5150(sd); |
715 | v4l2_std_id std=decoder->norm; | 714 | v4l2_std_id std = decoder->norm; |
716 | u8 reg; | 715 | u8 reg; |
717 | int pos, type=0; | 716 | int pos, type = 0; |
718 | 717 | ||
719 | if (std == V4L2_STD_ALL) { | 718 | if (std == V4L2_STD_ALL) { |
720 | tvp5150_err("VBI can't be configured without knowing number of lines\n"); | 719 | v4l2_err(sd, "VBI can't be configured without knowing number of lines\n"); |
721 | return 0; | 720 | return 0; |
722 | } else if (std & V4L2_STD_625_50) { | 721 | } else if (std & V4L2_STD_625_50) { |
723 | /* Don't follow NTSC Line number convension */ | 722 | /* Don't follow NTSC Line number convension */ |
724 | line += 3; | 723 | line += 3; |
725 | } | 724 | } |
726 | 725 | ||
727 | if (line<6||line>27) | 726 | if (line < 6 || line > 27) |
728 | return 0; | 727 | return 0; |
729 | 728 | ||
730 | reg=((line-6)<<1)+TVP5150_LINE_MODE_INI; | 729 | reg = ((line - 6) << 1) + TVP5150_LINE_MODE_INI; |
731 | 730 | ||
732 | pos=tvp5150_read(c, reg)&0x0f; | 731 | pos = tvp5150_read(sd, reg) & 0x0f; |
733 | if (pos<0x0f) | 732 | if (pos < 0x0f) |
734 | type=regs[pos].type.vbi_type; | 733 | type = regs[pos].type.vbi_type; |
735 | 734 | ||
736 | pos=tvp5150_read(c, reg+1)&0x0f; | 735 | pos = tvp5150_read(sd, reg + 1) & 0x0f; |
737 | if (pos<0x0f) | 736 | if (pos < 0x0f) |
738 | type|=regs[pos].type.vbi_type; | 737 | type |= regs[pos].type.vbi_type; |
739 | 738 | ||
740 | return type; | 739 | return type; |
741 | } | 740 | } |
742 | static int tvp5150_set_std(struct i2c_client *c, v4l2_std_id std) | 741 | |
742 | static int tvp5150_set_std(struct v4l2_subdev *sd, v4l2_std_id std) | ||
743 | { | 743 | { |
744 | struct tvp5150 *decoder = i2c_get_clientdata(c); | 744 | struct tvp5150 *decoder = to_tvp5150(sd); |
745 | int fmt=0; | 745 | int fmt = 0; |
746 | 746 | ||
747 | decoder->norm=std; | 747 | decoder->norm = std; |
748 | 748 | ||
749 | /* First tests should be against specific std */ | 749 | /* First tests should be against specific std */ |
750 | 750 | ||
751 | if (std == V4L2_STD_ALL) { | 751 | if (std == V4L2_STD_ALL) { |
752 | fmt=0; /* Autodetect mode */ | 752 | fmt = 0; /* Autodetect mode */ |
753 | } else if (std & V4L2_STD_NTSC_443) { | 753 | } else if (std & V4L2_STD_NTSC_443) { |
754 | fmt=0xa; | 754 | fmt = 0xa; |
755 | } else if (std & V4L2_STD_PAL_M) { | 755 | } else if (std & V4L2_STD_PAL_M) { |
756 | fmt=0x6; | 756 | fmt = 0x6; |
757 | } else if (std & (V4L2_STD_PAL_N| V4L2_STD_PAL_Nc)) { | 757 | } else if (std & (V4L2_STD_PAL_N | V4L2_STD_PAL_Nc)) { |
758 | fmt=0x8; | 758 | fmt = 0x8; |
759 | } else { | 759 | } else { |
760 | /* Then, test against generic ones */ | 760 | /* Then, test against generic ones */ |
761 | if (std & V4L2_STD_NTSC) { | 761 | if (std & V4L2_STD_NTSC) |
762 | fmt=0x2; | 762 | fmt = 0x2; |
763 | } else if (std & V4L2_STD_PAL) { | 763 | else if (std & V4L2_STD_PAL) |
764 | fmt=0x4; | 764 | fmt = 0x4; |
765 | } else if (std & V4L2_STD_SECAM) { | 765 | else if (std & V4L2_STD_SECAM) |
766 | fmt=0xc; | 766 | fmt = 0xc; |
767 | } | ||
768 | } | 767 | } |
769 | 768 | ||
770 | tvp5150_dbg(1,"Set video std register to %d.\n",fmt); | 769 | v4l2_dbg(1, debug, sd, "Set video std register to %d.\n", fmt); |
771 | tvp5150_write(c, TVP5150_VIDEO_STD, fmt); | 770 | tvp5150_write(sd, TVP5150_VIDEO_STD, fmt); |
772 | |||
773 | return 0; | 771 | return 0; |
774 | } | 772 | } |
775 | 773 | ||
776 | static inline void tvp5150_reset(struct i2c_client *c) | 774 | static int tvp5150_s_std(struct v4l2_subdev *sd, v4l2_std_id std) |
775 | { | ||
776 | struct tvp5150 *decoder = to_tvp5150(sd); | ||
777 | |||
778 | if (decoder->norm == std) | ||
779 | return 0; | ||
780 | |||
781 | return tvp5150_set_std(sd, std); | ||
782 | } | ||
783 | |||
784 | static int tvp5150_reset(struct v4l2_subdev *sd, u32 val) | ||
777 | { | 785 | { |
786 | struct tvp5150 *decoder = to_tvp5150(sd); | ||
778 | u8 msb_id, lsb_id, msb_rom, lsb_rom; | 787 | u8 msb_id, lsb_id, msb_rom, lsb_rom; |
779 | struct tvp5150 *decoder = i2c_get_clientdata(c); | ||
780 | 788 | ||
781 | msb_id=tvp5150_read(c,TVP5150_MSB_DEV_ID); | 789 | msb_id = tvp5150_read(sd, TVP5150_MSB_DEV_ID); |
782 | lsb_id=tvp5150_read(c,TVP5150_LSB_DEV_ID); | 790 | lsb_id = tvp5150_read(sd, TVP5150_LSB_DEV_ID); |
783 | msb_rom=tvp5150_read(c,TVP5150_ROM_MAJOR_VER); | 791 | msb_rom = tvp5150_read(sd, TVP5150_ROM_MAJOR_VER); |
784 | lsb_rom=tvp5150_read(c,TVP5150_ROM_MINOR_VER); | 792 | lsb_rom = tvp5150_read(sd, TVP5150_ROM_MINOR_VER); |
785 | 793 | ||
786 | if ((msb_rom==4)&&(lsb_rom==0)) { /* Is TVP5150AM1 */ | 794 | if (msb_rom == 4 && lsb_rom == 0) { /* Is TVP5150AM1 */ |
787 | tvp5150_info("tvp%02x%02xam1 detected.\n",msb_id, lsb_id); | 795 | v4l2_info(sd, "tvp%02x%02xam1 detected.\n", msb_id, lsb_id); |
788 | 796 | ||
789 | /* ITU-T BT.656.4 timing */ | 797 | /* ITU-T BT.656.4 timing */ |
790 | tvp5150_write(c,TVP5150_REV_SELECT,0); | 798 | tvp5150_write(sd, TVP5150_REV_SELECT, 0); |
791 | } else { | 799 | } else { |
792 | if ((msb_rom==3)||(lsb_rom==0x21)) { /* Is TVP5150A */ | 800 | if (msb_rom == 3 || lsb_rom == 0x21) { /* Is TVP5150A */ |
793 | tvp5150_info("tvp%02x%02xa detected.\n",msb_id, lsb_id); | 801 | v4l2_info(sd, "tvp%02x%02xa detected.\n", msb_id, lsb_id); |
794 | } else { | 802 | } else { |
795 | tvp5150_info("*** unknown tvp%02x%02x chip detected.\n",msb_id,lsb_id); | 803 | v4l2_info(sd, "*** unknown tvp%02x%02x chip detected.\n", |
796 | tvp5150_info("*** Rom ver is %d.%d\n",msb_rom,lsb_rom); | 804 | msb_id, lsb_id); |
805 | v4l2_info(sd, "*** Rom ver is %d.%d\n", msb_rom, lsb_rom); | ||
797 | } | 806 | } |
798 | } | 807 | } |
799 | 808 | ||
800 | /* Initializes TVP5150 to its default values */ | 809 | /* Initializes TVP5150 to its default values */ |
801 | tvp5150_write_inittab(c, tvp5150_init_default); | 810 | tvp5150_write_inittab(sd, tvp5150_init_default); |
802 | 811 | ||
803 | /* Initializes VDP registers */ | 812 | /* Initializes VDP registers */ |
804 | tvp5150_vdp_init(c, vbi_ram_default); | 813 | tvp5150_vdp_init(sd, vbi_ram_default); |
805 | 814 | ||
806 | /* Selects decoder input */ | 815 | /* Selects decoder input */ |
807 | tvp5150_selmux(c); | 816 | tvp5150_selmux(sd); |
808 | 817 | ||
809 | /* Initializes TVP5150 to stream enabled values */ | 818 | /* Initializes TVP5150 to stream enabled values */ |
810 | tvp5150_write_inittab(c, tvp5150_init_enable); | 819 | tvp5150_write_inittab(sd, tvp5150_init_enable); |
811 | 820 | ||
812 | /* Initialize image preferences */ | 821 | /* Initialize image preferences */ |
813 | tvp5150_write(c, TVP5150_BRIGHT_CTL, decoder->bright); | 822 | tvp5150_write(sd, TVP5150_BRIGHT_CTL, decoder->bright); |
814 | tvp5150_write(c, TVP5150_CONTRAST_CTL, decoder->contrast); | 823 | tvp5150_write(sd, TVP5150_CONTRAST_CTL, decoder->contrast); |
815 | tvp5150_write(c, TVP5150_SATURATION_CTL, decoder->contrast); | 824 | tvp5150_write(sd, TVP5150_SATURATION_CTL, decoder->contrast); |
816 | tvp5150_write(c, TVP5150_HUE_CTL, decoder->hue); | 825 | tvp5150_write(sd, TVP5150_HUE_CTL, decoder->hue); |
817 | 826 | ||
818 | tvp5150_set_std(c, decoder->norm); | 827 | tvp5150_set_std(sd, decoder->norm); |
828 | return 0; | ||
819 | }; | 829 | }; |
820 | 830 | ||
821 | static int tvp5150_get_ctrl(struct i2c_client *c, struct v4l2_control *ctrl) | 831 | static int tvp5150_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
822 | { | 832 | { |
823 | /* struct tvp5150 *decoder = i2c_get_clientdata(c); */ | 833 | v4l2_dbg(1, debug, sd, "VIDIOC_G_CTRL called\n"); |
824 | 834 | ||
825 | switch (ctrl->id) { | 835 | switch (ctrl->id) { |
826 | case V4L2_CID_BRIGHTNESS: | 836 | case V4L2_CID_BRIGHTNESS: |
827 | ctrl->value = tvp5150_read(c, TVP5150_BRIGHT_CTL); | 837 | ctrl->value = tvp5150_read(sd, TVP5150_BRIGHT_CTL); |
828 | return 0; | 838 | return 0; |
829 | case V4L2_CID_CONTRAST: | 839 | case V4L2_CID_CONTRAST: |
830 | ctrl->value = tvp5150_read(c, TVP5150_CONTRAST_CTL); | 840 | ctrl->value = tvp5150_read(sd, TVP5150_CONTRAST_CTL); |
831 | return 0; | 841 | return 0; |
832 | case V4L2_CID_SATURATION: | 842 | case V4L2_CID_SATURATION: |
833 | ctrl->value = tvp5150_read(c, TVP5150_SATURATION_CTL); | 843 | ctrl->value = tvp5150_read(sd, TVP5150_SATURATION_CTL); |
834 | return 0; | 844 | return 0; |
835 | case V4L2_CID_HUE: | 845 | case V4L2_CID_HUE: |
836 | ctrl->value = tvp5150_read(c, TVP5150_HUE_CTL); | 846 | ctrl->value = tvp5150_read(sd, TVP5150_HUE_CTL); |
837 | return 0; | 847 | return 0; |
838 | } | 848 | } |
839 | return -EINVAL; | 849 | return -EINVAL; |
840 | } | 850 | } |
841 | 851 | ||
842 | static int tvp5150_set_ctrl(struct i2c_client *c, struct v4l2_control *ctrl) | 852 | static int tvp5150_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
843 | { | 853 | { |
844 | /* struct tvp5150 *decoder = i2c_get_clientdata(c); */ | 854 | u8 i, n; |
855 | n = ARRAY_SIZE(tvp5150_qctrl); | ||
856 | |||
857 | for (i = 0; i < n; i++) { | ||
858 | if (ctrl->id != tvp5150_qctrl[i].id) | ||
859 | continue; | ||
860 | if (ctrl->value < tvp5150_qctrl[i].minimum || | ||
861 | ctrl->value > tvp5150_qctrl[i].maximum) | ||
862 | return -ERANGE; | ||
863 | v4l2_dbg(1, debug, sd, "VIDIOC_S_CTRL: id=%d, value=%d\n", | ||
864 | ctrl->id, ctrl->value); | ||
865 | break; | ||
866 | } | ||
845 | 867 | ||
846 | switch (ctrl->id) { | 868 | switch (ctrl->id) { |
847 | case V4L2_CID_BRIGHTNESS: | 869 | case V4L2_CID_BRIGHTNESS: |
848 | tvp5150_write(c, TVP5150_BRIGHT_CTL, ctrl->value); | 870 | tvp5150_write(sd, TVP5150_BRIGHT_CTL, ctrl->value); |
849 | return 0; | 871 | return 0; |
850 | case V4L2_CID_CONTRAST: | 872 | case V4L2_CID_CONTRAST: |
851 | tvp5150_write(c, TVP5150_CONTRAST_CTL, ctrl->value); | 873 | tvp5150_write(sd, TVP5150_CONTRAST_CTL, ctrl->value); |
852 | return 0; | 874 | return 0; |
853 | case V4L2_CID_SATURATION: | 875 | case V4L2_CID_SATURATION: |
854 | tvp5150_write(c, TVP5150_SATURATION_CTL, ctrl->value); | 876 | tvp5150_write(sd, TVP5150_SATURATION_CTL, ctrl->value); |
855 | return 0; | 877 | return 0; |
856 | case V4L2_CID_HUE: | 878 | case V4L2_CID_HUE: |
857 | tvp5150_write(c, TVP5150_HUE_CTL, ctrl->value); | 879 | tvp5150_write(sd, TVP5150_HUE_CTL, ctrl->value); |
858 | return 0; | 880 | return 0; |
859 | } | 881 | } |
860 | return -EINVAL; | 882 | return -EINVAL; |
@@ -863,242 +885,195 @@ static int tvp5150_set_ctrl(struct i2c_client *c, struct v4l2_control *ctrl) | |||
863 | /**************************************************************************** | 885 | /**************************************************************************** |
864 | I2C Command | 886 | I2C Command |
865 | ****************************************************************************/ | 887 | ****************************************************************************/ |
866 | static int tvp5150_command(struct i2c_client *c, | ||
867 | unsigned int cmd, void *arg) | ||
868 | { | ||
869 | struct tvp5150 *decoder = i2c_get_clientdata(c); | ||
870 | |||
871 | switch (cmd) { | ||
872 | |||
873 | case 0: | ||
874 | case VIDIOC_INT_RESET: | ||
875 | tvp5150_reset(c); | ||
876 | break; | ||
877 | case VIDIOC_INT_G_VIDEO_ROUTING: | ||
878 | { | ||
879 | struct v4l2_routing *route = arg; | ||
880 | 888 | ||
881 | *route = decoder->route; | 889 | static int tvp5150_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route) |
882 | break; | 890 | { |
883 | } | 891 | struct tvp5150 *decoder = to_tvp5150(sd); |
884 | case VIDIOC_INT_S_VIDEO_ROUTING: | ||
885 | { | ||
886 | struct v4l2_routing *route = arg; | ||
887 | |||
888 | decoder->route = *route; | ||
889 | tvp5150_selmux(c); | ||
890 | break; | ||
891 | } | ||
892 | case VIDIOC_S_STD: | ||
893 | if (decoder->norm == *(v4l2_std_id *)arg) | ||
894 | break; | ||
895 | return tvp5150_set_std(c, *(v4l2_std_id *)arg); | ||
896 | case VIDIOC_G_STD: | ||
897 | *(v4l2_std_id *)arg = decoder->norm; | ||
898 | break; | ||
899 | 892 | ||
900 | case VIDIOC_G_SLICED_VBI_CAP: | 893 | decoder->route = *route; |
901 | { | 894 | tvp5150_selmux(sd); |
902 | struct v4l2_sliced_vbi_cap *cap = arg; | 895 | return 0; |
903 | tvp5150_dbg(1, "VIDIOC_G_SLICED_VBI_CAP\n"); | 896 | } |
904 | 897 | ||
905 | tvp5150_vbi_get_cap(vbi_ram_default, cap); | 898 | static int tvp5150_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) |
906 | break; | 899 | { |
900 | struct v4l2_sliced_vbi_format *svbi; | ||
901 | int i; | ||
902 | |||
903 | /* raw vbi */ | ||
904 | if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { | ||
905 | /* this is for capturing 36 raw vbi lines | ||
906 | if there's a way to cut off the beginning 2 vbi lines | ||
907 | with the tvp5150 then the vbi line count could be lowered | ||
908 | to 17 lines/field again, although I couldn't find a register | ||
909 | which could do that cropping */ | ||
910 | if (fmt->fmt.vbi.sample_format == V4L2_PIX_FMT_GREY) | ||
911 | tvp5150_write(sd, TVP5150_LUMA_PROC_CTL_1, 0x70); | ||
912 | if (fmt->fmt.vbi.count[0] == 18 && fmt->fmt.vbi.count[1] == 18) { | ||
913 | tvp5150_write(sd, TVP5150_VERT_BLANKING_START, 0x00); | ||
914 | tvp5150_write(sd, TVP5150_VERT_BLANKING_STOP, 0x01); | ||
915 | } | ||
916 | return 0; | ||
907 | } | 917 | } |
908 | case VIDIOC_S_FMT: | 918 | if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) |
909 | { | 919 | return -EINVAL; |
910 | struct v4l2_format *fmt; | 920 | svbi = &fmt->fmt.sliced; |
911 | struct v4l2_sliced_vbi_format *svbi; | 921 | if (svbi->service_set != 0) { |
912 | int i; | 922 | for (i = 0; i <= 23; i++) { |
913 | 923 | svbi->service_lines[1][i] = 0; | |
914 | fmt = arg; | 924 | svbi->service_lines[0][i] = |
915 | /* raw vbi */ | 925 | tvp5150_set_vbi(sd, vbi_ram_default, |
916 | if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { | 926 | svbi->service_lines[0][i], 0xf0, i, 3); |
917 | /* this is for capturing 36 raw vbi lines | ||
918 | if there's a way to cut off the beginning 2 vbi lines | ||
919 | with the tvp5150 then the vbi line count could be lowered | ||
920 | to 17 lines/field again, although I couldn't find a register | ||
921 | which could do that cropping */ | ||
922 | if (fmt->fmt.vbi.sample_format == V4L2_PIX_FMT_GREY) | ||
923 | tvp5150_write(c, TVP5150_LUMA_PROC_CTL_1, 0x70); | ||
924 | if (fmt->fmt.vbi.count[0] == 18 && fmt->fmt.vbi.count[1] == 18) { | ||
925 | tvp5150_write(c, TVP5150_VERT_BLANKING_START, 0x00); | ||
926 | tvp5150_write(c, TVP5150_VERT_BLANKING_STOP, 0x01); | ||
927 | } | ||
928 | break; | ||
929 | } | 927 | } |
930 | if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) | 928 | /* Enables FIFO */ |
931 | return -EINVAL; | 929 | tvp5150_write(sd, TVP5150_FIFO_OUT_CTRL, 1); |
932 | svbi = &fmt->fmt.sliced; | 930 | } else { |
933 | if (svbi->service_set != 0) { | 931 | /* Disables FIFO*/ |
934 | for (i = 0; i <= 23; i++) { | 932 | tvp5150_write(sd, TVP5150_FIFO_OUT_CTRL, 0); |
935 | svbi->service_lines[1][i] = 0; | ||
936 | |||
937 | svbi->service_lines[0][i]=tvp5150_set_vbi(c, | ||
938 | vbi_ram_default, | ||
939 | svbi->service_lines[0][i],0xf0,i,3); | ||
940 | } | ||
941 | /* Enables FIFO */ | ||
942 | tvp5150_write(c, TVP5150_FIFO_OUT_CTRL,1); | ||
943 | } else { | ||
944 | /* Disables FIFO*/ | ||
945 | tvp5150_write(c, TVP5150_FIFO_OUT_CTRL,0); | ||
946 | 933 | ||
947 | /* Disable Full Field */ | 934 | /* Disable Full Field */ |
948 | tvp5150_write(c, TVP5150_FULL_FIELD_ENA, 0); | 935 | tvp5150_write(sd, TVP5150_FULL_FIELD_ENA, 0); |
949 | 936 | ||
950 | /* Disable Line modes */ | 937 | /* Disable Line modes */ |
951 | for (i=TVP5150_LINE_MODE_INI; i<=TVP5150_LINE_MODE_END; i++) | 938 | for (i = TVP5150_LINE_MODE_INI; i <= TVP5150_LINE_MODE_END; i++) |
952 | tvp5150_write(c, i, 0xff); | 939 | tvp5150_write(sd, i, 0xff); |
953 | } | ||
954 | break; | ||
955 | } | 940 | } |
956 | case VIDIOC_G_FMT: | 941 | return 0; |
957 | { | 942 | } |
958 | struct v4l2_format *fmt; | ||
959 | struct v4l2_sliced_vbi_format *svbi; | ||
960 | 943 | ||
961 | int i, mask=0; | 944 | static int tvp5150_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) |
945 | { | ||
946 | struct v4l2_sliced_vbi_format *svbi; | ||
947 | int i, mask = 0; | ||
962 | 948 | ||
963 | fmt = arg; | 949 | if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) |
964 | if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) | 950 | return -EINVAL; |
965 | return -EINVAL; | 951 | svbi = &fmt->fmt.sliced; |
966 | svbi = &fmt->fmt.sliced; | 952 | memset(svbi, 0, sizeof(*svbi)); |
967 | memset(svbi, 0, sizeof(*svbi)); | ||
968 | 953 | ||
969 | for (i = 0; i <= 23; i++) { | 954 | for (i = 0; i <= 23; i++) { |
970 | svbi->service_lines[0][i]=tvp5150_get_vbi(c, | 955 | svbi->service_lines[0][i] = |
971 | vbi_ram_default,i); | 956 | tvp5150_get_vbi(sd, vbi_ram_default, i); |
972 | mask|=svbi->service_lines[0][i]; | 957 | mask |= svbi->service_lines[0][i]; |
973 | } | ||
974 | svbi->service_set=mask; | ||
975 | break; | ||
976 | } | 958 | } |
959 | svbi->service_set = mask; | ||
960 | return 0; | ||
961 | } | ||
962 | |||
977 | 963 | ||
978 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 964 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
979 | case VIDIOC_DBG_G_REGISTER: | 965 | static int tvp5150_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg) |
980 | case VIDIOC_DBG_S_REGISTER: | 966 | { |
981 | { | 967 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
982 | struct v4l2_register *reg = arg; | ||
983 | |||
984 | if (!v4l2_chip_match_i2c_client(c, reg->match_type, reg->match_chip)) | ||
985 | return -EINVAL; | ||
986 | if (!capable(CAP_SYS_ADMIN)) | ||
987 | return -EPERM; | ||
988 | if (cmd == VIDIOC_DBG_G_REGISTER) | ||
989 | reg->val = tvp5150_read(c, reg->reg & 0xff); | ||
990 | else | ||
991 | tvp5150_write(c, reg->reg & 0xff, reg->val & 0xff); | ||
992 | break; | ||
993 | } | ||
994 | #endif | ||
995 | 968 | ||
996 | case VIDIOC_LOG_STATUS: | 969 | if (!v4l2_chip_match_i2c_client(client, |
997 | dump_reg(c); | 970 | reg->match_type, reg->match_chip)) |
998 | break; | 971 | return -EINVAL; |
972 | if (!capable(CAP_SYS_ADMIN)) | ||
973 | return -EPERM; | ||
974 | reg->val = tvp5150_read(sd, reg->reg & 0xff); | ||
975 | return 0; | ||
976 | } | ||
999 | 977 | ||
1000 | case VIDIOC_G_TUNER: | 978 | static int tvp5150_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg) |
1001 | { | 979 | { |
1002 | struct v4l2_tuner *vt = arg; | 980 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
1003 | int status = tvp5150_read(c, 0x88); | ||
1004 | 981 | ||
1005 | vt->signal = ((status & 0x04) && (status & 0x02)) ? 0xffff : 0x0; | 982 | if (!v4l2_chip_match_i2c_client(client, |
1006 | break; | 983 | reg->match_type, reg->match_chip)) |
1007 | } | 984 | return -EINVAL; |
1008 | case VIDIOC_QUERYCTRL: | 985 | if (!capable(CAP_SYS_ADMIN)) |
1009 | { | 986 | return -EPERM; |
1010 | struct v4l2_queryctrl *qc = arg; | 987 | tvp5150_write(sd, reg->reg & 0xff, reg->val & 0xff); |
1011 | int i; | 988 | return 0; |
989 | } | ||
990 | #endif | ||
1012 | 991 | ||
1013 | tvp5150_dbg(1, "VIDIOC_QUERYCTRL called\n"); | 992 | static int tvp5150_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) |
993 | { | ||
994 | int status = tvp5150_read(sd, 0x88); | ||
1014 | 995 | ||
1015 | for (i = 0; i < ARRAY_SIZE(tvp5150_qctrl); i++) | 996 | vt->signal = ((status & 0x04) && (status & 0x02)) ? 0xffff : 0x0; |
1016 | if (qc->id && qc->id == tvp5150_qctrl[i].id) { | 997 | return 0; |
1017 | memcpy(qc, &(tvp5150_qctrl[i]), | 998 | } |
1018 | sizeof(*qc)); | ||
1019 | return 0; | ||
1020 | } | ||
1021 | 999 | ||
1022 | return -EINVAL; | 1000 | static int tvp5150_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) |
1023 | } | 1001 | { |
1024 | case VIDIOC_G_CTRL: | 1002 | int i; |
1025 | { | ||
1026 | struct v4l2_control *ctrl = arg; | ||
1027 | tvp5150_dbg(1, "VIDIOC_G_CTRL called\n"); | ||
1028 | 1003 | ||
1029 | return tvp5150_get_ctrl(c, ctrl); | 1004 | v4l2_dbg(1, debug, sd, "VIDIOC_QUERYCTRL called\n"); |
1030 | } | 1005 | |
1031 | case VIDIOC_S_CTRL: | 1006 | for (i = 0; i < ARRAY_SIZE(tvp5150_qctrl); i++) |
1032 | { | 1007 | if (qc->id && qc->id == tvp5150_qctrl[i].id) { |
1033 | struct v4l2_control *ctrl = arg; | 1008 | memcpy(qc, &(tvp5150_qctrl[i]), |
1034 | u8 i, n; | 1009 | sizeof(*qc)); |
1035 | n = ARRAY_SIZE(tvp5150_qctrl); | 1010 | return 0; |
1036 | for (i = 0; i < n; i++) | ||
1037 | if (ctrl->id == tvp5150_qctrl[i].id) { | ||
1038 | if (ctrl->value < | ||
1039 | tvp5150_qctrl[i].minimum | ||
1040 | || ctrl->value > | ||
1041 | tvp5150_qctrl[i].maximum) | ||
1042 | return -ERANGE; | ||
1043 | tvp5150_dbg(1, | ||
1044 | "VIDIOC_S_CTRL: id=%d, value=%d\n", | ||
1045 | ctrl->id, ctrl->value); | ||
1046 | return tvp5150_set_ctrl(c, ctrl); | ||
1047 | } | ||
1048 | return -EINVAL; | ||
1049 | } | 1011 | } |
1050 | 1012 | ||
1051 | default: | 1013 | return -EINVAL; |
1052 | return -EINVAL; | 1014 | } |
1053 | } | ||
1054 | 1015 | ||
1055 | return 0; | 1016 | static int tvp5150_command(struct i2c_client *client, unsigned cmd, void *arg) |
1017 | { | ||
1018 | return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); | ||
1056 | } | 1019 | } |
1057 | 1020 | ||
1021 | /* ----------------------------------------------------------------------- */ | ||
1022 | |||
1023 | static const struct v4l2_subdev_core_ops tvp5150_core_ops = { | ||
1024 | .log_status = tvp5150_log_status, | ||
1025 | .g_ctrl = tvp5150_g_ctrl, | ||
1026 | .s_ctrl = tvp5150_s_ctrl, | ||
1027 | .queryctrl = tvp5150_queryctrl, | ||
1028 | .reset = tvp5150_reset, | ||
1029 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1030 | .g_register = tvp5150_g_register, | ||
1031 | .s_register = tvp5150_s_register, | ||
1032 | #endif | ||
1033 | }; | ||
1034 | |||
1035 | static const struct v4l2_subdev_tuner_ops tvp5150_tuner_ops = { | ||
1036 | .s_std = tvp5150_s_std, | ||
1037 | .g_tuner = tvp5150_g_tuner, | ||
1038 | }; | ||
1039 | |||
1040 | static const struct v4l2_subdev_video_ops tvp5150_video_ops = { | ||
1041 | .s_routing = tvp5150_s_routing, | ||
1042 | .g_fmt = tvp5150_g_fmt, | ||
1043 | .s_fmt = tvp5150_s_fmt, | ||
1044 | .g_sliced_vbi_cap = tvp5150_g_sliced_vbi_cap, | ||
1045 | }; | ||
1046 | |||
1047 | static const struct v4l2_subdev_ops tvp5150_ops = { | ||
1048 | .core = &tvp5150_core_ops, | ||
1049 | .tuner = &tvp5150_tuner_ops, | ||
1050 | .video = &tvp5150_video_ops, | ||
1051 | }; | ||
1052 | |||
1053 | |||
1058 | /**************************************************************************** | 1054 | /**************************************************************************** |
1059 | I2C Client & Driver | 1055 | I2C Client & Driver |
1060 | ****************************************************************************/ | 1056 | ****************************************************************************/ |
1061 | static struct i2c_driver driver; | ||
1062 | |||
1063 | static struct i2c_client client_template = { | ||
1064 | .name = "(unset)", | ||
1065 | .driver = &driver, | ||
1066 | }; | ||
1067 | 1057 | ||
1068 | static int tvp5150_detect_client(struct i2c_adapter *adapter, | 1058 | static int tvp5150_probe(struct i2c_client *c, |
1069 | int address, int kind) | 1059 | const struct i2c_device_id *id) |
1070 | { | 1060 | { |
1071 | struct i2c_client *c; | ||
1072 | struct tvp5150 *core; | 1061 | struct tvp5150 *core; |
1073 | int rv; | 1062 | struct v4l2_subdev *sd; |
1074 | |||
1075 | if (debug) | ||
1076 | printk( KERN_INFO | ||
1077 | "tvp5150.c: detecting tvp5150 client on address 0x%x\n", | ||
1078 | address << 1); | ||
1079 | |||
1080 | client_template.adapter = adapter; | ||
1081 | client_template.addr = address; | ||
1082 | 1063 | ||
1083 | /* Check if the adapter supports the needed features */ | 1064 | /* Check if the adapter supports the needed features */ |
1084 | if (!i2c_check_functionality | 1065 | if (!i2c_check_functionality(c->adapter, |
1085 | (adapter, | ||
1086 | I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) | 1066 | I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) |
1087 | return 0; | 1067 | return -EIO; |
1088 | |||
1089 | c = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
1090 | if (!c) | ||
1091 | return -ENOMEM; | ||
1092 | memcpy(c, &client_template, sizeof(struct i2c_client)); | ||
1093 | 1068 | ||
1094 | core = kzalloc(sizeof(struct tvp5150), GFP_KERNEL); | 1069 | core = kzalloc(sizeof(struct tvp5150), GFP_KERNEL); |
1095 | if (!core) { | 1070 | if (!core) { |
1096 | kfree(c); | ||
1097 | return -ENOMEM; | 1071 | return -ENOMEM; |
1098 | } | 1072 | } |
1099 | i2c_set_clientdata(c, core); | 1073 | sd = &core->sd; |
1100 | 1074 | v4l2_i2c_subdev_init(sd, c, &tvp5150_ops); | |
1101 | rv = i2c_attach_client(c); | 1075 | v4l_info(c, "chip found @ 0x%02x (%s)\n", |
1076 | c->addr << 1, c->adapter->name); | ||
1102 | 1077 | ||
1103 | core->norm = V4L2_STD_ALL; /* Default is autodetect */ | 1078 | core->norm = V4L2_STD_ALL; /* Default is autodetect */ |
1104 | core->route.input = TVP5150_COMPOSITE1; | 1079 | core->route.input = TVP5150_COMPOSITE1; |
@@ -1108,69 +1083,38 @@ static int tvp5150_detect_client(struct i2c_adapter *adapter, | |||
1108 | core->hue = 0; | 1083 | core->hue = 0; |
1109 | core->sat = 128; | 1084 | core->sat = 128; |
1110 | 1085 | ||
1111 | if (rv) { | ||
1112 | kfree(c); | ||
1113 | kfree(core); | ||
1114 | return rv; | ||
1115 | } | ||
1116 | |||
1117 | if (debug > 1) | 1086 | if (debug > 1) |
1118 | dump_reg(c); | 1087 | tvp5150_log_status(sd); |
1119 | return 0; | 1088 | return 0; |
1120 | } | 1089 | } |
1121 | 1090 | ||
1122 | static int tvp5150_attach_adapter(struct i2c_adapter *adapter) | 1091 | static int tvp5150_remove(struct i2c_client *c) |
1123 | { | 1092 | { |
1124 | if (debug) | 1093 | struct v4l2_subdev *sd = i2c_get_clientdata(c); |
1125 | printk( KERN_INFO | ||
1126 | "tvp5150.c: starting probe for adapter %s (0x%x)\n", | ||
1127 | adapter->name, adapter->id); | ||
1128 | return i2c_probe(adapter, &addr_data, &tvp5150_detect_client); | ||
1129 | } | ||
1130 | |||
1131 | static int tvp5150_detach_client(struct i2c_client *c) | ||
1132 | { | ||
1133 | struct tvp5150 *decoder = i2c_get_clientdata(c); | ||
1134 | int err; | ||
1135 | 1094 | ||
1136 | tvp5150_dbg(1, | 1095 | v4l2_dbg(1, debug, sd, |
1137 | "tvp5150.c: removing tvp5150 adapter on address 0x%x\n", | 1096 | "tvp5150.c: removing tvp5150 adapter on address 0x%x\n", |
1138 | c->addr << 1); | 1097 | c->addr << 1); |
1139 | 1098 | ||
1140 | err = i2c_detach_client(c); | 1099 | v4l2_device_unregister_subdev(sd); |
1141 | if (err) { | 1100 | kfree(to_tvp5150(sd)); |
1142 | return err; | ||
1143 | } | ||
1144 | |||
1145 | kfree(decoder); | ||
1146 | kfree(c); | ||
1147 | |||
1148 | return 0; | 1101 | return 0; |
1149 | } | 1102 | } |
1150 | 1103 | ||
1151 | /* ----------------------------------------------------------------------- */ | 1104 | /* ----------------------------------------------------------------------- */ |
1152 | 1105 | ||
1153 | static struct i2c_driver driver = { | 1106 | static const struct i2c_device_id tvp5150_id[] = { |
1154 | .driver = { | 1107 | { "tvp5150", 0 }, |
1155 | .name = "tvp5150", | 1108 | { } |
1156 | }, | 1109 | }; |
1157 | .id = I2C_DRIVERID_TVP5150, | 1110 | MODULE_DEVICE_TABLE(i2c, tvp5150_id); |
1158 | |||
1159 | .attach_adapter = tvp5150_attach_adapter, | ||
1160 | .detach_client = tvp5150_detach_client, | ||
1161 | 1111 | ||
1112 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { | ||
1113 | .name = "tvp5150", | ||
1114 | .driverid = I2C_DRIVERID_TVP5150, | ||
1162 | .command = tvp5150_command, | 1115 | .command = tvp5150_command, |
1116 | .probe = tvp5150_probe, | ||
1117 | .remove = tvp5150_remove, | ||
1118 | .legacy_class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL, | ||
1119 | .id_table = tvp5150_id, | ||
1163 | }; | 1120 | }; |
1164 | |||
1165 | static int __init tvp5150_init(void) | ||
1166 | { | ||
1167 | return i2c_add_driver(&driver); | ||
1168 | } | ||
1169 | |||
1170 | static void __exit tvp5150_exit(void) | ||
1171 | { | ||
1172 | i2c_del_driver(&driver); | ||
1173 | } | ||
1174 | |||
1175 | module_init(tvp5150_init); | ||
1176 | module_exit(tvp5150_exit); | ||