diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-21 12:03:10 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-21 12:03:10 -0400 |
commit | c720f5655df159a630fa0290a0bd67c93e92b0bf (patch) | |
tree | 940d139d0ec1ff5201efddef6cc663166a8a2df3 /drivers/media/video/tvp514x.c | |
parent | 33e6c1a0de818d3698cdab27c42915661011319d (diff) | |
parent | 84d6ae431f315e8973aac3c3fe1d550fc9240ef3 (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (222 commits)
V4L/DVB (13033): pt1: Don't use a deprecated DMA_BIT_MASK macro
V4L/DVB (13029): radio-si4713: remove #include <linux/version.h>
V4L/DVB (13027): go7007: convert printks to v4l2_info
V4L/DVB (13026): s2250-board: Implement brightness and contrast controls
V4L/DVB (13025): s2250-board: Fix memory leaks
V4L/DVB (13024): go7007: Implement vidioc_g_std and vidioc_querystd
V4L/DVB (13023): go7007: Merge struct gofh and go declarations
V4L/DVB (13022): go7007: Fix mpeg controls
V4L/DVB (13021): go7007: Fix whitespace and line lengths
V4L/DVB (13020): go7007: Updates to Kconfig and Makefile
V4L/DVB (13019): video: initial support for ADV7180
V4L/DVB (13018): kzalloc failure ignored in au8522_probe()
V4L/DVB (13017): gspca: kmalloc failure ignored in sd_start()
V4L/DVB (13016): kmalloc failure ignored in lgdt3304_attach() and s921_attach()
V4L/DVB (13015): kmalloc failure ignored in m920x_firmware_download()
V4L/DVB (13014): Add support for Compro VideoMate E800 (DVB-T part only)
V4L/DVB (13013): FM TX: si4713: Kconfig: Fixed two typos.
V4L/DVB (13012): uvc: introduce missing kfree
V4L/DVB (13011): Change tuner type of BeholdTV cards
V4L/DVB (13009): gspca - stv06xx-hdcs: Reduce exposure range
...
Diffstat (limited to 'drivers/media/video/tvp514x.c')
-rw-r--r-- | drivers/media/video/tvp514x.c | 1030 |
1 files changed, 446 insertions, 584 deletions
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c index 3750f7fadb12..244372627df2 100644 --- a/drivers/media/video/tvp514x.c +++ b/drivers/media/video/tvp514x.c | |||
@@ -31,7 +31,10 @@ | |||
31 | #include <linux/i2c.h> | 31 | #include <linux/i2c.h> |
32 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
33 | #include <linux/videodev2.h> | 33 | #include <linux/videodev2.h> |
34 | #include <media/v4l2-int-device.h> | 34 | |
35 | #include <media/v4l2-device.h> | ||
36 | #include <media/v4l2-common.h> | ||
37 | #include <media/v4l2-chip-ident.h> | ||
35 | #include <media/tvp514x.h> | 38 | #include <media/tvp514x.h> |
36 | 39 | ||
37 | #include "tvp514x_regs.h" | 40 | #include "tvp514x_regs.h" |
@@ -49,15 +52,11 @@ static int debug; | |||
49 | module_param(debug, bool, 0644); | 52 | module_param(debug, bool, 0644); |
50 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 53 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
51 | 54 | ||
52 | #define dump_reg(client, reg, val) \ | 55 | MODULE_AUTHOR("Texas Instruments"); |
53 | do { \ | 56 | MODULE_DESCRIPTION("TVP514X linux decoder driver"); |
54 | val = tvp514x_read_reg(client, reg); \ | 57 | MODULE_LICENSE("GPL"); |
55 | v4l_info(client, "Reg(0x%.2X): 0x%.2X\n", reg, val); \ | ||
56 | } while (0) | ||
57 | 58 | ||
58 | /** | 59 | /* enum tvp514x_std - enum for supported standards */ |
59 | * enum tvp514x_std - enum for supported standards | ||
60 | */ | ||
61 | enum tvp514x_std { | 60 | enum tvp514x_std { |
62 | STD_NTSC_MJ = 0, | 61 | STD_NTSC_MJ = 0, |
63 | STD_PAL_BDGHIN, | 62 | STD_PAL_BDGHIN, |
@@ -65,14 +64,6 @@ enum tvp514x_std { | |||
65 | }; | 64 | }; |
66 | 65 | ||
67 | /** | 66 | /** |
68 | * enum tvp514x_state - enum for different decoder states | ||
69 | */ | ||
70 | enum tvp514x_state { | ||
71 | STATE_NOT_DETECTED, | ||
72 | STATE_DETECTED | ||
73 | }; | ||
74 | |||
75 | /** | ||
76 | * struct tvp514x_std_info - Structure to store standard informations | 67 | * struct tvp514x_std_info - Structure to store standard informations |
77 | * @width: Line width in pixels | 68 | * @width: Line width in pixels |
78 | * @height:Number of active lines | 69 | * @height:Number of active lines |
@@ -89,33 +80,27 @@ struct tvp514x_std_info { | |||
89 | static struct tvp514x_reg tvp514x_reg_list_default[0x40]; | 80 | static struct tvp514x_reg tvp514x_reg_list_default[0x40]; |
90 | /** | 81 | /** |
91 | * struct tvp514x_decoder - TVP5146/47 decoder object | 82 | * struct tvp514x_decoder - TVP5146/47 decoder object |
92 | * @v4l2_int_device: Slave handle | 83 | * @sd: Subdevice Slave handle |
93 | * @tvp514x_slave: Slave pointer which is used by @v4l2_int_device | ||
94 | * @tvp514x_regs: copy of hw's regs with preset values. | 84 | * @tvp514x_regs: copy of hw's regs with preset values. |
95 | * @pdata: Board specific | 85 | * @pdata: Board specific |
96 | * @client: I2C client data | ||
97 | * @id: Entry from I2C table | ||
98 | * @ver: Chip version | 86 | * @ver: Chip version |
99 | * @state: TVP5146/47 decoder state - detected or not-detected | 87 | * @streaming: TVP5146/47 decoder streaming - enabled or disabled. |
100 | * @pix: Current pixel format | 88 | * @pix: Current pixel format |
101 | * @num_fmts: Number of formats | 89 | * @num_fmts: Number of formats |
102 | * @fmt_list: Format list | 90 | * @fmt_list: Format list |
103 | * @current_std: Current standard | 91 | * @current_std: Current standard |
104 | * @num_stds: Number of standards | 92 | * @num_stds: Number of standards |
105 | * @std_list: Standards list | 93 | * @std_list: Standards list |
106 | * @route: input and output routing at chip level | 94 | * @input: Input routing at chip level |
95 | * @output: Output routing at chip level | ||
107 | */ | 96 | */ |
108 | struct tvp514x_decoder { | 97 | struct tvp514x_decoder { |
109 | struct v4l2_int_device v4l2_int_device; | 98 | struct v4l2_subdev sd; |
110 | struct v4l2_int_slave tvp514x_slave; | ||
111 | struct tvp514x_reg tvp514x_regs[ARRAY_SIZE(tvp514x_reg_list_default)]; | 99 | struct tvp514x_reg tvp514x_regs[ARRAY_SIZE(tvp514x_reg_list_default)]; |
112 | const struct tvp514x_platform_data *pdata; | 100 | const struct tvp514x_platform_data *pdata; |
113 | struct i2c_client *client; | ||
114 | |||
115 | struct i2c_device_id *id; | ||
116 | 101 | ||
117 | int ver; | 102 | int ver; |
118 | enum tvp514x_state state; | 103 | int streaming; |
119 | 104 | ||
120 | struct v4l2_pix_format pix; | 105 | struct v4l2_pix_format pix; |
121 | int num_fmts; | 106 | int num_fmts; |
@@ -124,15 +109,18 @@ struct tvp514x_decoder { | |||
124 | enum tvp514x_std current_std; | 109 | enum tvp514x_std current_std; |
125 | int num_stds; | 110 | int num_stds; |
126 | struct tvp514x_std_info *std_list; | 111 | struct tvp514x_std_info *std_list; |
127 | 112 | /* Input and Output Routing parameters */ | |
128 | struct v4l2_routing route; | 113 | u32 input; |
114 | u32 output; | ||
129 | }; | 115 | }; |
130 | 116 | ||
131 | /* TVP514x default register values */ | 117 | /* TVP514x default register values */ |
132 | static struct tvp514x_reg tvp514x_reg_list_default[] = { | 118 | static struct tvp514x_reg tvp514x_reg_list_default[] = { |
133 | {TOK_WRITE, REG_INPUT_SEL, 0x05}, /* Composite selected */ | 119 | /* Composite selected */ |
120 | {TOK_WRITE, REG_INPUT_SEL, 0x05}, | ||
134 | {TOK_WRITE, REG_AFE_GAIN_CTRL, 0x0F}, | 121 | {TOK_WRITE, REG_AFE_GAIN_CTRL, 0x0F}, |
135 | {TOK_WRITE, REG_VIDEO_STD, 0x00}, /* Auto mode */ | 122 | /* Auto mode */ |
123 | {TOK_WRITE, REG_VIDEO_STD, 0x00}, | ||
136 | {TOK_WRITE, REG_OPERATION_MODE, 0x00}, | 124 | {TOK_WRITE, REG_OPERATION_MODE, 0x00}, |
137 | {TOK_SKIP, REG_AUTOSWITCH_MASK, 0x3F}, | 125 | {TOK_SKIP, REG_AUTOSWITCH_MASK, 0x3F}, |
138 | {TOK_WRITE, REG_COLOR_KILLER, 0x10}, | 126 | {TOK_WRITE, REG_COLOR_KILLER, 0x10}, |
@@ -145,53 +133,74 @@ static struct tvp514x_reg tvp514x_reg_list_default[] = { | |||
145 | {TOK_WRITE, REG_HUE, 0x00}, | 133 | {TOK_WRITE, REG_HUE, 0x00}, |
146 | {TOK_WRITE, REG_CHROMA_CONTROL1, 0x00}, | 134 | {TOK_WRITE, REG_CHROMA_CONTROL1, 0x00}, |
147 | {TOK_WRITE, REG_CHROMA_CONTROL2, 0x0E}, | 135 | {TOK_WRITE, REG_CHROMA_CONTROL2, 0x0E}, |
148 | {TOK_SKIP, 0x0F, 0x00}, /* Reserved */ | 136 | /* Reserved */ |
137 | {TOK_SKIP, 0x0F, 0x00}, | ||
149 | {TOK_WRITE, REG_COMP_PR_SATURATION, 0x80}, | 138 | {TOK_WRITE, REG_COMP_PR_SATURATION, 0x80}, |
150 | {TOK_WRITE, REG_COMP_Y_CONTRAST, 0x80}, | 139 | {TOK_WRITE, REG_COMP_Y_CONTRAST, 0x80}, |
151 | {TOK_WRITE, REG_COMP_PB_SATURATION, 0x80}, | 140 | {TOK_WRITE, REG_COMP_PB_SATURATION, 0x80}, |
152 | {TOK_SKIP, 0x13, 0x00}, /* Reserved */ | 141 | /* Reserved */ |
142 | {TOK_SKIP, 0x13, 0x00}, | ||
153 | {TOK_WRITE, REG_COMP_Y_BRIGHTNESS, 0x80}, | 143 | {TOK_WRITE, REG_COMP_Y_BRIGHTNESS, 0x80}, |
154 | {TOK_SKIP, 0x15, 0x00}, /* Reserved */ | 144 | /* Reserved */ |
155 | {TOK_SKIP, REG_AVID_START_PIXEL_LSB, 0x55}, /* NTSC timing */ | 145 | {TOK_SKIP, 0x15, 0x00}, |
146 | /* NTSC timing */ | ||
147 | {TOK_SKIP, REG_AVID_START_PIXEL_LSB, 0x55}, | ||
156 | {TOK_SKIP, REG_AVID_START_PIXEL_MSB, 0x00}, | 148 | {TOK_SKIP, REG_AVID_START_PIXEL_MSB, 0x00}, |
157 | {TOK_SKIP, REG_AVID_STOP_PIXEL_LSB, 0x25}, | 149 | {TOK_SKIP, REG_AVID_STOP_PIXEL_LSB, 0x25}, |
158 | {TOK_SKIP, REG_AVID_STOP_PIXEL_MSB, 0x03}, | 150 | {TOK_SKIP, REG_AVID_STOP_PIXEL_MSB, 0x03}, |
159 | {TOK_SKIP, REG_HSYNC_START_PIXEL_LSB, 0x00}, /* NTSC timing */ | 151 | /* NTSC timing */ |
152 | {TOK_SKIP, REG_HSYNC_START_PIXEL_LSB, 0x00}, | ||
160 | {TOK_SKIP, REG_HSYNC_START_PIXEL_MSB, 0x00}, | 153 | {TOK_SKIP, REG_HSYNC_START_PIXEL_MSB, 0x00}, |
161 | {TOK_SKIP, REG_HSYNC_STOP_PIXEL_LSB, 0x40}, | 154 | {TOK_SKIP, REG_HSYNC_STOP_PIXEL_LSB, 0x40}, |
162 | {TOK_SKIP, REG_HSYNC_STOP_PIXEL_MSB, 0x00}, | 155 | {TOK_SKIP, REG_HSYNC_STOP_PIXEL_MSB, 0x00}, |
163 | {TOK_SKIP, REG_VSYNC_START_LINE_LSB, 0x04}, /* NTSC timing */ | 156 | /* NTSC timing */ |
157 | {TOK_SKIP, REG_VSYNC_START_LINE_LSB, 0x04}, | ||
164 | {TOK_SKIP, REG_VSYNC_START_LINE_MSB, 0x00}, | 158 | {TOK_SKIP, REG_VSYNC_START_LINE_MSB, 0x00}, |
165 | {TOK_SKIP, REG_VSYNC_STOP_LINE_LSB, 0x07}, | 159 | {TOK_SKIP, REG_VSYNC_STOP_LINE_LSB, 0x07}, |
166 | {TOK_SKIP, REG_VSYNC_STOP_LINE_MSB, 0x00}, | 160 | {TOK_SKIP, REG_VSYNC_STOP_LINE_MSB, 0x00}, |
167 | {TOK_SKIP, REG_VBLK_START_LINE_LSB, 0x01}, /* NTSC timing */ | 161 | /* NTSC timing */ |
162 | {TOK_SKIP, REG_VBLK_START_LINE_LSB, 0x01}, | ||
168 | {TOK_SKIP, REG_VBLK_START_LINE_MSB, 0x00}, | 163 | {TOK_SKIP, REG_VBLK_START_LINE_MSB, 0x00}, |
169 | {TOK_SKIP, REG_VBLK_STOP_LINE_LSB, 0x15}, | 164 | {TOK_SKIP, REG_VBLK_STOP_LINE_LSB, 0x15}, |
170 | {TOK_SKIP, REG_VBLK_STOP_LINE_MSB, 0x00}, | 165 | {TOK_SKIP, REG_VBLK_STOP_LINE_MSB, 0x00}, |
171 | {TOK_SKIP, 0x26, 0x00}, /* Reserved */ | 166 | /* Reserved */ |
172 | {TOK_SKIP, 0x27, 0x00}, /* Reserved */ | 167 | {TOK_SKIP, 0x26, 0x00}, |
168 | /* Reserved */ | ||
169 | {TOK_SKIP, 0x27, 0x00}, | ||
173 | {TOK_SKIP, REG_FAST_SWTICH_CONTROL, 0xCC}, | 170 | {TOK_SKIP, REG_FAST_SWTICH_CONTROL, 0xCC}, |
174 | {TOK_SKIP, 0x29, 0x00}, /* Reserved */ | 171 | /* Reserved */ |
172 | {TOK_SKIP, 0x29, 0x00}, | ||
175 | {TOK_SKIP, REG_FAST_SWTICH_SCART_DELAY, 0x00}, | 173 | {TOK_SKIP, REG_FAST_SWTICH_SCART_DELAY, 0x00}, |
176 | {TOK_SKIP, 0x2B, 0x00}, /* Reserved */ | 174 | /* Reserved */ |
175 | {TOK_SKIP, 0x2B, 0x00}, | ||
177 | {TOK_SKIP, REG_SCART_DELAY, 0x00}, | 176 | {TOK_SKIP, REG_SCART_DELAY, 0x00}, |
178 | {TOK_SKIP, REG_CTI_DELAY, 0x00}, | 177 | {TOK_SKIP, REG_CTI_DELAY, 0x00}, |
179 | {TOK_SKIP, REG_CTI_CONTROL, 0x00}, | 178 | {TOK_SKIP, REG_CTI_CONTROL, 0x00}, |
180 | {TOK_SKIP, 0x2F, 0x00}, /* Reserved */ | 179 | /* Reserved */ |
181 | {TOK_SKIP, 0x30, 0x00}, /* Reserved */ | 180 | {TOK_SKIP, 0x2F, 0x00}, |
182 | {TOK_SKIP, 0x31, 0x00}, /* Reserved */ | 181 | /* Reserved */ |
183 | {TOK_WRITE, REG_SYNC_CONTROL, 0x00}, /* HS, VS active high */ | 182 | {TOK_SKIP, 0x30, 0x00}, |
184 | {TOK_WRITE, REG_OUTPUT_FORMATTER1, 0x00}, /* 10-bit BT.656 */ | 183 | /* Reserved */ |
185 | {TOK_WRITE, REG_OUTPUT_FORMATTER2, 0x11}, /* Enable clk & data */ | 184 | {TOK_SKIP, 0x31, 0x00}, |
186 | {TOK_WRITE, REG_OUTPUT_FORMATTER3, 0xEE}, /* Enable AVID & FLD */ | 185 | /* HS, VS active high */ |
187 | {TOK_WRITE, REG_OUTPUT_FORMATTER4, 0xAF}, /* Enable VS & HS */ | 186 | {TOK_WRITE, REG_SYNC_CONTROL, 0x00}, |
187 | /* 10-bit BT.656 */ | ||
188 | {TOK_WRITE, REG_OUTPUT_FORMATTER1, 0x00}, | ||
189 | /* Enable clk & data */ | ||
190 | {TOK_WRITE, REG_OUTPUT_FORMATTER2, 0x11}, | ||
191 | /* Enable AVID & FLD */ | ||
192 | {TOK_WRITE, REG_OUTPUT_FORMATTER3, 0xEE}, | ||
193 | /* Enable VS & HS */ | ||
194 | {TOK_WRITE, REG_OUTPUT_FORMATTER4, 0xAF}, | ||
188 | {TOK_WRITE, REG_OUTPUT_FORMATTER5, 0xFF}, | 195 | {TOK_WRITE, REG_OUTPUT_FORMATTER5, 0xFF}, |
189 | {TOK_WRITE, REG_OUTPUT_FORMATTER6, 0xFF}, | 196 | {TOK_WRITE, REG_OUTPUT_FORMATTER6, 0xFF}, |
190 | {TOK_WRITE, REG_CLEAR_LOST_LOCK, 0x01}, /* Clear status */ | 197 | /* Clear status */ |
198 | {TOK_WRITE, REG_CLEAR_LOST_LOCK, 0x01}, | ||
191 | {TOK_TERM, 0, 0}, | 199 | {TOK_TERM, 0, 0}, |
192 | }; | 200 | }; |
193 | 201 | ||
194 | /* List of image formats supported by TVP5146/47 decoder | 202 | /** |
203 | * List of image formats supported by TVP5146/47 decoder | ||
195 | * Currently we are using 8 bit mode only, but can be | 204 | * Currently we are using 8 bit mode only, but can be |
196 | * extended to 10/20 bit mode. | 205 | * extended to 10/20 bit mode. |
197 | */ | 206 | */ |
@@ -205,7 +214,7 @@ static const struct v4l2_fmtdesc tvp514x_fmt_list[] = { | |||
205 | }, | 214 | }, |
206 | }; | 215 | }; |
207 | 216 | ||
208 | /* | 217 | /** |
209 | * Supported standards - | 218 | * Supported standards - |
210 | * | 219 | * |
211 | * Currently supports two standards only, need to add support for rest of the | 220 | * Currently supports two standards only, need to add support for rest of the |
@@ -240,35 +249,32 @@ static struct tvp514x_std_info tvp514x_std_list[] = { | |||
240 | }, | 249 | }, |
241 | /* Standard: need to add for additional standard */ | 250 | /* Standard: need to add for additional standard */ |
242 | }; | 251 | }; |
243 | /* | ||
244 | * Control structure for Auto Gain | ||
245 | * This is temporary data, will get replaced once | ||
246 | * v4l2_ctrl_query_fill supports it. | ||
247 | */ | ||
248 | static const struct v4l2_queryctrl tvp514x_autogain_ctrl = { | ||
249 | .id = V4L2_CID_AUTOGAIN, | ||
250 | .name = "Gain, Automatic", | ||
251 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
252 | .minimum = 0, | ||
253 | .maximum = 1, | ||
254 | .step = 1, | ||
255 | .default_value = 1, | ||
256 | }; | ||
257 | 252 | ||
258 | /* | 253 | |
259 | * Read a value from a register in an TVP5146/47 decoder device. | 254 | static inline struct tvp514x_decoder *to_decoder(struct v4l2_subdev *sd) |
255 | { | ||
256 | return container_of(sd, struct tvp514x_decoder, sd); | ||
257 | } | ||
258 | |||
259 | |||
260 | /** | ||
261 | * tvp514x_read_reg() - Read a value from a register in an TVP5146/47. | ||
262 | * @sd: ptr to v4l2_subdev struct | ||
263 | * @reg: TVP5146/47 register address | ||
264 | * | ||
260 | * Returns value read if successful, or non-zero (-1) otherwise. | 265 | * Returns value read if successful, or non-zero (-1) otherwise. |
261 | */ | 266 | */ |
262 | static int tvp514x_read_reg(struct i2c_client *client, u8 reg) | 267 | static int tvp514x_read_reg(struct v4l2_subdev *sd, u8 reg) |
263 | { | 268 | { |
264 | int err; | 269 | int err, retry = 0; |
265 | int retry = 0; | 270 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
271 | |||
266 | read_again: | 272 | read_again: |
267 | 273 | ||
268 | err = i2c_smbus_read_byte_data(client, reg); | 274 | err = i2c_smbus_read_byte_data(client, reg); |
269 | if (err == -1) { | 275 | if (err == -1) { |
270 | if (retry <= I2C_RETRY_COUNT) { | 276 | if (retry <= I2C_RETRY_COUNT) { |
271 | v4l_warn(client, "Read: retry ... %d\n", retry); | 277 | v4l2_warn(sd, "Read: retry ... %d\n", retry); |
272 | retry++; | 278 | retry++; |
273 | msleep_interruptible(10); | 279 | msleep_interruptible(10); |
274 | goto read_again; | 280 | goto read_again; |
@@ -278,20 +284,39 @@ read_again: | |||
278 | return err; | 284 | return err; |
279 | } | 285 | } |
280 | 286 | ||
281 | /* | 287 | /** |
288 | * dump_reg() - dump the register content of TVP5146/47. | ||
289 | * @sd: ptr to v4l2_subdev struct | ||
290 | * @reg: TVP5146/47 register address | ||
291 | */ | ||
292 | static void dump_reg(struct v4l2_subdev *sd, u8 reg) | ||
293 | { | ||
294 | u32 val; | ||
295 | |||
296 | val = tvp514x_read_reg(sd, reg); | ||
297 | v4l2_info(sd, "Reg(0x%.2X): 0x%.2X\n", reg, val); | ||
298 | } | ||
299 | |||
300 | /** | ||
301 | * tvp514x_write_reg() - Write a value to a register in TVP5146/47 | ||
302 | * @sd: ptr to v4l2_subdev struct | ||
303 | * @reg: TVP5146/47 register address | ||
304 | * @val: value to be written to the register | ||
305 | * | ||
282 | * Write a value to a register in an TVP5146/47 decoder device. | 306 | * Write a value to a register in an TVP5146/47 decoder device. |
283 | * Returns zero if successful, or non-zero otherwise. | 307 | * Returns zero if successful, or non-zero otherwise. |
284 | */ | 308 | */ |
285 | static int tvp514x_write_reg(struct i2c_client *client, u8 reg, u8 val) | 309 | static int tvp514x_write_reg(struct v4l2_subdev *sd, u8 reg, u8 val) |
286 | { | 310 | { |
287 | int err; | 311 | int err, retry = 0; |
288 | int retry = 0; | 312 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
313 | |||
289 | write_again: | 314 | write_again: |
290 | 315 | ||
291 | err = i2c_smbus_write_byte_data(client, reg, val); | 316 | err = i2c_smbus_write_byte_data(client, reg, val); |
292 | if (err) { | 317 | if (err) { |
293 | if (retry <= I2C_RETRY_COUNT) { | 318 | if (retry <= I2C_RETRY_COUNT) { |
294 | v4l_warn(client, "Write: retry ... %d\n", retry); | 319 | v4l2_warn(sd, "Write: retry ... %d\n", retry); |
295 | retry++; | 320 | retry++; |
296 | msleep_interruptible(10); | 321 | msleep_interruptible(10); |
297 | goto write_again; | 322 | goto write_again; |
@@ -301,17 +326,19 @@ write_again: | |||
301 | return err; | 326 | return err; |
302 | } | 327 | } |
303 | 328 | ||
304 | /* | 329 | /** |
305 | * tvp514x_write_regs : Initializes a list of TVP5146/47 registers | 330 | * tvp514x_write_regs() : Initializes a list of TVP5146/47 registers |
331 | * @sd: ptr to v4l2_subdev struct | ||
332 | * @reglist: list of TVP5146/47 registers and values | ||
333 | * | ||
334 | * Initializes a list of TVP5146/47 registers:- | ||
306 | * if token is TOK_TERM, then entire write operation terminates | 335 | * if token is TOK_TERM, then entire write operation terminates |
307 | * if token is TOK_DELAY, then a delay of 'val' msec is introduced | 336 | * if token is TOK_DELAY, then a delay of 'val' msec is introduced |
308 | * if token is TOK_SKIP, then the register write is skipped | 337 | * if token is TOK_SKIP, then the register write is skipped |
309 | * if token is TOK_WRITE, then the register write is performed | 338 | * if token is TOK_WRITE, then the register write is performed |
310 | * | ||
311 | * reglist - list of registers to be written | ||
312 | * Returns zero if successful, or non-zero otherwise. | 339 | * Returns zero if successful, or non-zero otherwise. |
313 | */ | 340 | */ |
314 | static int tvp514x_write_regs(struct i2c_client *client, | 341 | static int tvp514x_write_regs(struct v4l2_subdev *sd, |
315 | const struct tvp514x_reg reglist[]) | 342 | const struct tvp514x_reg reglist[]) |
316 | { | 343 | { |
317 | int err; | 344 | int err; |
@@ -326,31 +353,33 @@ static int tvp514x_write_regs(struct i2c_client *client, | |||
326 | if (next->token == TOK_SKIP) | 353 | if (next->token == TOK_SKIP) |
327 | continue; | 354 | continue; |
328 | 355 | ||
329 | err = tvp514x_write_reg(client, next->reg, (u8) next->val); | 356 | err = tvp514x_write_reg(sd, next->reg, (u8) next->val); |
330 | if (err) { | 357 | if (err) { |
331 | v4l_err(client, "Write failed. Err[%d]\n", err); | 358 | v4l2_err(sd, "Write failed. Err[%d]\n", err); |
332 | return err; | 359 | return err; |
333 | } | 360 | } |
334 | } | 361 | } |
335 | return 0; | 362 | return 0; |
336 | } | 363 | } |
337 | 364 | ||
338 | /* | 365 | /** |
339 | * tvp514x_get_current_std: | 366 | * tvp514x_get_current_std() : Get the current standard detected by TVP5146/47 |
340 | * Returns the current standard detected by TVP5146/47 | 367 | * @sd: ptr to v4l2_subdev struct |
368 | * | ||
369 | * Get current standard detected by TVP5146/47, STD_INVALID if there is no | ||
370 | * standard detected. | ||
341 | */ | 371 | */ |
342 | static enum tvp514x_std tvp514x_get_current_std(struct tvp514x_decoder | 372 | static enum tvp514x_std tvp514x_get_current_std(struct v4l2_subdev *sd) |
343 | *decoder) | ||
344 | { | 373 | { |
345 | u8 std, std_status; | 374 | u8 std, std_status; |
346 | 375 | ||
347 | std = tvp514x_read_reg(decoder->client, REG_VIDEO_STD); | 376 | std = tvp514x_read_reg(sd, REG_VIDEO_STD); |
348 | if ((std & VIDEO_STD_MASK) == VIDEO_STD_AUTO_SWITCH_BIT) { | 377 | if ((std & VIDEO_STD_MASK) == VIDEO_STD_AUTO_SWITCH_BIT) |
349 | /* use the standard status register */ | 378 | /* use the standard status register */ |
350 | std_status = tvp514x_read_reg(decoder->client, | 379 | std_status = tvp514x_read_reg(sd, REG_VIDEO_STD_STATUS); |
351 | REG_VIDEO_STD_STATUS); | 380 | else |
352 | } else | 381 | /* use the standard register itself */ |
353 | std_status = std; /* use the standard register itself */ | 382 | std_status = std; |
354 | 383 | ||
355 | switch (std_status & VIDEO_STD_MASK) { | 384 | switch (std_status & VIDEO_STD_MASK) { |
356 | case VIDEO_STD_NTSC_MJ_BIT: | 385 | case VIDEO_STD_NTSC_MJ_BIT: |
@@ -366,94 +395,99 @@ static enum tvp514x_std tvp514x_get_current_std(struct tvp514x_decoder | |||
366 | return STD_INVALID; | 395 | return STD_INVALID; |
367 | } | 396 | } |
368 | 397 | ||
369 | /* | 398 | /* TVP5146/47 register dump function */ |
370 | * TVP5146/47 register dump function | 399 | static void tvp514x_reg_dump(struct v4l2_subdev *sd) |
371 | */ | ||
372 | static void tvp514x_reg_dump(struct tvp514x_decoder *decoder) | ||
373 | { | 400 | { |
374 | u8 value; | 401 | dump_reg(sd, REG_INPUT_SEL); |
375 | 402 | dump_reg(sd, REG_AFE_GAIN_CTRL); | |
376 | dump_reg(decoder->client, REG_INPUT_SEL, value); | 403 | dump_reg(sd, REG_VIDEO_STD); |
377 | dump_reg(decoder->client, REG_AFE_GAIN_CTRL, value); | 404 | dump_reg(sd, REG_OPERATION_MODE); |
378 | dump_reg(decoder->client, REG_VIDEO_STD, value); | 405 | dump_reg(sd, REG_COLOR_KILLER); |
379 | dump_reg(decoder->client, REG_OPERATION_MODE, value); | 406 | dump_reg(sd, REG_LUMA_CONTROL1); |
380 | dump_reg(decoder->client, REG_COLOR_KILLER, value); | 407 | dump_reg(sd, REG_LUMA_CONTROL2); |
381 | dump_reg(decoder->client, REG_LUMA_CONTROL1, value); | 408 | dump_reg(sd, REG_LUMA_CONTROL3); |
382 | dump_reg(decoder->client, REG_LUMA_CONTROL2, value); | 409 | dump_reg(sd, REG_BRIGHTNESS); |
383 | dump_reg(decoder->client, REG_LUMA_CONTROL3, value); | 410 | dump_reg(sd, REG_CONTRAST); |
384 | dump_reg(decoder->client, REG_BRIGHTNESS, value); | 411 | dump_reg(sd, REG_SATURATION); |
385 | dump_reg(decoder->client, REG_CONTRAST, value); | 412 | dump_reg(sd, REG_HUE); |
386 | dump_reg(decoder->client, REG_SATURATION, value); | 413 | dump_reg(sd, REG_CHROMA_CONTROL1); |
387 | dump_reg(decoder->client, REG_HUE, value); | 414 | dump_reg(sd, REG_CHROMA_CONTROL2); |
388 | dump_reg(decoder->client, REG_CHROMA_CONTROL1, value); | 415 | dump_reg(sd, REG_COMP_PR_SATURATION); |
389 | dump_reg(decoder->client, REG_CHROMA_CONTROL2, value); | 416 | dump_reg(sd, REG_COMP_Y_CONTRAST); |
390 | dump_reg(decoder->client, REG_COMP_PR_SATURATION, value); | 417 | dump_reg(sd, REG_COMP_PB_SATURATION); |
391 | dump_reg(decoder->client, REG_COMP_Y_CONTRAST, value); | 418 | dump_reg(sd, REG_COMP_Y_BRIGHTNESS); |
392 | dump_reg(decoder->client, REG_COMP_PB_SATURATION, value); | 419 | dump_reg(sd, REG_AVID_START_PIXEL_LSB); |
393 | dump_reg(decoder->client, REG_COMP_Y_BRIGHTNESS, value); | 420 | dump_reg(sd, REG_AVID_START_PIXEL_MSB); |
394 | dump_reg(decoder->client, REG_AVID_START_PIXEL_LSB, value); | 421 | dump_reg(sd, REG_AVID_STOP_PIXEL_LSB); |
395 | dump_reg(decoder->client, REG_AVID_START_PIXEL_MSB, value); | 422 | dump_reg(sd, REG_AVID_STOP_PIXEL_MSB); |
396 | dump_reg(decoder->client, REG_AVID_STOP_PIXEL_LSB, value); | 423 | dump_reg(sd, REG_HSYNC_START_PIXEL_LSB); |
397 | dump_reg(decoder->client, REG_AVID_STOP_PIXEL_MSB, value); | 424 | dump_reg(sd, REG_HSYNC_START_PIXEL_MSB); |
398 | dump_reg(decoder->client, REG_HSYNC_START_PIXEL_LSB, value); | 425 | dump_reg(sd, REG_HSYNC_STOP_PIXEL_LSB); |
399 | dump_reg(decoder->client, REG_HSYNC_START_PIXEL_MSB, value); | 426 | dump_reg(sd, REG_HSYNC_STOP_PIXEL_MSB); |
400 | dump_reg(decoder->client, REG_HSYNC_STOP_PIXEL_LSB, value); | 427 | dump_reg(sd, REG_VSYNC_START_LINE_LSB); |
401 | dump_reg(decoder->client, REG_HSYNC_STOP_PIXEL_MSB, value); | 428 | dump_reg(sd, REG_VSYNC_START_LINE_MSB); |
402 | dump_reg(decoder->client, REG_VSYNC_START_LINE_LSB, value); | 429 | dump_reg(sd, REG_VSYNC_STOP_LINE_LSB); |
403 | dump_reg(decoder->client, REG_VSYNC_START_LINE_MSB, value); | 430 | dump_reg(sd, REG_VSYNC_STOP_LINE_MSB); |
404 | dump_reg(decoder->client, REG_VSYNC_STOP_LINE_LSB, value); | 431 | dump_reg(sd, REG_VBLK_START_LINE_LSB); |
405 | dump_reg(decoder->client, REG_VSYNC_STOP_LINE_MSB, value); | 432 | dump_reg(sd, REG_VBLK_START_LINE_MSB); |
406 | dump_reg(decoder->client, REG_VBLK_START_LINE_LSB, value); | 433 | dump_reg(sd, REG_VBLK_STOP_LINE_LSB); |
407 | dump_reg(decoder->client, REG_VBLK_START_LINE_MSB, value); | 434 | dump_reg(sd, REG_VBLK_STOP_LINE_MSB); |
408 | dump_reg(decoder->client, REG_VBLK_STOP_LINE_LSB, value); | 435 | dump_reg(sd, REG_SYNC_CONTROL); |
409 | dump_reg(decoder->client, REG_VBLK_STOP_LINE_MSB, value); | 436 | dump_reg(sd, REG_OUTPUT_FORMATTER1); |
410 | dump_reg(decoder->client, REG_SYNC_CONTROL, value); | 437 | dump_reg(sd, REG_OUTPUT_FORMATTER2); |
411 | dump_reg(decoder->client, REG_OUTPUT_FORMATTER1, value); | 438 | dump_reg(sd, REG_OUTPUT_FORMATTER3); |
412 | dump_reg(decoder->client, REG_OUTPUT_FORMATTER2, value); | 439 | dump_reg(sd, REG_OUTPUT_FORMATTER4); |
413 | dump_reg(decoder->client, REG_OUTPUT_FORMATTER3, value); | 440 | dump_reg(sd, REG_OUTPUT_FORMATTER5); |
414 | dump_reg(decoder->client, REG_OUTPUT_FORMATTER4, value); | 441 | dump_reg(sd, REG_OUTPUT_FORMATTER6); |
415 | dump_reg(decoder->client, REG_OUTPUT_FORMATTER5, value); | 442 | dump_reg(sd, REG_CLEAR_LOST_LOCK); |
416 | dump_reg(decoder->client, REG_OUTPUT_FORMATTER6, value); | ||
417 | dump_reg(decoder->client, REG_CLEAR_LOST_LOCK, value); | ||
418 | } | 443 | } |
419 | 444 | ||
420 | /* | 445 | /** |
421 | * Configure the TVP5146/47 with the current register settings | 446 | * tvp514x_configure() - Configure the TVP5146/47 registers |
447 | * @sd: ptr to v4l2_subdev struct | ||
448 | * @decoder: ptr to tvp514x_decoder structure | ||
449 | * | ||
422 | * Returns zero if successful, or non-zero otherwise. | 450 | * Returns zero if successful, or non-zero otherwise. |
423 | */ | 451 | */ |
424 | static int tvp514x_configure(struct tvp514x_decoder *decoder) | 452 | static int tvp514x_configure(struct v4l2_subdev *sd, |
453 | struct tvp514x_decoder *decoder) | ||
425 | { | 454 | { |
426 | int err; | 455 | int err; |
427 | 456 | ||
428 | /* common register initialization */ | 457 | /* common register initialization */ |
429 | err = | 458 | err = |
430 | tvp514x_write_regs(decoder->client, decoder->tvp514x_regs); | 459 | tvp514x_write_regs(sd, decoder->tvp514x_regs); |
431 | if (err) | 460 | if (err) |
432 | return err; | 461 | return err; |
433 | 462 | ||
434 | if (debug) | 463 | if (debug) |
435 | tvp514x_reg_dump(decoder); | 464 | tvp514x_reg_dump(sd); |
436 | 465 | ||
437 | return 0; | 466 | return 0; |
438 | } | 467 | } |
439 | 468 | ||
440 | /* | 469 | /** |
441 | * Detect if an tvp514x is present, and if so which revision. | 470 | * tvp514x_detect() - Detect if an tvp514x is present, and if so which revision. |
471 | * @sd: pointer to standard V4L2 sub-device structure | ||
472 | * @decoder: pointer to tvp514x_decoder structure | ||
473 | * | ||
442 | * A device is considered to be detected if the chip ID (LSB and MSB) | 474 | * A device is considered to be detected if the chip ID (LSB and MSB) |
443 | * registers match the expected values. | 475 | * registers match the expected values. |
444 | * Any value of the rom version register is accepted. | 476 | * Any value of the rom version register is accepted. |
445 | * Returns ENODEV error number if no device is detected, or zero | 477 | * Returns ENODEV error number if no device is detected, or zero |
446 | * if a device is detected. | 478 | * if a device is detected. |
447 | */ | 479 | */ |
448 | static int tvp514x_detect(struct tvp514x_decoder *decoder) | 480 | static int tvp514x_detect(struct v4l2_subdev *sd, |
481 | struct tvp514x_decoder *decoder) | ||
449 | { | 482 | { |
450 | u8 chip_id_msb, chip_id_lsb, rom_ver; | 483 | u8 chip_id_msb, chip_id_lsb, rom_ver; |
484 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
451 | 485 | ||
452 | chip_id_msb = tvp514x_read_reg(decoder->client, REG_CHIP_ID_MSB); | 486 | chip_id_msb = tvp514x_read_reg(sd, REG_CHIP_ID_MSB); |
453 | chip_id_lsb = tvp514x_read_reg(decoder->client, REG_CHIP_ID_LSB); | 487 | chip_id_lsb = tvp514x_read_reg(sd, REG_CHIP_ID_LSB); |
454 | rom_ver = tvp514x_read_reg(decoder->client, REG_ROM_VERSION); | 488 | rom_ver = tvp514x_read_reg(sd, REG_ROM_VERSION); |
455 | 489 | ||
456 | v4l_dbg(1, debug, decoder->client, | 490 | v4l2_dbg(1, debug, sd, |
457 | "chip id detected msb:0x%x lsb:0x%x rom version:0x%x\n", | 491 | "chip id detected msb:0x%x lsb:0x%x rom version:0x%x\n", |
458 | chip_id_msb, chip_id_lsb, rom_ver); | 492 | chip_id_msb, chip_id_lsb, rom_ver); |
459 | if ((chip_id_msb != TVP514X_CHIP_ID_MSB) | 493 | if ((chip_id_msb != TVP514X_CHIP_ID_MSB) |
@@ -462,38 +496,30 @@ static int tvp514x_detect(struct tvp514x_decoder *decoder) | |||
462 | /* We didn't read the values we expected, so this must not be | 496 | /* We didn't read the values we expected, so this must not be |
463 | * an TVP5146/47. | 497 | * an TVP5146/47. |
464 | */ | 498 | */ |
465 | v4l_err(decoder->client, | 499 | v4l2_err(sd, "chip id mismatch msb:0x%x lsb:0x%x\n", |
466 | "chip id mismatch msb:0x%x lsb:0x%x\n", | 500 | chip_id_msb, chip_id_lsb); |
467 | chip_id_msb, chip_id_lsb); | ||
468 | return -ENODEV; | 501 | return -ENODEV; |
469 | } | 502 | } |
470 | 503 | ||
471 | decoder->ver = rom_ver; | 504 | decoder->ver = rom_ver; |
472 | decoder->state = STATE_DETECTED; | ||
473 | 505 | ||
474 | v4l_info(decoder->client, | 506 | v4l2_info(sd, "%s (Version - 0x%.2x) found at 0x%x (%s)\n", |
475 | "%s found at 0x%x (%s)\n", decoder->client->name, | 507 | client->name, decoder->ver, |
476 | decoder->client->addr << 1, | 508 | client->addr << 1, client->adapter->name); |
477 | decoder->client->adapter->name); | ||
478 | return 0; | 509 | return 0; |
479 | } | 510 | } |
480 | 511 | ||
481 | /* | ||
482 | * Following are decoder interface functions implemented by | ||
483 | * TVP5146/47 decoder driver. | ||
484 | */ | ||
485 | |||
486 | /** | 512 | /** |
487 | * ioctl_querystd - V4L2 decoder interface handler for VIDIOC_QUERYSTD ioctl | 513 | * tvp514x_querystd() - V4L2 decoder interface handler for querystd |
488 | * @s: pointer to standard V4L2 device structure | 514 | * @sd: pointer to standard V4L2 sub-device structure |
489 | * @std_id: standard V4L2 std_id ioctl enum | 515 | * @std_id: standard V4L2 std_id ioctl enum |
490 | * | 516 | * |
491 | * Returns the current standard detected by TVP5146/47. If no active input is | 517 | * Returns the current standard detected by TVP5146/47. If no active input is |
492 | * detected, returns -EINVAL | 518 | * detected, returns -EINVAL |
493 | */ | 519 | */ |
494 | static int ioctl_querystd(struct v4l2_int_device *s, v4l2_std_id *std_id) | 520 | static int tvp514x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std_id) |
495 | { | 521 | { |
496 | struct tvp514x_decoder *decoder = s->priv; | 522 | struct tvp514x_decoder *decoder = to_decoder(sd); |
497 | enum tvp514x_std current_std; | 523 | enum tvp514x_std current_std; |
498 | enum tvp514x_input input_sel; | 524 | enum tvp514x_input input_sel; |
499 | u8 sync_lock_status, lock_mask; | 525 | u8 sync_lock_status, lock_mask; |
@@ -502,11 +528,11 @@ static int ioctl_querystd(struct v4l2_int_device *s, v4l2_std_id *std_id) | |||
502 | return -EINVAL; | 528 | return -EINVAL; |
503 | 529 | ||
504 | /* get the current standard */ | 530 | /* get the current standard */ |
505 | current_std = tvp514x_get_current_std(decoder); | 531 | current_std = tvp514x_get_current_std(sd); |
506 | if (current_std == STD_INVALID) | 532 | if (current_std == STD_INVALID) |
507 | return -EINVAL; | 533 | return -EINVAL; |
508 | 534 | ||
509 | input_sel = decoder->route.input; | 535 | input_sel = decoder->input; |
510 | 536 | ||
511 | switch (input_sel) { | 537 | switch (input_sel) { |
512 | case INPUT_CVBS_VI1A: | 538 | case INPUT_CVBS_VI1A: |
@@ -544,42 +570,39 @@ static int ioctl_querystd(struct v4l2_int_device *s, v4l2_std_id *std_id) | |||
544 | return -EINVAL; | 570 | return -EINVAL; |
545 | } | 571 | } |
546 | /* check whether signal is locked */ | 572 | /* check whether signal is locked */ |
547 | sync_lock_status = tvp514x_read_reg(decoder->client, REG_STATUS1); | 573 | sync_lock_status = tvp514x_read_reg(sd, REG_STATUS1); |
548 | if (lock_mask != (sync_lock_status & lock_mask)) | 574 | if (lock_mask != (sync_lock_status & lock_mask)) |
549 | return -EINVAL; /* No input detected */ | 575 | return -EINVAL; /* No input detected */ |
550 | 576 | ||
551 | decoder->current_std = current_std; | 577 | decoder->current_std = current_std; |
552 | *std_id = decoder->std_list[current_std].standard.id; | 578 | *std_id = decoder->std_list[current_std].standard.id; |
553 | 579 | ||
554 | v4l_dbg(1, debug, decoder->client, "Current STD: %s", | 580 | v4l2_dbg(1, debug, sd, "Current STD: %s", |
555 | decoder->std_list[current_std].standard.name); | 581 | decoder->std_list[current_std].standard.name); |
556 | return 0; | 582 | return 0; |
557 | } | 583 | } |
558 | 584 | ||
559 | /** | 585 | /** |
560 | * ioctl_s_std - V4L2 decoder interface handler for VIDIOC_S_STD ioctl | 586 | * tvp514x_s_std() - V4L2 decoder interface handler for s_std |
561 | * @s: pointer to standard V4L2 device structure | 587 | * @sd: pointer to standard V4L2 sub-device structure |
562 | * @std_id: standard V4L2 v4l2_std_id ioctl enum | 588 | * @std_id: standard V4L2 v4l2_std_id ioctl enum |
563 | * | 589 | * |
564 | * If std_id is supported, sets the requested standard. Otherwise, returns | 590 | * If std_id is supported, sets the requested standard. Otherwise, returns |
565 | * -EINVAL | 591 | * -EINVAL |
566 | */ | 592 | */ |
567 | static int ioctl_s_std(struct v4l2_int_device *s, v4l2_std_id *std_id) | 593 | static int tvp514x_s_std(struct v4l2_subdev *sd, v4l2_std_id std_id) |
568 | { | 594 | { |
569 | struct tvp514x_decoder *decoder = s->priv; | 595 | struct tvp514x_decoder *decoder = to_decoder(sd); |
570 | int err, i; | 596 | int err, i; |
571 | 597 | ||
572 | if (std_id == NULL) | ||
573 | return -EINVAL; | ||
574 | |||
575 | for (i = 0; i < decoder->num_stds; i++) | 598 | for (i = 0; i < decoder->num_stds; i++) |
576 | if (*std_id & decoder->std_list[i].standard.id) | 599 | if (std_id & decoder->std_list[i].standard.id) |
577 | break; | 600 | break; |
578 | 601 | ||
579 | if ((i == decoder->num_stds) || (i == STD_INVALID)) | 602 | if ((i == decoder->num_stds) || (i == STD_INVALID)) |
580 | return -EINVAL; | 603 | return -EINVAL; |
581 | 604 | ||
582 | err = tvp514x_write_reg(decoder->client, REG_VIDEO_STD, | 605 | err = tvp514x_write_reg(sd, REG_VIDEO_STD, |
583 | decoder->std_list[i].video_std); | 606 | decoder->std_list[i].video_std); |
584 | if (err) | 607 | if (err) |
585 | return err; | 608 | return err; |
@@ -588,24 +611,26 @@ static int ioctl_s_std(struct v4l2_int_device *s, v4l2_std_id *std_id) | |||
588 | decoder->tvp514x_regs[REG_VIDEO_STD].val = | 611 | decoder->tvp514x_regs[REG_VIDEO_STD].val = |
589 | decoder->std_list[i].video_std; | 612 | decoder->std_list[i].video_std; |
590 | 613 | ||
591 | v4l_dbg(1, debug, decoder->client, "Standard set to: %s", | 614 | v4l2_dbg(1, debug, sd, "Standard set to: %s", |
592 | decoder->std_list[i].standard.name); | 615 | decoder->std_list[i].standard.name); |
593 | return 0; | 616 | return 0; |
594 | } | 617 | } |
595 | 618 | ||
596 | /** | 619 | /** |
597 | * ioctl_s_routing - V4L2 decoder interface handler for VIDIOC_S_INPUT ioctl | 620 | * tvp514x_s_routing() - V4L2 decoder interface handler for s_routing |
598 | * @s: pointer to standard V4L2 device structure | 621 | * @sd: pointer to standard V4L2 sub-device structure |
599 | * @index: number of the input | 622 | * @input: input selector for routing the signal |
623 | * @output: output selector for routing the signal | ||
624 | * @config: config value. Not used | ||
600 | * | 625 | * |
601 | * If index is valid, selects the requested input. Otherwise, returns -EINVAL if | 626 | * If index is valid, selects the requested input. Otherwise, returns -EINVAL if |
602 | * the input is not supported or there is no active signal present in the | 627 | * the input is not supported or there is no active signal present in the |
603 | * selected input. | 628 | * selected input. |
604 | */ | 629 | */ |
605 | static int ioctl_s_routing(struct v4l2_int_device *s, | 630 | static int tvp514x_s_routing(struct v4l2_subdev *sd, |
606 | struct v4l2_routing *route) | 631 | u32 input, u32 output, u32 config) |
607 | { | 632 | { |
608 | struct tvp514x_decoder *decoder = s->priv; | 633 | struct tvp514x_decoder *decoder = to_decoder(sd); |
609 | int err; | 634 | int err; |
610 | enum tvp514x_input input_sel; | 635 | enum tvp514x_input input_sel; |
611 | enum tvp514x_output output_sel; | 636 | enum tvp514x_output output_sel; |
@@ -613,20 +638,21 @@ static int ioctl_s_routing(struct v4l2_int_device *s, | |||
613 | u8 sync_lock_status, lock_mask; | 638 | u8 sync_lock_status, lock_mask; |
614 | int try_count = LOCK_RETRY_COUNT; | 639 | int try_count = LOCK_RETRY_COUNT; |
615 | 640 | ||
616 | if ((!route) || (route->input >= INPUT_INVALID) || | 641 | if ((input >= INPUT_INVALID) || |
617 | (route->output >= OUTPUT_INVALID)) | 642 | (output >= OUTPUT_INVALID)) |
618 | return -EINVAL; /* Index out of bound */ | 643 | /* Index out of bound */ |
644 | return -EINVAL; | ||
619 | 645 | ||
620 | input_sel = route->input; | 646 | input_sel = input; |
621 | output_sel = route->output; | 647 | output_sel = output; |
622 | 648 | ||
623 | err = tvp514x_write_reg(decoder->client, REG_INPUT_SEL, input_sel); | 649 | err = tvp514x_write_reg(sd, REG_INPUT_SEL, input_sel); |
624 | if (err) | 650 | if (err) |
625 | return err; | 651 | return err; |
626 | 652 | ||
627 | output_sel |= tvp514x_read_reg(decoder->client, | 653 | output_sel |= tvp514x_read_reg(sd, |
628 | REG_OUTPUT_FORMATTER1) & 0x7; | 654 | REG_OUTPUT_FORMATTER1) & 0x7; |
629 | err = tvp514x_write_reg(decoder->client, REG_OUTPUT_FORMATTER1, | 655 | err = tvp514x_write_reg(sd, REG_OUTPUT_FORMATTER1, |
630 | output_sel); | 656 | output_sel); |
631 | if (err) | 657 | if (err) |
632 | return err; | 658 | return err; |
@@ -637,7 +663,7 @@ static int ioctl_s_routing(struct v4l2_int_device *s, | |||
637 | /* Clear status */ | 663 | /* Clear status */ |
638 | msleep(LOCK_RETRY_DELAY); | 664 | msleep(LOCK_RETRY_DELAY); |
639 | err = | 665 | err = |
640 | tvp514x_write_reg(decoder->client, REG_CLEAR_LOST_LOCK, 0x01); | 666 | tvp514x_write_reg(sd, REG_CLEAR_LOST_LOCK, 0x01); |
641 | if (err) | 667 | if (err) |
642 | return err; | 668 | return err; |
643 | 669 | ||
@@ -672,7 +698,7 @@ static int ioctl_s_routing(struct v4l2_int_device *s, | |||
672 | lock_mask = STATUS_HORZ_SYNC_LOCK_BIT | | 698 | lock_mask = STATUS_HORZ_SYNC_LOCK_BIT | |
673 | STATUS_VIRT_SYNC_LOCK_BIT; | 699 | STATUS_VIRT_SYNC_LOCK_BIT; |
674 | break; | 700 | break; |
675 | /*Need to add other interfaces*/ | 701 | /* Need to add other interfaces*/ |
676 | default: | 702 | default: |
677 | return -EINVAL; | 703 | return -EINVAL; |
678 | } | 704 | } |
@@ -682,42 +708,41 @@ static int ioctl_s_routing(struct v4l2_int_device *s, | |||
682 | msleep(LOCK_RETRY_DELAY); | 708 | msleep(LOCK_RETRY_DELAY); |
683 | 709 | ||
684 | /* get the current standard for future reference */ | 710 | /* get the current standard for future reference */ |
685 | current_std = tvp514x_get_current_std(decoder); | 711 | current_std = tvp514x_get_current_std(sd); |
686 | if (current_std == STD_INVALID) | 712 | if (current_std == STD_INVALID) |
687 | continue; | 713 | continue; |
688 | 714 | ||
689 | sync_lock_status = tvp514x_read_reg(decoder->client, | 715 | sync_lock_status = tvp514x_read_reg(sd, |
690 | REG_STATUS1); | 716 | REG_STATUS1); |
691 | if (lock_mask == (sync_lock_status & lock_mask)) | 717 | if (lock_mask == (sync_lock_status & lock_mask)) |
692 | break; /* Input detected */ | 718 | /* Input detected */ |
719 | break; | ||
693 | } | 720 | } |
694 | 721 | ||
695 | if ((current_std == STD_INVALID) || (try_count < 0)) | 722 | if ((current_std == STD_INVALID) || (try_count < 0)) |
696 | return -EINVAL; | 723 | return -EINVAL; |
697 | 724 | ||
698 | decoder->current_std = current_std; | 725 | decoder->current_std = current_std; |
699 | decoder->route.input = route->input; | 726 | decoder->input = input; |
700 | decoder->route.output = route->output; | 727 | decoder->output = output; |
701 | 728 | ||
702 | v4l_dbg(1, debug, decoder->client, | 729 | v4l2_dbg(1, debug, sd, "Input set to: %d, std : %d", |
703 | "Input set to: %d, std : %d", | ||
704 | input_sel, current_std); | 730 | input_sel, current_std); |
705 | 731 | ||
706 | return 0; | 732 | return 0; |
707 | } | 733 | } |
708 | 734 | ||
709 | /** | 735 | /** |
710 | * ioctl_queryctrl - V4L2 decoder interface handler for VIDIOC_QUERYCTRL ioctl | 736 | * tvp514x_queryctrl() - V4L2 decoder interface handler for queryctrl |
711 | * @s: pointer to standard V4L2 device structure | 737 | * @sd: pointer to standard V4L2 sub-device structure |
712 | * @qctrl: standard V4L2 v4l2_queryctrl structure | 738 | * @qctrl: standard V4L2 v4l2_queryctrl structure |
713 | * | 739 | * |
714 | * If the requested control is supported, returns the control information. | 740 | * If the requested control is supported, returns the control information. |
715 | * Otherwise, returns -EINVAL if the control is not supported. | 741 | * Otherwise, returns -EINVAL if the control is not supported. |
716 | */ | 742 | */ |
717 | static int | 743 | static int |
718 | ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qctrl) | 744 | tvp514x_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl) |
719 | { | 745 | { |
720 | struct tvp514x_decoder *decoder = s->priv; | ||
721 | int err = -EINVAL; | 746 | int err = -EINVAL; |
722 | 747 | ||
723 | if (qctrl == NULL) | 748 | if (qctrl == NULL) |
@@ -725,13 +750,13 @@ ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qctrl) | |||
725 | 750 | ||
726 | switch (qctrl->id) { | 751 | switch (qctrl->id) { |
727 | case V4L2_CID_BRIGHTNESS: | 752 | case V4L2_CID_BRIGHTNESS: |
728 | /* Brightness supported is (0-255), | 753 | /* Brightness supported is (0-255), */ |
729 | */ | ||
730 | err = v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128); | 754 | err = v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128); |
731 | break; | 755 | break; |
732 | case V4L2_CID_CONTRAST: | 756 | case V4L2_CID_CONTRAST: |
733 | case V4L2_CID_SATURATION: | 757 | case V4L2_CID_SATURATION: |
734 | /* Saturation and Contrast supported is - | 758 | /** |
759 | * Saturation and Contrast supported is - | ||
735 | * Contrast: 0 - 255 (Default - 128) | 760 | * Contrast: 0 - 255 (Default - 128) |
736 | * Saturation: 0 - 255 (Default - 128) | 761 | * Saturation: 0 - 255 (Default - 128) |
737 | */ | 762 | */ |
@@ -744,30 +769,27 @@ ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qctrl) | |||
744 | err = v4l2_ctrl_query_fill(qctrl, -180, 180, 180, 0); | 769 | err = v4l2_ctrl_query_fill(qctrl, -180, 180, 180, 0); |
745 | break; | 770 | break; |
746 | case V4L2_CID_AUTOGAIN: | 771 | case V4L2_CID_AUTOGAIN: |
747 | /* Autogain is either 0 or 1*/ | 772 | /** |
748 | memcpy(qctrl, &tvp514x_autogain_ctrl, | 773 | * Auto Gain supported is - |
749 | sizeof(struct v4l2_queryctrl)); | 774 | * 0 - 1 (Default - 1) |
750 | err = 0; | 775 | */ |
776 | err = v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1); | ||
751 | break; | 777 | break; |
752 | default: | 778 | default: |
753 | v4l_err(decoder->client, | 779 | v4l2_err(sd, "invalid control id %d\n", qctrl->id); |
754 | "invalid control id %d\n", qctrl->id); | ||
755 | return err; | 780 | return err; |
756 | } | 781 | } |
757 | 782 | ||
758 | v4l_dbg(1, debug, decoder->client, | 783 | v4l2_dbg(1, debug, sd, "Query Control:%s: Min - %d, Max - %d, Def - %d", |
759 | "Query Control: %s : Min - %d, Max - %d, Def - %d", | 784 | qctrl->name, qctrl->minimum, qctrl->maximum, |
760 | qctrl->name, | ||
761 | qctrl->minimum, | ||
762 | qctrl->maximum, | ||
763 | qctrl->default_value); | 785 | qctrl->default_value); |
764 | 786 | ||
765 | return err; | 787 | return err; |
766 | } | 788 | } |
767 | 789 | ||
768 | /** | 790 | /** |
769 | * ioctl_g_ctrl - V4L2 decoder interface handler for VIDIOC_G_CTRL ioctl | 791 | * tvp514x_g_ctrl() - V4L2 decoder interface handler for g_ctrl |
770 | * @s: pointer to standard V4L2 device structure | 792 | * @sd: pointer to standard V4L2 sub-device structure |
771 | * @ctrl: pointer to v4l2_control structure | 793 | * @ctrl: pointer to v4l2_control structure |
772 | * | 794 | * |
773 | * If the requested control is supported, returns the control's current | 795 | * If the requested control is supported, returns the control's current |
@@ -775,9 +797,9 @@ ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qctrl) | |||
775 | * supported. | 797 | * supported. |
776 | */ | 798 | */ |
777 | static int | 799 | static int |
778 | ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) | 800 | tvp514x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
779 | { | 801 | { |
780 | struct tvp514x_decoder *decoder = s->priv; | 802 | struct tvp514x_decoder *decoder = to_decoder(sd); |
781 | 803 | ||
782 | if (ctrl == NULL) | 804 | if (ctrl == NULL) |
783 | return -EINVAL; | 805 | return -EINVAL; |
@@ -811,74 +833,70 @@ ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) | |||
811 | 833 | ||
812 | break; | 834 | break; |
813 | default: | 835 | default: |
814 | v4l_err(decoder->client, | 836 | v4l2_err(sd, "invalid control id %d\n", ctrl->id); |
815 | "invalid control id %d\n", ctrl->id); | ||
816 | return -EINVAL; | 837 | return -EINVAL; |
817 | } | 838 | } |
818 | 839 | ||
819 | v4l_dbg(1, debug, decoder->client, | 840 | v4l2_dbg(1, debug, sd, "Get Control: ID - %d - %d", |
820 | "Get Control: ID - %d - %d", | ||
821 | ctrl->id, ctrl->value); | 841 | ctrl->id, ctrl->value); |
822 | return 0; | 842 | return 0; |
823 | } | 843 | } |
824 | 844 | ||
825 | /** | 845 | /** |
826 | * ioctl_s_ctrl - V4L2 decoder interface handler for VIDIOC_S_CTRL ioctl | 846 | * tvp514x_s_ctrl() - V4L2 decoder interface handler for s_ctrl |
827 | * @s: pointer to standard V4L2 device structure | 847 | * @sd: pointer to standard V4L2 sub-device structure |
828 | * @ctrl: pointer to v4l2_control structure | 848 | * @ctrl: pointer to v4l2_control structure |
829 | * | 849 | * |
830 | * If the requested control is supported, sets the control's current | 850 | * If the requested control is supported, sets the control's current |
831 | * value in HW. Otherwise, returns -EINVAL if the control is not supported. | 851 | * value in HW. Otherwise, returns -EINVAL if the control is not supported. |
832 | */ | 852 | */ |
833 | static int | 853 | static int |
834 | ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) | 854 | tvp514x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
835 | { | 855 | { |
836 | struct tvp514x_decoder *decoder = s->priv; | 856 | struct tvp514x_decoder *decoder = to_decoder(sd); |
837 | int err = -EINVAL, value; | 857 | int err = -EINVAL, value; |
838 | 858 | ||
839 | if (ctrl == NULL) | 859 | if (ctrl == NULL) |
840 | return err; | 860 | return err; |
841 | 861 | ||
842 | value = (__s32) ctrl->value; | 862 | value = ctrl->value; |
843 | 863 | ||
844 | switch (ctrl->id) { | 864 | switch (ctrl->id) { |
845 | case V4L2_CID_BRIGHTNESS: | 865 | case V4L2_CID_BRIGHTNESS: |
846 | if (ctrl->value < 0 || ctrl->value > 255) { | 866 | if (ctrl->value < 0 || ctrl->value > 255) { |
847 | v4l_err(decoder->client, | 867 | v4l2_err(sd, "invalid brightness setting %d\n", |
848 | "invalid brightness setting %d\n", | ||
849 | ctrl->value); | 868 | ctrl->value); |
850 | return -ERANGE; | 869 | return -ERANGE; |
851 | } | 870 | } |
852 | err = tvp514x_write_reg(decoder->client, REG_BRIGHTNESS, | 871 | err = tvp514x_write_reg(sd, REG_BRIGHTNESS, |
853 | value); | 872 | value); |
854 | if (err) | 873 | if (err) |
855 | return err; | 874 | return err; |
875 | |||
856 | decoder->tvp514x_regs[REG_BRIGHTNESS].val = value; | 876 | decoder->tvp514x_regs[REG_BRIGHTNESS].val = value; |
857 | break; | 877 | break; |
858 | case V4L2_CID_CONTRAST: | 878 | case V4L2_CID_CONTRAST: |
859 | if (ctrl->value < 0 || ctrl->value > 255) { | 879 | if (ctrl->value < 0 || ctrl->value > 255) { |
860 | v4l_err(decoder->client, | 880 | v4l2_err(sd, "invalid contrast setting %d\n", |
861 | "invalid contrast setting %d\n", | ||
862 | ctrl->value); | 881 | ctrl->value); |
863 | return -ERANGE; | 882 | return -ERANGE; |
864 | } | 883 | } |
865 | err = tvp514x_write_reg(decoder->client, REG_CONTRAST, | 884 | err = tvp514x_write_reg(sd, REG_CONTRAST, value); |
866 | value); | ||
867 | if (err) | 885 | if (err) |
868 | return err; | 886 | return err; |
887 | |||
869 | decoder->tvp514x_regs[REG_CONTRAST].val = value; | 888 | decoder->tvp514x_regs[REG_CONTRAST].val = value; |
870 | break; | 889 | break; |
871 | case V4L2_CID_SATURATION: | 890 | case V4L2_CID_SATURATION: |
872 | if (ctrl->value < 0 || ctrl->value > 255) { | 891 | if (ctrl->value < 0 || ctrl->value > 255) { |
873 | v4l_err(decoder->client, | 892 | v4l2_err(sd, "invalid saturation setting %d\n", |
874 | "invalid saturation setting %d\n", | ||
875 | ctrl->value); | 893 | ctrl->value); |
876 | return -ERANGE; | 894 | return -ERANGE; |
877 | } | 895 | } |
878 | err = tvp514x_write_reg(decoder->client, REG_SATURATION, | 896 | err = tvp514x_write_reg(sd, REG_SATURATION, value); |
879 | value); | ||
880 | if (err) | 897 | if (err) |
881 | return err; | 898 | return err; |
899 | |||
882 | decoder->tvp514x_regs[REG_SATURATION].val = value; | 900 | decoder->tvp514x_regs[REG_SATURATION].val = value; |
883 | break; | 901 | break; |
884 | case V4L2_CID_HUE: | 902 | case V4L2_CID_HUE: |
@@ -889,15 +907,13 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) | |||
889 | else if (value == 0) | 907 | else if (value == 0) |
890 | value = 0; | 908 | value = 0; |
891 | else { | 909 | else { |
892 | v4l_err(decoder->client, | 910 | v4l2_err(sd, "invalid hue setting %d\n", ctrl->value); |
893 | "invalid hue setting %d\n", | ||
894 | ctrl->value); | ||
895 | return -ERANGE; | 911 | return -ERANGE; |
896 | } | 912 | } |
897 | err = tvp514x_write_reg(decoder->client, REG_HUE, | 913 | err = tvp514x_write_reg(sd, REG_HUE, value); |
898 | value); | ||
899 | if (err) | 914 | if (err) |
900 | return err; | 915 | return err; |
916 | |||
901 | decoder->tvp514x_regs[REG_HUE].val = value; | 917 | decoder->tvp514x_regs[REG_HUE].val = value; |
902 | break; | 918 | break; |
903 | case V4L2_CID_AUTOGAIN: | 919 | case V4L2_CID_AUTOGAIN: |
@@ -906,41 +922,38 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) | |||
906 | else if (value == 0) | 922 | else if (value == 0) |
907 | value = 0x0C; | 923 | value = 0x0C; |
908 | else { | 924 | else { |
909 | v4l_err(decoder->client, | 925 | v4l2_err(sd, "invalid auto gain setting %d\n", |
910 | "invalid auto gain setting %d\n", | ||
911 | ctrl->value); | 926 | ctrl->value); |
912 | return -ERANGE; | 927 | return -ERANGE; |
913 | } | 928 | } |
914 | err = tvp514x_write_reg(decoder->client, REG_AFE_GAIN_CTRL, | 929 | err = tvp514x_write_reg(sd, REG_AFE_GAIN_CTRL, value); |
915 | value); | ||
916 | if (err) | 930 | if (err) |
917 | return err; | 931 | return err; |
932 | |||
918 | decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val = value; | 933 | decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val = value; |
919 | break; | 934 | break; |
920 | default: | 935 | default: |
921 | v4l_err(decoder->client, | 936 | v4l2_err(sd, "invalid control id %d\n", ctrl->id); |
922 | "invalid control id %d\n", ctrl->id); | ||
923 | return err; | 937 | return err; |
924 | } | 938 | } |
925 | 939 | ||
926 | v4l_dbg(1, debug, decoder->client, | 940 | v4l2_dbg(1, debug, sd, "Set Control: ID - %d - %d", |
927 | "Set Control: ID - %d - %d", | ||
928 | ctrl->id, ctrl->value); | 941 | ctrl->id, ctrl->value); |
929 | 942 | ||
930 | return err; | 943 | return err; |
931 | } | 944 | } |
932 | 945 | ||
933 | /** | 946 | /** |
934 | * ioctl_enum_fmt_cap - Implement the CAPTURE buffer VIDIOC_ENUM_FMT ioctl | 947 | * tvp514x_enum_fmt_cap() - V4L2 decoder interface handler for enum_fmt |
935 | * @s: pointer to standard V4L2 device structure | 948 | * @sd: pointer to standard V4L2 sub-device structure |
936 | * @fmt: standard V4L2 VIDIOC_ENUM_FMT ioctl structure | 949 | * @fmt: standard V4L2 VIDIOC_ENUM_FMT ioctl structure |
937 | * | 950 | * |
938 | * Implement the VIDIOC_ENUM_FMT ioctl to enumerate supported formats | 951 | * Implement the VIDIOC_ENUM_FMT ioctl to enumerate supported formats |
939 | */ | 952 | */ |
940 | static int | 953 | static int |
941 | ioctl_enum_fmt_cap(struct v4l2_int_device *s, struct v4l2_fmtdesc *fmt) | 954 | tvp514x_enum_fmt_cap(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt) |
942 | { | 955 | { |
943 | struct tvp514x_decoder *decoder = s->priv; | 956 | struct tvp514x_decoder *decoder = to_decoder(sd); |
944 | int index; | 957 | int index; |
945 | 958 | ||
946 | if (fmt == NULL) | 959 | if (fmt == NULL) |
@@ -948,24 +961,25 @@ ioctl_enum_fmt_cap(struct v4l2_int_device *s, struct v4l2_fmtdesc *fmt) | |||
948 | 961 | ||
949 | index = fmt->index; | 962 | index = fmt->index; |
950 | if ((index >= decoder->num_fmts) || (index < 0)) | 963 | if ((index >= decoder->num_fmts) || (index < 0)) |
951 | return -EINVAL; /* Index out of bound */ | 964 | /* Index out of bound */ |
965 | return -EINVAL; | ||
952 | 966 | ||
953 | if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 967 | if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
954 | return -EINVAL; /* only capture is supported */ | 968 | /* only capture is supported */ |
969 | return -EINVAL; | ||
955 | 970 | ||
956 | memcpy(fmt, &decoder->fmt_list[index], | 971 | memcpy(fmt, &decoder->fmt_list[index], |
957 | sizeof(struct v4l2_fmtdesc)); | 972 | sizeof(struct v4l2_fmtdesc)); |
958 | 973 | ||
959 | v4l_dbg(1, debug, decoder->client, | 974 | v4l2_dbg(1, debug, sd, "Current FMT: index - %d (%s)", |
960 | "Current FMT: index - %d (%s)", | ||
961 | decoder->fmt_list[index].index, | 975 | decoder->fmt_list[index].index, |
962 | decoder->fmt_list[index].description); | 976 | decoder->fmt_list[index].description); |
963 | return 0; | 977 | return 0; |
964 | } | 978 | } |
965 | 979 | ||
966 | /** | 980 | /** |
967 | * ioctl_try_fmt_cap - Implement the CAPTURE buffer VIDIOC_TRY_FMT ioctl | 981 | * tvp514x_try_fmt_cap() - V4L2 decoder interface handler for try_fmt |
968 | * @s: pointer to standard V4L2 device structure | 982 | * @sd: pointer to standard V4L2 sub-device structure |
969 | * @f: pointer to standard V4L2 VIDIOC_TRY_FMT ioctl structure | 983 | * @f: pointer to standard V4L2 VIDIOC_TRY_FMT ioctl structure |
970 | * | 984 | * |
971 | * Implement the VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type. This | 985 | * Implement the VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type. This |
@@ -973,9 +987,9 @@ ioctl_enum_fmt_cap(struct v4l2_int_device *s, struct v4l2_fmtdesc *fmt) | |||
973 | * without actually making it take effect. | 987 | * without actually making it take effect. |
974 | */ | 988 | */ |
975 | static int | 989 | static int |
976 | ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f) | 990 | tvp514x_try_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f) |
977 | { | 991 | { |
978 | struct tvp514x_decoder *decoder = s->priv; | 992 | struct tvp514x_decoder *decoder = to_decoder(sd); |
979 | int ifmt; | 993 | int ifmt; |
980 | struct v4l2_pix_format *pix; | 994 | struct v4l2_pix_format *pix; |
981 | enum tvp514x_std current_std; | 995 | enum tvp514x_std current_std; |
@@ -984,12 +998,13 @@ ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f) | |||
984 | return -EINVAL; | 998 | return -EINVAL; |
985 | 999 | ||
986 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1000 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1001 | /* only capture is supported */ | ||
987 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1002 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
988 | 1003 | ||
989 | pix = &f->fmt.pix; | 1004 | pix = &f->fmt.pix; |
990 | 1005 | ||
991 | /* Calculate height and width based on current standard */ | 1006 | /* Calculate height and width based on current standard */ |
992 | current_std = tvp514x_get_current_std(decoder); | 1007 | current_std = tvp514x_get_current_std(sd); |
993 | if (current_std == STD_INVALID) | 1008 | if (current_std == STD_INVALID) |
994 | return -EINVAL; | 1009 | return -EINVAL; |
995 | 1010 | ||
@@ -1003,7 +1018,8 @@ ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f) | |||
1003 | break; | 1018 | break; |
1004 | } | 1019 | } |
1005 | if (ifmt == decoder->num_fmts) | 1020 | if (ifmt == decoder->num_fmts) |
1006 | ifmt = 0; /* None of the format matched, select default */ | 1021 | /* None of the format matched, select default */ |
1022 | ifmt = 0; | ||
1007 | pix->pixelformat = decoder->fmt_list[ifmt].pixelformat; | 1023 | pix->pixelformat = decoder->fmt_list[ifmt].pixelformat; |
1008 | 1024 | ||
1009 | pix->field = V4L2_FIELD_INTERLACED; | 1025 | pix->field = V4L2_FIELD_INTERLACED; |
@@ -1012,8 +1028,7 @@ ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f) | |||
1012 | pix->colorspace = V4L2_COLORSPACE_SMPTE170M; | 1028 | pix->colorspace = V4L2_COLORSPACE_SMPTE170M; |
1013 | pix->priv = 0; | 1029 | pix->priv = 0; |
1014 | 1030 | ||
1015 | v4l_dbg(1, debug, decoder->client, | 1031 | v4l2_dbg(1, debug, sd, "Try FMT: pixelformat - %s, bytesperline - %d" |
1016 | "Try FMT: pixelformat - %s, bytesperline - %d" | ||
1017 | "Width - %d, Height - %d", | 1032 | "Width - %d, Height - %d", |
1018 | decoder->fmt_list[ifmt].description, pix->bytesperline, | 1033 | decoder->fmt_list[ifmt].description, pix->bytesperline, |
1019 | pix->width, pix->height); | 1034 | pix->width, pix->height); |
@@ -1021,8 +1036,8 @@ ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f) | |||
1021 | } | 1036 | } |
1022 | 1037 | ||
1023 | /** | 1038 | /** |
1024 | * ioctl_s_fmt_cap - V4L2 decoder interface handler for VIDIOC_S_FMT ioctl | 1039 | * tvp514x_s_fmt_cap() - V4L2 decoder interface handler for s_fmt |
1025 | * @s: pointer to standard V4L2 device structure | 1040 | * @sd: pointer to standard V4L2 sub-device structure |
1026 | * @f: pointer to standard V4L2 VIDIOC_S_FMT ioctl structure | 1041 | * @f: pointer to standard V4L2 VIDIOC_S_FMT ioctl structure |
1027 | * | 1042 | * |
1028 | * If the requested format is supported, configures the HW to use that | 1043 | * If the requested format is supported, configures the HW to use that |
@@ -1030,9 +1045,9 @@ ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f) | |||
1030 | * correctly configured. | 1045 | * correctly configured. |
1031 | */ | 1046 | */ |
1032 | static int | 1047 | static int |
1033 | ioctl_s_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f) | 1048 | tvp514x_s_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f) |
1034 | { | 1049 | { |
1035 | struct tvp514x_decoder *decoder = s->priv; | 1050 | struct tvp514x_decoder *decoder = to_decoder(sd); |
1036 | struct v4l2_pix_format *pix; | 1051 | struct v4l2_pix_format *pix; |
1037 | int rval; | 1052 | int rval; |
1038 | 1053 | ||
@@ -1040,10 +1055,11 @@ ioctl_s_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f) | |||
1040 | return -EINVAL; | 1055 | return -EINVAL; |
1041 | 1056 | ||
1042 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1057 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1043 | return -EINVAL; /* only capture is supported */ | 1058 | /* only capture is supported */ |
1059 | return -EINVAL; | ||
1044 | 1060 | ||
1045 | pix = &f->fmt.pix; | 1061 | pix = &f->fmt.pix; |
1046 | rval = ioctl_try_fmt_cap(s, f); | 1062 | rval = tvp514x_try_fmt_cap(sd, f); |
1047 | if (rval) | 1063 | if (rval) |
1048 | return rval; | 1064 | return rval; |
1049 | 1065 | ||
@@ -1053,28 +1069,28 @@ ioctl_s_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f) | |||
1053 | } | 1069 | } |
1054 | 1070 | ||
1055 | /** | 1071 | /** |
1056 | * ioctl_g_fmt_cap - V4L2 decoder interface handler for ioctl_g_fmt_cap | 1072 | * tvp514x_g_fmt_cap() - V4L2 decoder interface handler for tvp514x_g_fmt_cap |
1057 | * @s: pointer to standard V4L2 device structure | 1073 | * @sd: pointer to standard V4L2 sub-device structure |
1058 | * @f: pointer to standard V4L2 v4l2_format structure | 1074 | * @f: pointer to standard V4L2 v4l2_format structure |
1059 | * | 1075 | * |
1060 | * Returns the decoder's current pixel format in the v4l2_format | 1076 | * Returns the decoder's current pixel format in the v4l2_format |
1061 | * parameter. | 1077 | * parameter. |
1062 | */ | 1078 | */ |
1063 | static int | 1079 | static int |
1064 | ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f) | 1080 | tvp514x_g_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f) |
1065 | { | 1081 | { |
1066 | struct tvp514x_decoder *decoder = s->priv; | 1082 | struct tvp514x_decoder *decoder = to_decoder(sd); |
1067 | 1083 | ||
1068 | if (f == NULL) | 1084 | if (f == NULL) |
1069 | return -EINVAL; | 1085 | return -EINVAL; |
1070 | 1086 | ||
1071 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1087 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1072 | return -EINVAL; /* only capture is supported */ | 1088 | /* only capture is supported */ |
1089 | return -EINVAL; | ||
1073 | 1090 | ||
1074 | f->fmt.pix = decoder->pix; | 1091 | f->fmt.pix = decoder->pix; |
1075 | 1092 | ||
1076 | v4l_dbg(1, debug, decoder->client, | 1093 | v4l2_dbg(1, debug, sd, "Current FMT: bytesperline - %d" |
1077 | "Current FMT: bytesperline - %d" | ||
1078 | "Width - %d, Height - %d", | 1094 | "Width - %d, Height - %d", |
1079 | decoder->pix.bytesperline, | 1095 | decoder->pix.bytesperline, |
1080 | decoder->pix.width, decoder->pix.height); | 1096 | decoder->pix.width, decoder->pix.height); |
@@ -1082,16 +1098,16 @@ ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f) | |||
1082 | } | 1098 | } |
1083 | 1099 | ||
1084 | /** | 1100 | /** |
1085 | * ioctl_g_parm - V4L2 decoder interface handler for VIDIOC_G_PARM ioctl | 1101 | * tvp514x_g_parm() - V4L2 decoder interface handler for g_parm |
1086 | * @s: pointer to standard V4L2 device structure | 1102 | * @sd: pointer to standard V4L2 sub-device structure |
1087 | * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure | 1103 | * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure |
1088 | * | 1104 | * |
1089 | * Returns the decoder's video CAPTURE parameters. | 1105 | * Returns the decoder's video CAPTURE parameters. |
1090 | */ | 1106 | */ |
1091 | static int | 1107 | static int |
1092 | ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a) | 1108 | tvp514x_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a) |
1093 | { | 1109 | { |
1094 | struct tvp514x_decoder *decoder = s->priv; | 1110 | struct tvp514x_decoder *decoder = to_decoder(sd); |
1095 | struct v4l2_captureparm *cparm; | 1111 | struct v4l2_captureparm *cparm; |
1096 | enum tvp514x_std current_std; | 1112 | enum tvp514x_std current_std; |
1097 | 1113 | ||
@@ -1099,13 +1115,14 @@ ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a) | |||
1099 | return -EINVAL; | 1115 | return -EINVAL; |
1100 | 1116 | ||
1101 | if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1117 | if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1102 | return -EINVAL; /* only capture is supported */ | 1118 | /* only capture is supported */ |
1119 | return -EINVAL; | ||
1103 | 1120 | ||
1104 | memset(a, 0, sizeof(*a)); | 1121 | memset(a, 0, sizeof(*a)); |
1105 | a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1122 | a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1106 | 1123 | ||
1107 | /* get the current standard */ | 1124 | /* get the current standard */ |
1108 | current_std = tvp514x_get_current_std(decoder); | 1125 | current_std = tvp514x_get_current_std(sd); |
1109 | if (current_std == STD_INVALID) | 1126 | if (current_std == STD_INVALID) |
1110 | return -EINVAL; | 1127 | return -EINVAL; |
1111 | 1128 | ||
@@ -1120,17 +1137,17 @@ ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a) | |||
1120 | } | 1137 | } |
1121 | 1138 | ||
1122 | /** | 1139 | /** |
1123 | * ioctl_s_parm - V4L2 decoder interface handler for VIDIOC_S_PARM ioctl | 1140 | * tvp514x_s_parm() - V4L2 decoder interface handler for s_parm |
1124 | * @s: pointer to standard V4L2 device structure | 1141 | * @sd: pointer to standard V4L2 sub-device structure |
1125 | * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure | 1142 | * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure |
1126 | * | 1143 | * |
1127 | * Configures the decoder to use the input parameters, if possible. If | 1144 | * Configures the decoder to use the input parameters, if possible. If |
1128 | * not possible, returns the appropriate error code. | 1145 | * not possible, returns the appropriate error code. |
1129 | */ | 1146 | */ |
1130 | static int | 1147 | static int |
1131 | ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a) | 1148 | tvp514x_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a) |
1132 | { | 1149 | { |
1133 | struct tvp514x_decoder *decoder = s->priv; | 1150 | struct tvp514x_decoder *decoder = to_decoder(sd); |
1134 | struct v4l2_fract *timeperframe; | 1151 | struct v4l2_fract *timeperframe; |
1135 | enum tvp514x_std current_std; | 1152 | enum tvp514x_std current_std; |
1136 | 1153 | ||
@@ -1138,12 +1155,13 @@ ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a) | |||
1138 | return -EINVAL; | 1155 | return -EINVAL; |
1139 | 1156 | ||
1140 | if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1157 | if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1141 | return -EINVAL; /* only capture is supported */ | 1158 | /* only capture is supported */ |
1159 | return -EINVAL; | ||
1142 | 1160 | ||
1143 | timeperframe = &a->parm.capture.timeperframe; | 1161 | timeperframe = &a->parm.capture.timeperframe; |
1144 | 1162 | ||
1145 | /* get the current standard */ | 1163 | /* get the current standard */ |
1146 | current_std = tvp514x_get_current_std(decoder); | 1164 | current_std = tvp514x_get_current_std(sd); |
1147 | if (current_std == STD_INVALID) | 1165 | if (current_std == STD_INVALID) |
1148 | return -EINVAL; | 1166 | return -EINVAL; |
1149 | 1167 | ||
@@ -1156,111 +1174,58 @@ ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a) | |||
1156 | } | 1174 | } |
1157 | 1175 | ||
1158 | /** | 1176 | /** |
1159 | * ioctl_g_ifparm - V4L2 decoder interface handler for vidioc_int_g_ifparm_num | 1177 | * tvp514x_s_stream() - V4L2 decoder i/f handler for s_stream |
1160 | * @s: pointer to standard V4L2 device structure | 1178 | * @sd: pointer to standard V4L2 sub-device structure |
1161 | * @p: pointer to standard V4L2 vidioc_int_g_ifparm_num ioctl structure | 1179 | * @enable: streaming enable or disable |
1162 | * | ||
1163 | * Gets slave interface parameters. | ||
1164 | * Calculates the required xclk value to support the requested | ||
1165 | * clock parameters in p. This value is returned in the p | ||
1166 | * parameter. | ||
1167 | */ | ||
1168 | static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p) | ||
1169 | { | ||
1170 | struct tvp514x_decoder *decoder = s->priv; | ||
1171 | int rval; | ||
1172 | |||
1173 | if (p == NULL) | ||
1174 | return -EINVAL; | ||
1175 | |||
1176 | if (NULL == decoder->pdata->ifparm) | ||
1177 | return -EINVAL; | ||
1178 | |||
1179 | rval = decoder->pdata->ifparm(p); | ||
1180 | if (rval) { | ||
1181 | v4l_err(decoder->client, "g_ifparm.Err[%d]\n", rval); | ||
1182 | return rval; | ||
1183 | } | ||
1184 | |||
1185 | p->u.bt656.clock_curr = TVP514X_XCLK_BT656; | ||
1186 | |||
1187 | return 0; | ||
1188 | } | ||
1189 | |||
1190 | /** | ||
1191 | * ioctl_g_priv - V4L2 decoder interface handler for vidioc_int_g_priv_num | ||
1192 | * @s: pointer to standard V4L2 device structure | ||
1193 | * @p: void pointer to hold decoder's private data address | ||
1194 | * | ||
1195 | * Returns device's (decoder's) private data area address in p parameter | ||
1196 | */ | ||
1197 | static int ioctl_g_priv(struct v4l2_int_device *s, void *p) | ||
1198 | { | ||
1199 | struct tvp514x_decoder *decoder = s->priv; | ||
1200 | |||
1201 | if (NULL == decoder->pdata->priv_data_set) | ||
1202 | return -EINVAL; | ||
1203 | |||
1204 | return decoder->pdata->priv_data_set(p); | ||
1205 | } | ||
1206 | |||
1207 | /** | ||
1208 | * ioctl_s_power - V4L2 decoder interface handler for vidioc_int_s_power_num | ||
1209 | * @s: pointer to standard V4L2 device structure | ||
1210 | * @on: power state to which device is to be set | ||
1211 | * | 1180 | * |
1212 | * Sets devices power state to requrested state, if possible. | 1181 | * Sets streaming to enable or disable, if possible. |
1213 | */ | 1182 | */ |
1214 | static int ioctl_s_power(struct v4l2_int_device *s, enum v4l2_power on) | 1183 | static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable) |
1215 | { | 1184 | { |
1216 | struct tvp514x_decoder *decoder = s->priv; | ||
1217 | int err = 0; | 1185 | int err = 0; |
1186 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1187 | struct tvp514x_decoder *decoder = to_decoder(sd); | ||
1218 | 1188 | ||
1219 | switch (on) { | 1189 | if (decoder->streaming == enable) |
1220 | case V4L2_POWER_OFF: | 1190 | return 0; |
1221 | /* Power Down Sequence */ | ||
1222 | err = | ||
1223 | tvp514x_write_reg(decoder->client, REG_OPERATION_MODE, | ||
1224 | 0x01); | ||
1225 | /* Disable mux for TVP5146/47 decoder data path */ | ||
1226 | if (decoder->pdata->power_set) | ||
1227 | err |= decoder->pdata->power_set(on); | ||
1228 | decoder->state = STATE_NOT_DETECTED; | ||
1229 | break; | ||
1230 | 1191 | ||
1231 | case V4L2_POWER_STANDBY: | 1192 | switch (enable) { |
1232 | if (decoder->pdata->power_set) | 1193 | case 0: |
1233 | err = decoder->pdata->power_set(on); | 1194 | { |
1195 | /* Power Down Sequence */ | ||
1196 | err = tvp514x_write_reg(sd, REG_OPERATION_MODE, 0x01); | ||
1197 | if (err) { | ||
1198 | v4l2_err(sd, "Unable to turn off decoder\n"); | ||
1199 | return err; | ||
1200 | } | ||
1201 | decoder->streaming = enable; | ||
1234 | break; | 1202 | break; |
1203 | } | ||
1204 | case 1: | ||
1205 | { | ||
1206 | struct tvp514x_reg *int_seq = (struct tvp514x_reg *) | ||
1207 | client->driver->id_table->driver_data; | ||
1235 | 1208 | ||
1236 | case V4L2_POWER_ON: | 1209 | /* Power Up Sequence */ |
1237 | /* Enable mux for TVP5146/47 decoder data path */ | 1210 | err = tvp514x_write_regs(sd, int_seq); |
1238 | if ((decoder->pdata->power_set) && | 1211 | if (err) { |
1239 | (decoder->state == STATE_NOT_DETECTED)) { | 1212 | v4l2_err(sd, "Unable to turn on decoder\n"); |
1240 | int i; | 1213 | return err; |
1241 | struct tvp514x_init_seq *int_seq = | ||
1242 | (struct tvp514x_init_seq *) | ||
1243 | decoder->id->driver_data; | ||
1244 | |||
1245 | err = decoder->pdata->power_set(on); | ||
1246 | |||
1247 | /* Power Up Sequence */ | ||
1248 | for (i = 0; i < int_seq->no_regs; i++) { | ||
1249 | err |= tvp514x_write_reg(decoder->client, | ||
1250 | int_seq->init_reg_seq[i].reg, | ||
1251 | int_seq->init_reg_seq[i].val); | ||
1252 | } | ||
1253 | /* Detect the sensor is not already detected */ | ||
1254 | err |= tvp514x_detect(decoder); | ||
1255 | if (err) { | ||
1256 | v4l_err(decoder->client, | ||
1257 | "Unable to detect decoder\n"); | ||
1258 | return err; | ||
1259 | } | ||
1260 | } | 1214 | } |
1261 | err |= tvp514x_configure(decoder); | 1215 | /* Detect if not already detected */ |
1216 | err = tvp514x_detect(sd, decoder); | ||
1217 | if (err) { | ||
1218 | v4l2_err(sd, "Unable to detect decoder\n"); | ||
1219 | return err; | ||
1220 | } | ||
1221 | err = tvp514x_configure(sd, decoder); | ||
1222 | if (err) { | ||
1223 | v4l2_err(sd, "Unable to configure decoder\n"); | ||
1224 | return err; | ||
1225 | } | ||
1226 | decoder->streaming = enable; | ||
1262 | break; | 1227 | break; |
1263 | 1228 | } | |
1264 | default: | 1229 | default: |
1265 | err = -ENODEV; | 1230 | err = -ENODEV; |
1266 | break; | 1231 | break; |
@@ -1269,93 +1234,38 @@ static int ioctl_s_power(struct v4l2_int_device *s, enum v4l2_power on) | |||
1269 | return err; | 1234 | return err; |
1270 | } | 1235 | } |
1271 | 1236 | ||
1272 | /** | 1237 | static const struct v4l2_subdev_core_ops tvp514x_core_ops = { |
1273 | * ioctl_init - V4L2 decoder interface handler for VIDIOC_INT_INIT | 1238 | .queryctrl = tvp514x_queryctrl, |
1274 | * @s: pointer to standard V4L2 device structure | 1239 | .g_ctrl = tvp514x_g_ctrl, |
1275 | * | 1240 | .s_ctrl = tvp514x_s_ctrl, |
1276 | * Initialize the decoder device (calls tvp514x_configure()) | 1241 | .s_std = tvp514x_s_std, |
1277 | */ | 1242 | }; |
1278 | static int ioctl_init(struct v4l2_int_device *s) | ||
1279 | { | ||
1280 | struct tvp514x_decoder *decoder = s->priv; | ||
1281 | |||
1282 | /* Set default standard to auto */ | ||
1283 | decoder->tvp514x_regs[REG_VIDEO_STD].val = | ||
1284 | VIDEO_STD_AUTO_SWITCH_BIT; | ||
1285 | |||
1286 | return tvp514x_configure(decoder); | ||
1287 | } | ||
1288 | |||
1289 | /** | ||
1290 | * ioctl_dev_exit - V4L2 decoder interface handler for vidioc_int_dev_exit_num | ||
1291 | * @s: pointer to standard V4L2 device structure | ||
1292 | * | ||
1293 | * Delinitialise the dev. at slave detach. The complement of ioctl_dev_init. | ||
1294 | */ | ||
1295 | static int ioctl_dev_exit(struct v4l2_int_device *s) | ||
1296 | { | ||
1297 | return 0; | ||
1298 | } | ||
1299 | |||
1300 | /** | ||
1301 | * ioctl_dev_init - V4L2 decoder interface handler for vidioc_int_dev_init_num | ||
1302 | * @s: pointer to standard V4L2 device structure | ||
1303 | * | ||
1304 | * Initialise the device when slave attaches to the master. Returns 0 if | ||
1305 | * TVP5146/47 device could be found, otherwise returns appropriate error. | ||
1306 | */ | ||
1307 | static int ioctl_dev_init(struct v4l2_int_device *s) | ||
1308 | { | ||
1309 | struct tvp514x_decoder *decoder = s->priv; | ||
1310 | int err; | ||
1311 | |||
1312 | err = tvp514x_detect(decoder); | ||
1313 | if (err < 0) { | ||
1314 | v4l_err(decoder->client, | ||
1315 | "Unable to detect decoder\n"); | ||
1316 | return err; | ||
1317 | } | ||
1318 | |||
1319 | v4l_info(decoder->client, | ||
1320 | "chip version 0x%.2x detected\n", decoder->ver); | ||
1321 | 1243 | ||
1322 | return 0; | 1244 | static const struct v4l2_subdev_video_ops tvp514x_video_ops = { |
1323 | } | 1245 | .s_routing = tvp514x_s_routing, |
1246 | .querystd = tvp514x_querystd, | ||
1247 | .enum_fmt = tvp514x_enum_fmt_cap, | ||
1248 | .g_fmt = tvp514x_g_fmt_cap, | ||
1249 | .try_fmt = tvp514x_try_fmt_cap, | ||
1250 | .s_fmt = tvp514x_s_fmt_cap, | ||
1251 | .g_parm = tvp514x_g_parm, | ||
1252 | .s_parm = tvp514x_s_parm, | ||
1253 | .s_stream = tvp514x_s_stream, | ||
1254 | }; | ||
1324 | 1255 | ||
1325 | static struct v4l2_int_ioctl_desc tvp514x_ioctl_desc[] = { | 1256 | static const struct v4l2_subdev_ops tvp514x_ops = { |
1326 | {vidioc_int_dev_init_num, (v4l2_int_ioctl_func*) ioctl_dev_init}, | 1257 | .core = &tvp514x_core_ops, |
1327 | {vidioc_int_dev_exit_num, (v4l2_int_ioctl_func*) ioctl_dev_exit}, | 1258 | .video = &tvp514x_video_ops, |
1328 | {vidioc_int_s_power_num, (v4l2_int_ioctl_func*) ioctl_s_power}, | ||
1329 | {vidioc_int_g_priv_num, (v4l2_int_ioctl_func*) ioctl_g_priv}, | ||
1330 | {vidioc_int_g_ifparm_num, (v4l2_int_ioctl_func*) ioctl_g_ifparm}, | ||
1331 | {vidioc_int_init_num, (v4l2_int_ioctl_func*) ioctl_init}, | ||
1332 | {vidioc_int_enum_fmt_cap_num, | ||
1333 | (v4l2_int_ioctl_func *) ioctl_enum_fmt_cap}, | ||
1334 | {vidioc_int_try_fmt_cap_num, | ||
1335 | (v4l2_int_ioctl_func *) ioctl_try_fmt_cap}, | ||
1336 | {vidioc_int_g_fmt_cap_num, | ||
1337 | (v4l2_int_ioctl_func *) ioctl_g_fmt_cap}, | ||
1338 | {vidioc_int_s_fmt_cap_num, | ||
1339 | (v4l2_int_ioctl_func *) ioctl_s_fmt_cap}, | ||
1340 | {vidioc_int_g_parm_num, (v4l2_int_ioctl_func *) ioctl_g_parm}, | ||
1341 | {vidioc_int_s_parm_num, (v4l2_int_ioctl_func *) ioctl_s_parm}, | ||
1342 | {vidioc_int_queryctrl_num, | ||
1343 | (v4l2_int_ioctl_func *) ioctl_queryctrl}, | ||
1344 | {vidioc_int_g_ctrl_num, (v4l2_int_ioctl_func *) ioctl_g_ctrl}, | ||
1345 | {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func *) ioctl_s_ctrl}, | ||
1346 | {vidioc_int_querystd_num, (v4l2_int_ioctl_func *) ioctl_querystd}, | ||
1347 | {vidioc_int_s_std_num, (v4l2_int_ioctl_func *) ioctl_s_std}, | ||
1348 | {vidioc_int_s_video_routing_num, | ||
1349 | (v4l2_int_ioctl_func *) ioctl_s_routing}, | ||
1350 | }; | 1259 | }; |
1351 | 1260 | ||
1352 | static struct tvp514x_decoder tvp514x_dev = { | 1261 | static struct tvp514x_decoder tvp514x_dev = { |
1353 | .state = STATE_NOT_DETECTED, | 1262 | .streaming = 0, |
1354 | 1263 | ||
1355 | .fmt_list = tvp514x_fmt_list, | 1264 | .fmt_list = tvp514x_fmt_list, |
1356 | .num_fmts = ARRAY_SIZE(tvp514x_fmt_list), | 1265 | .num_fmts = ARRAY_SIZE(tvp514x_fmt_list), |
1357 | 1266 | ||
1358 | .pix = { /* Default to NTSC 8-bit YUV 422 */ | 1267 | .pix = { |
1268 | /* Default to NTSC 8-bit YUV 422 */ | ||
1359 | .width = NTSC_NUM_ACTIVE_PIXELS, | 1269 | .width = NTSC_NUM_ACTIVE_PIXELS, |
1360 | .height = NTSC_NUM_ACTIVE_LINES, | 1270 | .height = NTSC_NUM_ACTIVE_LINES, |
1361 | .pixelformat = V4L2_PIX_FMT_UYVY, | 1271 | .pixelformat = V4L2_PIX_FMT_UYVY, |
@@ -1369,20 +1279,13 @@ static struct tvp514x_decoder tvp514x_dev = { | |||
1369 | .current_std = STD_NTSC_MJ, | 1279 | .current_std = STD_NTSC_MJ, |
1370 | .std_list = tvp514x_std_list, | 1280 | .std_list = tvp514x_std_list, |
1371 | .num_stds = ARRAY_SIZE(tvp514x_std_list), | 1281 | .num_stds = ARRAY_SIZE(tvp514x_std_list), |
1372 | .v4l2_int_device = { | 1282 | |
1373 | .module = THIS_MODULE, | ||
1374 | .name = TVP514X_MODULE_NAME, | ||
1375 | .type = v4l2_int_type_slave, | ||
1376 | }, | ||
1377 | .tvp514x_slave = { | ||
1378 | .ioctls = tvp514x_ioctl_desc, | ||
1379 | .num_ioctls = ARRAY_SIZE(tvp514x_ioctl_desc), | ||
1380 | }, | ||
1381 | }; | 1283 | }; |
1382 | 1284 | ||
1383 | /** | 1285 | /** |
1384 | * tvp514x_probe - decoder driver i2c probe handler | 1286 | * tvp514x_probe() - decoder driver i2c probe handler |
1385 | * @client: i2c driver client device structure | 1287 | * @client: i2c driver client device structure |
1288 | * @id: i2c driver id table | ||
1386 | * | 1289 | * |
1387 | * Register decoder as an i2c client device and V4L2 | 1290 | * Register decoder as an i2c client device and V4L2 |
1388 | * device. | 1291 | * device. |
@@ -1391,88 +1294,71 @@ static int | |||
1391 | tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id) | 1294 | tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id) |
1392 | { | 1295 | { |
1393 | struct tvp514x_decoder *decoder; | 1296 | struct tvp514x_decoder *decoder; |
1394 | int err; | 1297 | struct v4l2_subdev *sd; |
1395 | 1298 | ||
1396 | /* Check if the adapter supports the needed features */ | 1299 | /* Check if the adapter supports the needed features */ |
1397 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 1300 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
1398 | return -EIO; | 1301 | return -EIO; |
1399 | 1302 | ||
1303 | if (!client->dev.platform_data) { | ||
1304 | v4l2_err(client, "No platform data!!\n"); | ||
1305 | return -ENODEV; | ||
1306 | } | ||
1307 | |||
1400 | decoder = kzalloc(sizeof(*decoder), GFP_KERNEL); | 1308 | decoder = kzalloc(sizeof(*decoder), GFP_KERNEL); |
1401 | if (!decoder) | 1309 | if (!decoder) |
1402 | return -ENOMEM; | 1310 | return -ENOMEM; |
1403 | 1311 | ||
1404 | if (!client->dev.platform_data) { | 1312 | /* Initialize the tvp514x_decoder with default configuration */ |
1405 | v4l_err(client, "No platform data!!\n"); | ||
1406 | err = -ENODEV; | ||
1407 | goto out_free; | ||
1408 | } | ||
1409 | |||
1410 | *decoder = tvp514x_dev; | 1313 | *decoder = tvp514x_dev; |
1411 | decoder->v4l2_int_device.priv = decoder; | 1314 | /* Copy default register configuration */ |
1412 | decoder->pdata = client->dev.platform_data; | ||
1413 | decoder->v4l2_int_device.u.slave = &decoder->tvp514x_slave; | ||
1414 | memcpy(decoder->tvp514x_regs, tvp514x_reg_list_default, | 1315 | memcpy(decoder->tvp514x_regs, tvp514x_reg_list_default, |
1415 | sizeof(tvp514x_reg_list_default)); | 1316 | sizeof(tvp514x_reg_list_default)); |
1416 | /* | 1317 | |
1318 | /* Copy board specific information here */ | ||
1319 | decoder->pdata = client->dev.platform_data; | ||
1320 | |||
1321 | /** | ||
1417 | * Fetch platform specific data, and configure the | 1322 | * Fetch platform specific data, and configure the |
1418 | * tvp514x_reg_list[] accordingly. Since this is one | 1323 | * tvp514x_reg_list[] accordingly. Since this is one |
1419 | * time configuration, no need to preserve. | 1324 | * time configuration, no need to preserve. |
1420 | */ | 1325 | */ |
1421 | decoder->tvp514x_regs[REG_OUTPUT_FORMATTER2].val |= | 1326 | decoder->tvp514x_regs[REG_OUTPUT_FORMATTER2].val |= |
1422 | (decoder->pdata->clk_polarity << 1); | 1327 | (decoder->pdata->clk_polarity << 1); |
1423 | decoder->tvp514x_regs[REG_SYNC_CONTROL].val |= | 1328 | decoder->tvp514x_regs[REG_SYNC_CONTROL].val |= |
1424 | ((decoder->pdata->hs_polarity << 2) | | 1329 | ((decoder->pdata->hs_polarity << 2) | |
1425 | (decoder->pdata->vs_polarity << 3)); | 1330 | (decoder->pdata->vs_polarity << 3)); |
1426 | /* | 1331 | /* Set default standard to auto */ |
1427 | * Save the id data, required for power up sequence | 1332 | decoder->tvp514x_regs[REG_VIDEO_STD].val = |
1428 | */ | 1333 | VIDEO_STD_AUTO_SWITCH_BIT; |
1429 | decoder->id = (struct i2c_device_id *)id; | ||
1430 | /* Attach to Master */ | ||
1431 | strcpy(decoder->v4l2_int_device.u.slave->attach_to, | ||
1432 | decoder->pdata->master); | ||
1433 | decoder->client = client; | ||
1434 | i2c_set_clientdata(client, decoder); | ||
1435 | 1334 | ||
1436 | /* Register with V4L2 layer as slave device */ | 1335 | /* Register with V4L2 layer as slave device */ |
1437 | err = v4l2_int_device_register(&decoder->v4l2_int_device); | 1336 | sd = &decoder->sd; |
1438 | if (err) { | 1337 | v4l2_i2c_subdev_init(sd, client, &tvp514x_ops); |
1439 | i2c_set_clientdata(client, NULL); | 1338 | |
1440 | v4l_err(client, | 1339 | v4l2_info(sd, "%s decoder driver registered !!\n", sd->name); |
1441 | "Unable to register to v4l2. Err[%d]\n", err); | 1340 | |
1442 | goto out_free; | ||
1443 | |||
1444 | } else | ||
1445 | v4l_info(client, "Registered to v4l2 master %s!!\n", | ||
1446 | decoder->pdata->master); | ||
1447 | return 0; | 1341 | return 0; |
1448 | 1342 | ||
1449 | out_free: | ||
1450 | kfree(decoder); | ||
1451 | return err; | ||
1452 | } | 1343 | } |
1453 | 1344 | ||
1454 | /** | 1345 | /** |
1455 | * tvp514x_remove - decoder driver i2c remove handler | 1346 | * tvp514x_remove() - decoder driver i2c remove handler |
1456 | * @client: i2c driver client device structure | 1347 | * @client: i2c driver client device structure |
1457 | * | 1348 | * |
1458 | * Unregister decoder as an i2c client device and V4L2 | 1349 | * Unregister decoder as an i2c client device and V4L2 |
1459 | * device. Complement of tvp514x_probe(). | 1350 | * device. Complement of tvp514x_probe(). |
1460 | */ | 1351 | */ |
1461 | static int __exit tvp514x_remove(struct i2c_client *client) | 1352 | static int tvp514x_remove(struct i2c_client *client) |
1462 | { | 1353 | { |
1463 | struct tvp514x_decoder *decoder = i2c_get_clientdata(client); | 1354 | struct v4l2_subdev *sd = i2c_get_clientdata(client); |
1464 | 1355 | struct tvp514x_decoder *decoder = to_decoder(sd); | |
1465 | if (!client->adapter) | ||
1466 | return -ENODEV; /* our client isn't attached */ | ||
1467 | 1356 | ||
1468 | v4l2_int_device_unregister(&decoder->v4l2_int_device); | 1357 | v4l2_device_unregister_subdev(sd); |
1469 | i2c_set_clientdata(client, NULL); | ||
1470 | kfree(decoder); | 1358 | kfree(decoder); |
1471 | return 0; | 1359 | return 0; |
1472 | } | 1360 | } |
1473 | /* | 1361 | /* TVP5146 Init/Power on Sequence */ |
1474 | * TVP5146 Init/Power on Sequence | ||
1475 | */ | ||
1476 | static const struct tvp514x_reg tvp5146_init_reg_seq[] = { | 1362 | static const struct tvp514x_reg tvp5146_init_reg_seq[] = { |
1477 | {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x02}, | 1363 | {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x02}, |
1478 | {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00}, | 1364 | {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00}, |
@@ -1485,14 +1371,10 @@ static const struct tvp514x_reg tvp5146_init_reg_seq[] = { | |||
1485 | {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x00}, | 1371 | {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x00}, |
1486 | {TOK_WRITE, REG_OPERATION_MODE, 0x01}, | 1372 | {TOK_WRITE, REG_OPERATION_MODE, 0x01}, |
1487 | {TOK_WRITE, REG_OPERATION_MODE, 0x00}, | 1373 | {TOK_WRITE, REG_OPERATION_MODE, 0x00}, |
1374 | {TOK_TERM, 0, 0}, | ||
1488 | }; | 1375 | }; |
1489 | static const struct tvp514x_init_seq tvp5146_init = { | 1376 | |
1490 | .no_regs = ARRAY_SIZE(tvp5146_init_reg_seq), | 1377 | /* TVP5147 Init/Power on Sequence */ |
1491 | .init_reg_seq = tvp5146_init_reg_seq, | ||
1492 | }; | ||
1493 | /* | ||
1494 | * TVP5147 Init/Power on Sequence | ||
1495 | */ | ||
1496 | static const struct tvp514x_reg tvp5147_init_reg_seq[] = { | 1378 | static const struct tvp514x_reg tvp5147_init_reg_seq[] = { |
1497 | {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x02}, | 1379 | {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x02}, |
1498 | {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00}, | 1380 | {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00}, |
@@ -1512,71 +1394,51 @@ static const struct tvp514x_reg tvp5147_init_reg_seq[] = { | |||
1512 | {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x00}, | 1394 | {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x00}, |
1513 | {TOK_WRITE, REG_OPERATION_MODE, 0x01}, | 1395 | {TOK_WRITE, REG_OPERATION_MODE, 0x01}, |
1514 | {TOK_WRITE, REG_OPERATION_MODE, 0x00}, | 1396 | {TOK_WRITE, REG_OPERATION_MODE, 0x00}, |
1397 | {TOK_TERM, 0, 0}, | ||
1515 | }; | 1398 | }; |
1516 | static const struct tvp514x_init_seq tvp5147_init = { | 1399 | |
1517 | .no_regs = ARRAY_SIZE(tvp5147_init_reg_seq), | 1400 | /* TVP5146M2/TVP5147M1 Init/Power on Sequence */ |
1518 | .init_reg_seq = tvp5147_init_reg_seq, | ||
1519 | }; | ||
1520 | /* | ||
1521 | * TVP5146M2/TVP5147M1 Init/Power on Sequence | ||
1522 | */ | ||
1523 | static const struct tvp514x_reg tvp514xm_init_reg_seq[] = { | 1401 | static const struct tvp514x_reg tvp514xm_init_reg_seq[] = { |
1524 | {TOK_WRITE, REG_OPERATION_MODE, 0x01}, | 1402 | {TOK_WRITE, REG_OPERATION_MODE, 0x01}, |
1525 | {TOK_WRITE, REG_OPERATION_MODE, 0x00}, | 1403 | {TOK_WRITE, REG_OPERATION_MODE, 0x00}, |
1404 | {TOK_TERM, 0, 0}, | ||
1526 | }; | 1405 | }; |
1527 | static const struct tvp514x_init_seq tvp514xm_init = { | 1406 | |
1528 | .no_regs = ARRAY_SIZE(tvp514xm_init_reg_seq), | 1407 | /** |
1529 | .init_reg_seq = tvp514xm_init_reg_seq, | ||
1530 | }; | ||
1531 | /* | ||
1532 | * I2C Device Table - | 1408 | * I2C Device Table - |
1533 | * | 1409 | * |
1534 | * name - Name of the actual device/chip. | 1410 | * name - Name of the actual device/chip. |
1535 | * driver_data - Driver data | 1411 | * driver_data - Driver data |
1536 | */ | 1412 | */ |
1537 | static const struct i2c_device_id tvp514x_id[] = { | 1413 | static const struct i2c_device_id tvp514x_id[] = { |
1538 | {"tvp5146", (unsigned long)&tvp5146_init}, | 1414 | {"tvp5146", (unsigned long)tvp5146_init_reg_seq}, |
1539 | {"tvp5146m2", (unsigned long)&tvp514xm_init}, | 1415 | {"tvp5146m2", (unsigned long)tvp514xm_init_reg_seq}, |
1540 | {"tvp5147", (unsigned long)&tvp5147_init}, | 1416 | {"tvp5147", (unsigned long)tvp5147_init_reg_seq}, |
1541 | {"tvp5147m1", (unsigned long)&tvp514xm_init}, | 1417 | {"tvp5147m1", (unsigned long)tvp514xm_init_reg_seq}, |
1542 | {}, | 1418 | {}, |
1543 | }; | 1419 | }; |
1544 | 1420 | ||
1545 | MODULE_DEVICE_TABLE(i2c, tvp514x_id); | 1421 | MODULE_DEVICE_TABLE(i2c, tvp514x_id); |
1546 | 1422 | ||
1547 | static struct i2c_driver tvp514x_i2c_driver = { | 1423 | static struct i2c_driver tvp514x_driver = { |
1548 | .driver = { | 1424 | .driver = { |
1549 | .name = TVP514X_MODULE_NAME, | 1425 | .owner = THIS_MODULE, |
1550 | .owner = THIS_MODULE, | 1426 | .name = TVP514X_MODULE_NAME, |
1551 | }, | 1427 | }, |
1552 | .probe = tvp514x_probe, | 1428 | .probe = tvp514x_probe, |
1553 | .remove = __exit_p(tvp514x_remove), | 1429 | .remove = tvp514x_remove, |
1554 | .id_table = tvp514x_id, | 1430 | .id_table = tvp514x_id, |
1555 | }; | 1431 | }; |
1556 | 1432 | ||
1557 | /** | ||
1558 | * tvp514x_init | ||
1559 | * | ||
1560 | * Module init function | ||
1561 | */ | ||
1562 | static int __init tvp514x_init(void) | 1433 | static int __init tvp514x_init(void) |
1563 | { | 1434 | { |
1564 | return i2c_add_driver(&tvp514x_i2c_driver); | 1435 | return i2c_add_driver(&tvp514x_driver); |
1565 | } | 1436 | } |
1566 | 1437 | ||
1567 | /** | 1438 | static void __exit tvp514x_exit(void) |
1568 | * tvp514x_cleanup | ||
1569 | * | ||
1570 | * Module exit function | ||
1571 | */ | ||
1572 | static void __exit tvp514x_cleanup(void) | ||
1573 | { | 1439 | { |
1574 | i2c_del_driver(&tvp514x_i2c_driver); | 1440 | i2c_del_driver(&tvp514x_driver); |
1575 | } | 1441 | } |
1576 | 1442 | ||
1577 | module_init(tvp514x_init); | 1443 | module_init(tvp514x_init); |
1578 | module_exit(tvp514x_cleanup); | 1444 | module_exit(tvp514x_exit); |
1579 | |||
1580 | MODULE_AUTHOR("Texas Instruments"); | ||
1581 | MODULE_DESCRIPTION("TVP514X linux decoder driver"); | ||
1582 | MODULE_LICENSE("GPL"); | ||