* [RFC PATCH 0/5] Use control framework in cafe_ccic and s_config removal @ 2011-01-07 12:47 Hans Verkuil 2011-01-07 12:47 ` [RFC PATCH 1/5] v4l2-subdev: remove core.s_config and v4l2_i2c_new_subdev_cfg() Hans Verkuil 0 siblings, 1 reply; 13+ messages in thread From: Hans Verkuil @ 2011-01-07 12:47 UTC (permalink / raw) To: linux-media; +Cc: Jonathan Corbet, Laurent Pinchart Hi Jon, Laurent, This patch series converts the OLPC cafe_ccic driver to the new control framework. It turned out that this depended on the removal of the legacy s_config subdev operation. I originally created the ov7670 controls in s_config, but it turned out that s_config is called after v4l2_device_register_subdev, so v4l2_device_register_subdev is unable to 'inherit' the ov7670 controls in cafe_ccic since there aren't any yet. Another reason why s_config is a bad idea. So the first patch removes s_config and v4l2_i2c_new_subdev_cfg and converts any users (cafe_ccic/ov7670 among them) to v4l2_i2c_new_subdev_board, which is what God (i.e. Jean Delvare) intended. :-) The second patch adds the (un)register internal ops allowing subdev drivers to do some work after the subdevice is registered with a v4l2_device. So here the sd->v4l2_dev pointer is set. Laurent, is this sufficient for the upcoming omap3 sub-devices? The third patch fixes a small bug in v4l2_ctrl_handler_setup() that is required for the ov7670 conversion. This bug does not affect any existing drivers. The last two patches convert ov7670 and cafe_ccic to the V4L2 control framework. This saves over a 100 lines of code and adds full support of the control API (including extended controls) to the drivers. This has been extensively tested on my humble OLPC laptop (and it took me 4-5 hours just to get the damn thing up and running with these drivers). Special attention was given to the handling of gain/autogain and exposure/autoexposure. The way this works is that setting the gain on its own will turn off autogain (this conforms to the current behavior of ov7670), setting autogain and gain atomically will only set the gain if autogain is set to manual. Ditto for exposure/autoexposure. The only question is: is the current behavior of implicitly turning off autogain when setting a new gain value correct? I think setting the gain in that case should do nothing. On the other hand, I don't know if there is any code that depends on this behavior, so perhaps we should just leave it as is. Jon, can you take a look and let me know if it is OK with you? Regards, Hans ov7670.c | 296 ++++++++++++++++++++++++--------------------------------------- 1 file changed, 116 insertions(+), 180 deletions(-) cafe_ccic.c | 59 +++++++++++------------------------------------------------ 1 file changed, 11 insertions(+), 48 deletions(-) ^ permalink raw reply [flat|nested] 13+ messages in thread
* [RFC PATCH 1/5] v4l2-subdev: remove core.s_config and v4l2_i2c_new_subdev_cfg() 2011-01-07 12:47 [RFC PATCH 0/5] Use control framework in cafe_ccic and s_config removal Hans Verkuil @ 2011-01-07 12:47 ` Hans Verkuil 2011-01-07 12:47 ` [RFC PATCH 2/5] v4l2-subdev: add (un)register internal ops Hans Verkuil ` (5 more replies) 0 siblings, 6 replies; 13+ messages in thread From: Hans Verkuil @ 2011-01-07 12:47 UTC (permalink / raw) To: linux-media; +Cc: Jonathan Corbet, Laurent Pinchart The core.s_config op was meant for legacy drivers that needed to work with old pre-2.6.26 kernels. This is no longer relevant. Unfortunately, this op was incorrectly called from several drivers. Replace those occurences with proper i2c_board_info structs and call v4l2_i2c_new_subdev_board. After these changes v4l2_i2c_new_subdev_cfg() was no longer used, so remove that function as well. Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> --- drivers/media/video/cafe_ccic.c | 11 +++- drivers/media/video/cx25840/cx25840-core.c | 22 ++------ drivers/media/video/em28xx/em28xx-cards.c | 18 ++++--- drivers/media/video/ivtv/ivtv-i2c.c | 9 +++- drivers/media/video/mt9v011.c | 29 ++++------- drivers/media/video/mt9v011.h | 36 ------------- drivers/media/video/mt9v011_regs.h | 36 +++++++++++++ drivers/media/video/ov7670.c | 74 ++++++++++++---------------- drivers/media/video/sr030pc30.c | 10 ---- drivers/media/video/v4l2-common.c | 19 +------ include/media/mt9v011.h | 17 ++++++ include/media/v4l2-common.h | 13 +----- include/media/v4l2-subdev.h | 6 +-- 13 files changed, 130 insertions(+), 170 deletions(-) delete mode 100644 drivers/media/video/mt9v011.h create mode 100644 drivers/media/video/mt9v011_regs.h create mode 100644 include/media/mt9v011.h diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 789087c..7488b47 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -2001,6 +2001,11 @@ static int cafe_pci_probe(struct pci_dev *pdev, .min_width = 320, .min_height = 240, }; + struct i2c_board_info ov7670_info = { + .type = "ov7670", + .addr = 0x42, + .platform_data = &sensor_cfg, + }; /* * Start putting together one of our big camera structures. @@ -2062,9 +2067,9 @@ static int cafe_pci_probe(struct pci_dev *pdev, if (dmi_check_system(olpc_xo1_dmi)) sensor_cfg.clock_speed = 45; - cam->sensor_addr = 0x42; - cam->sensor = v4l2_i2c_new_subdev_cfg(&cam->v4l2_dev, &cam->i2c_adapter, - "ov7670", 0, &sensor_cfg, cam->sensor_addr, NULL); + cam->sensor_addr = ov7670_info.addr; + cam->sensor = v4l2_i2c_new_subdev_board(&cam->v4l2_dev, &cam->i2c_adapter, + &ov7670_info, NULL); if (cam->sensor == NULL) { ret = -ENODEV; goto out_smbus; diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index dfb198d..9b384ac 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -1682,20 +1682,6 @@ static int cx25840_log_status(struct v4l2_subdev *sd) return 0; } -static int cx25840_s_config(struct v4l2_subdev *sd, int irq, void *platform_data) -{ - struct cx25840_state *state = to_state(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - - if (platform_data) { - struct cx25840_platform_data *pdata = platform_data; - - state->pvr150_workaround = pdata->pvr150_workaround; - set_input(client, state->vid_input, state->aud_input); - } - return 0; -} - static int cx23885_irq_handler(struct v4l2_subdev *sd, u32 status, bool *handled) { @@ -1787,7 +1773,6 @@ static const struct v4l2_ctrl_ops cx25840_ctrl_ops = { static const struct v4l2_subdev_core_ops cx25840_core_ops = { .log_status = cx25840_log_status, - .s_config = cx25840_s_config, .g_chip_ident = cx25840_g_chip_ident, .g_ctrl = v4l2_subdev_g_ctrl, .s_ctrl = v4l2_subdev_s_ctrl, @@ -1974,7 +1959,6 @@ static int cx25840_probe(struct i2c_client *client, state->vid_input = CX25840_COMPOSITE7; state->aud_input = CX25840_AUDIO8; state->audclk_freq = 48000; - state->pvr150_workaround = 0; state->audmode = V4L2_TUNER_MODE_LANG1; state->vbi_line_offset = 8; state->id = id; @@ -2019,6 +2003,12 @@ static int cx25840_probe(struct i2c_client *client, v4l2_ctrl_cluster(2, &state->volume); v4l2_ctrl_handler_setup(&state->hdl); + if (client->dev.platform_data) { + struct cx25840_platform_data *pdata = client->dev.platform_data; + + state->pvr150_workaround = pdata->pvr150_workaround; + } + cx25840_ir_probe(sd); return 0; } diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 8af302b..2822aeb 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -33,6 +33,7 @@ #include <media/saa7115.h> #include <media/tvp5150.h> #include <media/tvaudio.h> +#include <media/mt9v011.h> #include <media/i2c-addr.h> #include <media/tveeprom.h> #include <media/v4l2-common.h> @@ -1917,11 +1918,6 @@ static unsigned short tvp5150_addrs[] = { I2C_CLIENT_END }; -static unsigned short mt9v011_addrs[] = { - 0xba >> 1, - I2C_CLIENT_END -}; - static unsigned short msp3400_addrs[] = { 0x80 >> 1, 0x88 >> 1, @@ -2623,11 +2619,17 @@ void em28xx_card_setup(struct em28xx *dev) "tvp5150", 0, tvp5150_addrs); if (dev->em28xx_sensor == EM28XX_MT9V011) { + struct mt9v011_platform_data pdata; + struct i2c_board_info mt9v011_info = { + .type = "mt9v011", + .addr = 0xba >> 1, + .platform_data = &pdata, + }; struct v4l2_subdev *sd; - sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, - &dev->i2c_adap, "mt9v011", 0, mt9v011_addrs); - v4l2_subdev_call(sd, core, s_config, 0, &dev->sensor_xtal); + pdata.xtal = dev->sensor_xtal; + sd = v4l2_i2c_new_subdev_board(&dev->v4l2_dev, &dev->i2c_adap, + &mt9v011_info, NULL); } diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c index e103b8f..9fb86a0 100644 --- a/drivers/media/video/ivtv/ivtv-i2c.c +++ b/drivers/media/video/ivtv/ivtv-i2c.c @@ -300,10 +300,15 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx) adap, type, 0, I2C_ADDRS(hw_addrs[idx])); } else if (hw == IVTV_HW_CX25840) { struct cx25840_platform_data pdata; + struct i2c_board_info cx25840_info = { + .type = "cx25840", + .addr = hw_addrs[idx], + .platform_data = &pdata, + }; pdata.pvr150_workaround = itv->pvr150_workaround; - sd = v4l2_i2c_new_subdev_cfg(&itv->v4l2_dev, - adap, type, 0, &pdata, hw_addrs[idx], NULL); + sd = v4l2_i2c_new_subdev_board(&itv->v4l2_dev, adap, + &cx25840_info, NULL); } else { sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, hw_addrs[idx], NULL); diff --git a/drivers/media/video/mt9v011.c b/drivers/media/video/mt9v011.c index 209ff97..f3f73d3 100644 --- a/drivers/media/video/mt9v011.c +++ b/drivers/media/video/mt9v011.c @@ -12,7 +12,8 @@ #include <asm/div64.h> #include <media/v4l2-device.h> #include <media/v4l2-chip-ident.h> -#include "mt9v011.h" +#include <media/mt9v011.h> +#include "mt9v011_regs.h" MODULE_DESCRIPTION("Micron mt9v011 sensor driver"); MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); @@ -469,23 +470,6 @@ static int mt9v011_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt return 0; } -static int mt9v011_s_config(struct v4l2_subdev *sd, int dumb, void *data) -{ - struct mt9v011 *core = to_mt9v011(sd); - unsigned *xtal = data; - - v4l2_dbg(1, debug, sd, "s_config called\n"); - - if (xtal) { - core->xtal = *xtal; - v4l2_dbg(1, debug, sd, "xtal set to %d.%03d MHz\n", - *xtal / 1000000, (*xtal / 1000) % 1000); - } - - return 0; -} - - #ifdef CONFIG_VIDEO_ADV_DEBUG static int mt9v011_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) @@ -536,7 +520,6 @@ static const struct v4l2_subdev_core_ops mt9v011_core_ops = { .g_ctrl = mt9v011_g_ctrl, .s_ctrl = mt9v011_s_ctrl, .reset = mt9v011_reset, - .s_config = mt9v011_s_config, .g_chip_ident = mt9v011_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG .g_register = mt9v011_g_register, @@ -596,6 +579,14 @@ static int mt9v011_probe(struct i2c_client *c, core->height = 480; core->xtal = 27000000; /* Hz */ + if (c->dev.platform_data) { + struct mt9v011_platform_data *pdata = c->dev.platform_data; + + core->xtal = pdata->xtal; + v4l2_dbg(1, debug, sd, "xtal set to %d.%03d MHz\n", + core->xtal / 1000000, (core->xtal / 1000) % 1000); + } + v4l_info(c, "chip found @ 0x%02x (%s - chip version 0x%04x)\n", c->addr << 1, c->adapter->name, version); diff --git a/drivers/media/video/mt9v011.h b/drivers/media/video/mt9v011.h deleted file mode 100644 index 3350fd6..0000000 --- a/drivers/media/video/mt9v011.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * mt9v011 -Micron 1/4-Inch VGA Digital Image Sensor - * - * Copyright (c) 2009 Mauro Carvalho Chehab (mchehab@redhat.com) - * This code is placed under the terms of the GNU General Public License v2 - */ - -#ifndef MT9V011_H_ -#define MT9V011_H_ - -#define R00_MT9V011_CHIP_VERSION 0x00 -#define R01_MT9V011_ROWSTART 0x01 -#define R02_MT9V011_COLSTART 0x02 -#define R03_MT9V011_HEIGHT 0x03 -#define R04_MT9V011_WIDTH 0x04 -#define R05_MT9V011_HBLANK 0x05 -#define R06_MT9V011_VBLANK 0x06 -#define R07_MT9V011_OUT_CTRL 0x07 -#define R09_MT9V011_SHUTTER_WIDTH 0x09 -#define R0A_MT9V011_CLK_SPEED 0x0a -#define R0B_MT9V011_RESTART 0x0b -#define R0C_MT9V011_SHUTTER_DELAY 0x0c -#define R0D_MT9V011_RESET 0x0d -#define R1E_MT9V011_DIGITAL_ZOOM 0x1e -#define R20_MT9V011_READ_MODE 0x20 -#define R2B_MT9V011_GREEN_1_GAIN 0x2b -#define R2C_MT9V011_BLUE_GAIN 0x2c -#define R2D_MT9V011_RED_GAIN 0x2d -#define R2E_MT9V011_GREEN_2_GAIN 0x2e -#define R35_MT9V011_GLOBAL_GAIN 0x35 -#define RF1_MT9V011_CHIP_ENABLE 0xf1 - -#define MT9V011_VERSION 0x8232 -#define MT9V011_REV_B_VERSION 0x8243 - -#endif diff --git a/drivers/media/video/mt9v011_regs.h b/drivers/media/video/mt9v011_regs.h new file mode 100644 index 0000000..d6a5a08 --- /dev/null +++ b/drivers/media/video/mt9v011_regs.h @@ -0,0 +1,36 @@ +/* + * mt9v011 -Micron 1/4-Inch VGA Digital Image Sensor + * + * Copyright (c) 2009 Mauro Carvalho Chehab (mchehab@redhat.com) + * This code is placed under the terms of the GNU General Public License v2 + */ + +#ifndef MT9V011_REGS_H_ +#define MT9V011_REGS_H_ + +#define R00_MT9V011_CHIP_VERSION 0x00 +#define R01_MT9V011_ROWSTART 0x01 +#define R02_MT9V011_COLSTART 0x02 +#define R03_MT9V011_HEIGHT 0x03 +#define R04_MT9V011_WIDTH 0x04 +#define R05_MT9V011_HBLANK 0x05 +#define R06_MT9V011_VBLANK 0x06 +#define R07_MT9V011_OUT_CTRL 0x07 +#define R09_MT9V011_SHUTTER_WIDTH 0x09 +#define R0A_MT9V011_CLK_SPEED 0x0a +#define R0B_MT9V011_RESTART 0x0b +#define R0C_MT9V011_SHUTTER_DELAY 0x0c +#define R0D_MT9V011_RESET 0x0d +#define R1E_MT9V011_DIGITAL_ZOOM 0x1e +#define R20_MT9V011_READ_MODE 0x20 +#define R2B_MT9V011_GREEN_1_GAIN 0x2b +#define R2C_MT9V011_BLUE_GAIN 0x2c +#define R2D_MT9V011_RED_GAIN 0x2d +#define R2E_MT9V011_GREEN_2_GAIN 0x2e +#define R35_MT9V011_GLOBAL_GAIN 0x35 +#define RF1_MT9V011_CHIP_ENABLE 0xf1 + +#define MT9V011_VERSION 0x8232 +#define MT9V011_REV_B_VERSION 0x8243 + +#endif diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c index c881a64..d4e7c11 100644 --- a/drivers/media/video/ov7670.c +++ b/drivers/media/video/ov7670.c @@ -1449,47 +1449,6 @@ static int ov7670_g_chip_ident(struct v4l2_subdev *sd, return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_OV7670, 0); } -static int ov7670_s_config(struct v4l2_subdev *sd, int dumb, void *data) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct ov7670_config *config = data; - struct ov7670_info *info = to_state(sd); - int ret; - - info->clock_speed = 30; /* default: a guess */ - - /* - * Must apply configuration before initializing device, because it - * selects I/O method. - */ - if (config) { - info->min_width = config->min_width; - info->min_height = config->min_height; - info->use_smbus = config->use_smbus; - - if (config->clock_speed) - info->clock_speed = config->clock_speed; - } - - /* Make sure it's an ov7670 */ - ret = ov7670_detect(sd); - if (ret) { - v4l_dbg(1, debug, client, - "chip found @ 0x%x (%s) is not an ov7670 chip.\n", - client->addr << 1, client->adapter->name); - kfree(info); - return ret; - } - v4l_info(client, "chip found @ 0x%02x (%s)\n", - client->addr << 1, client->adapter->name); - - info->fmt = &ov7670_formats[0]; - info->sat = 128; /* Review this */ - info->clkrc = info->clock_speed / 30; - - return 0; -} - #ifdef CONFIG_VIDEO_ADV_DEBUG static int ov7670_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { @@ -1528,7 +1487,6 @@ static const struct v4l2_subdev_core_ops ov7670_core_ops = { .s_ctrl = ov7670_s_ctrl, .queryctrl = ov7670_queryctrl, .reset = ov7670_reset, - .s_config = ov7670_s_config, .init = ov7670_init, #ifdef CONFIG_VIDEO_ADV_DEBUG .g_register = ov7670_g_register, @@ -1558,6 +1516,7 @@ static int ov7670_probe(struct i2c_client *client, { struct v4l2_subdev *sd; struct ov7670_info *info; + int ret; info = kzalloc(sizeof(struct ov7670_info), GFP_KERNEL); if (info == NULL) @@ -1565,6 +1524,37 @@ static int ov7670_probe(struct i2c_client *client, sd = &info->sd; v4l2_i2c_subdev_init(sd, client, &ov7670_ops); + info->clock_speed = 30; /* default: a guess */ + if (client->dev.platform_data) { + struct ov7670_config *config = client->dev.platform_data; + + /* + * Must apply configuration before initializing device, because it + * selects I/O method. + */ + info->min_width = config->min_width; + info->min_height = config->min_height; + info->use_smbus = config->use_smbus; + + if (config->clock_speed) + info->clock_speed = config->clock_speed; + } + + /* Make sure it's an ov7670 */ + ret = ov7670_detect(sd); + if (ret) { + v4l_dbg(1, debug, client, + "chip found @ 0x%x (%s) is not an ov7670 chip.\n", + client->addr << 1, client->adapter->name); + kfree(info); + return ret; + } + v4l_info(client, "chip found @ 0x%02x (%s)\n", + client->addr << 1, client->adapter->name); + + info->fmt = &ov7670_formats[0]; + info->sat = 128; /* Review this */ + info->clkrc = info->clock_speed / 30; return 0; } diff --git a/drivers/media/video/sr030pc30.c b/drivers/media/video/sr030pc30.c index 864696b..c901721 100644 --- a/drivers/media/video/sr030pc30.c +++ b/drivers/media/video/sr030pc30.c @@ -714,15 +714,6 @@ static int sr030pc30_base_config(struct v4l2_subdev *sd) return ret; } -static int sr030pc30_s_config(struct v4l2_subdev *sd, - int irq, void *platform_data) -{ - struct sr030pc30_info *info = to_sr030pc30(sd); - - info->pdata = platform_data; - return 0; -} - static int sr030pc30_s_stream(struct v4l2_subdev *sd, int enable) { return 0; @@ -763,7 +754,6 @@ static int sr030pc30_s_power(struct v4l2_subdev *sd, int on) } static const struct v4l2_subdev_core_ops sr030pc30_core_ops = { - .s_config = sr030pc30_s_config, .s_power = sr030pc30_s_power, .queryctrl = sr030pc30_queryctrl, .s_ctrl = sr030pc30_s_ctrl, diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index 3f0871b..810eef4 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c @@ -407,18 +407,6 @@ struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev, /* Decrease the module use count to match the first try_module_get. */ module_put(client->driver->driver.owner); - if (sd) { - /* We return errors from v4l2_subdev_call only if we have the - callback as the .s_config is not mandatory */ - int err = v4l2_subdev_call(sd, core, s_config, - info->irq, info->platform_data); - - if (err && err != -ENOIOCTLCMD) { - v4l2_device_unregister_subdev(sd); - sd = NULL; - } - } - error: /* If we have a client but no subdev, then something went wrong and we must unregister the client. */ @@ -428,9 +416,8 @@ error: } EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_board); -struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev, +struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev, struct i2c_adapter *adapter, const char *client_type, - int irq, void *platform_data, u8 addr, const unsigned short *probe_addrs) { struct i2c_board_info info; @@ -440,12 +427,10 @@ struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev, memset(&info, 0, sizeof(info)); strlcpy(info.type, client_type, sizeof(info.type)); info.addr = addr; - info.irq = irq; - info.platform_data = platform_data; return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, &info, probe_addrs); } -EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_cfg); +EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev); /* Return i2c client address of v4l2_subdev. */ unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd) diff --git a/include/media/mt9v011.h b/include/media/mt9v011.h new file mode 100644 index 0000000..ea29fc7 --- /dev/null +++ b/include/media/mt9v011.h @@ -0,0 +1,17 @@ +/* mt9v011 sensor + * + * Copyright (C) 2011 Hans Verkuil <hverkuil@xs4all.nl> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __MT9V011_H__ +#define __MT9V011_H__ + +struct mt9v011_platform_data { + unsigned xtal; /* Hz */ +}; + +#endif diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index 2d65b35..a659319 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -138,21 +138,10 @@ struct v4l2_subdev_ops; /* Load an i2c module and return an initialized v4l2_subdev struct. The client_type argument is the name of the chip that's on the adapter. */ -struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev, +struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev, struct i2c_adapter *adapter, const char *client_type, - int irq, void *platform_data, u8 addr, const unsigned short *probe_addrs); -/* Load an i2c module and return an initialized v4l2_subdev struct. - The client_type argument is the name of the chip that's on the adapter. */ -static inline struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev, - struct i2c_adapter *adapter, const char *client_type, - u8 addr, const unsigned short *probe_addrs) -{ - return v4l2_i2c_new_subdev_cfg(v4l2_dev, adapter, client_type, 0, NULL, - addr, probe_addrs); -} - struct i2c_board_info; struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev, diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index b0316a7..42fbe46 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -106,10 +106,7 @@ struct v4l2_subdev_io_pin_config { u8 strength; /* Pin drive strength */ }; -/* s_config: if set, then it is always called by the v4l2_i2c_new_subdev* - functions after the v4l2_subdev was registered. It is used to pass - platform data to the subdev which can be used during initialization. - +/* s_io_pin_config: configure one or more chip I/O pins for chips that multiplex different internal signal pads out to IO pins. This function takes a pointer to an array of 'n' pin configuration entries, one for @@ -141,7 +138,6 @@ struct v4l2_subdev_io_pin_config { struct v4l2_subdev_core_ops { int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip); int (*log_status)(struct v4l2_subdev *sd); - int (*s_config)(struct v4l2_subdev *sd, int irq, void *platform_data); int (*s_io_pin_config)(struct v4l2_subdev *sd, size_t n, struct v4l2_subdev_io_pin_config *pincfg); int (*init)(struct v4l2_subdev *sd, u32 val); -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [RFC PATCH 2/5] v4l2-subdev: add (un)register internal ops 2011-01-07 12:47 ` [RFC PATCH 1/5] v4l2-subdev: remove core.s_config and v4l2_i2c_new_subdev_cfg() Hans Verkuil @ 2011-01-07 12:47 ` Hans Verkuil 2011-01-07 13:37 ` Laurent Pinchart 2011-01-07 12:47 ` [RFC PATCH 3/5] v4l2-ctrls: v4l2_ctrl_handler_setup must set has_new to 1 Hans Verkuil ` (4 subsequent siblings) 5 siblings, 1 reply; 13+ messages in thread From: Hans Verkuil @ 2011-01-07 12:47 UTC (permalink / raw) To: linux-media; +Cc: Jonathan Corbet, Laurent Pinchart Some subdevs need to call into the board code after they are registered and have a valid struct v4l2_device pointer. The s_config op was abused for this, but now that it is removed we need a cleaner way of solving this. So this patch adds a struct with internal ops that the v4l2 core can call. Currently only two ops exist: register and unregister. Subdevs can implement these to call the board code and pass it the v4l2_device pointer, which the board code can then use to get access to the struct that embeds the v4l2_device. It is expected that in the future open and close ops will also be added. Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> --- drivers/media/video/v4l2-device.c | 4 ++++ include/media/v4l2-subdev.h | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 0 deletions(-) diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c index 7fe6f92..0780c32 100644 --- a/drivers/media/video/v4l2-device.c +++ b/drivers/media/video/v4l2-device.c @@ -131,6 +131,8 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, if (err) return err; sd->v4l2_dev = v4l2_dev; + if (sd->internal_ops && sd->internal_ops->registered) + sd->internal_ops->registered(sd); spin_lock(&v4l2_dev->lock); list_add_tail(&sd->list, &v4l2_dev->subdevs); spin_unlock(&v4l2_dev->lock); @@ -146,6 +148,8 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd) spin_lock(&sd->v4l2_dev->lock); list_del(&sd->list); spin_unlock(&sd->v4l2_dev->lock); + if (sd->internal_ops && sd->internal_ops->unregistered) + sd->internal_ops->unregistered(sd); sd->v4l2_dev = NULL; module_put(sd->owner); } diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 42fbe46..f559562 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -411,6 +411,21 @@ struct v4l2_subdev_ops { const struct v4l2_subdev_sensor_ops *sensor; }; +/* + * Internal ops. Never call this from drivers, only the v4l2 framework can call + * these ops. + * + * registered: called when this subdev is registered. When called the v4l2_dev + * field is set to the correct v4l2_device. + * + * unregistered: called when this subdev is unregistered. When called the + * v4l2_dev field is still set to the correct v4l2_device. + */ +struct v4l2_subdev_internal_ops { + int (*registered)(struct v4l2_subdev *sd); + int (*unregistered)(struct v4l2_subdev *sd); +}; + #define V4L2_SUBDEV_NAME_SIZE 32 /* Set this flag if this subdev is a i2c device. */ @@ -427,6 +442,8 @@ struct v4l2_subdev { u32 flags; struct v4l2_device *v4l2_dev; const struct v4l2_subdev_ops *ops; + /* Never call these internal ops from within a driver! */ + const struct v4l2_subdev_internal_ops *internal_ops; /* The control handler of this subdev. May be NULL. */ struct v4l2_ctrl_handler *ctrl_handler; /* name must be unique */ -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [RFC PATCH 2/5] v4l2-subdev: add (un)register internal ops 2011-01-07 12:47 ` [RFC PATCH 2/5] v4l2-subdev: add (un)register internal ops Hans Verkuil @ 2011-01-07 13:37 ` Laurent Pinchart 0 siblings, 0 replies; 13+ messages in thread From: Laurent Pinchart @ 2011-01-07 13:37 UTC (permalink / raw) To: Hans Verkuil; +Cc: linux-media, Jonathan Corbet Hi Hans, Thanks for the patch. On Friday 07 January 2011 13:47:32 Hans Verkuil wrote: > Some subdevs need to call into the board code after they are registered > and have a valid struct v4l2_device pointer. The s_config op was abused > for this, but now that it is removed we need a cleaner way of solving this. > > So this patch adds a struct with internal ops that the v4l2 core can call. > > Currently only two ops exist: register and unregister. Subdevs can > implement these to call the board code and pass it the v4l2_device > pointer, which the board code can then use to get access to the struct > that embeds the v4l2_device. > > It is expected that in the future open and close ops will also be added. > > Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> -- Regards, Laurent Pinchart ^ permalink raw reply [flat|nested] 13+ messages in thread
* [RFC PATCH 3/5] v4l2-ctrls: v4l2_ctrl_handler_setup must set has_new to 1 2011-01-07 12:47 ` [RFC PATCH 1/5] v4l2-subdev: remove core.s_config and v4l2_i2c_new_subdev_cfg() Hans Verkuil 2011-01-07 12:47 ` [RFC PATCH 2/5] v4l2-subdev: add (un)register internal ops Hans Verkuil @ 2011-01-07 12:47 ` Hans Verkuil 2011-01-07 13:25 ` Laurent Pinchart 2011-01-07 12:47 ` [RFC PATCH 4/5] ov7670: use the control framework Hans Verkuil ` (3 subsequent siblings) 5 siblings, 1 reply; 13+ messages in thread From: Hans Verkuil @ 2011-01-07 12:47 UTC (permalink / raw) To: linux-media; +Cc: Jonathan Corbet, Laurent Pinchart Drivers can use the has_new field to determine if a new value was specified for a control. The v4l2_ctrl_handler_setup() must always set this to 1 since the setup has to force a full update of all controls. Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> --- drivers/media/video/v4l2-ctrls.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c index 8f81efc..64f56bb 100644 --- a/drivers/media/video/v4l2-ctrls.c +++ b/drivers/media/video/v4l2-ctrls.c @@ -1280,8 +1280,10 @@ int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl) if (ctrl->done) continue; - for (i = 0; i < master->ncontrols; i++) + for (i = 0; i < master->ncontrols; i++) { cur_to_new(master->cluster[i]); + master->cluster[i]->has_new = 1; + } /* Skip button controls and read-only controls. */ if (ctrl->type == V4L2_CTRL_TYPE_BUTTON || -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [RFC PATCH 3/5] v4l2-ctrls: v4l2_ctrl_handler_setup must set has_new to 1 2011-01-07 12:47 ` [RFC PATCH 3/5] v4l2-ctrls: v4l2_ctrl_handler_setup must set has_new to 1 Hans Verkuil @ 2011-01-07 13:25 ` Laurent Pinchart 2011-01-07 21:22 ` Hans Verkuil 0 siblings, 1 reply; 13+ messages in thread From: Laurent Pinchart @ 2011-01-07 13:25 UTC (permalink / raw) To: Hans Verkuil; +Cc: linux-media, Jonathan Corbet Hi Hans, On Friday 07 January 2011 13:47:33 Hans Verkuil wrote: > Drivers can use the has_new field to determine if a new value was specified > for a control. The v4l2_ctrl_handler_setup() must always set this to 1 > since the setup has to force a full update of all controls. According to include/media/v4l2-ctrls.h, has_new is a "Internal flag: set when there is a valid new value". Drivers should then not use it. If you want to use the flag in a driver, the comment should be changed and its usage should be documented in Documentation/video4linux/v4l2-controls.txt. > Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> > --- > drivers/media/video/v4l2-ctrls.c | 4 +++- > 1 files changed, 3 insertions(+), 1 deletions(-) > > diff --git a/drivers/media/video/v4l2-ctrls.c > b/drivers/media/video/v4l2-ctrls.c index 8f81efc..64f56bb 100644 > --- a/drivers/media/video/v4l2-ctrls.c > +++ b/drivers/media/video/v4l2-ctrls.c > @@ -1280,8 +1280,10 @@ int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler > *hdl) if (ctrl->done) > continue; > > - for (i = 0; i < master->ncontrols; i++) > + for (i = 0; i < master->ncontrols; i++) { > cur_to_new(master->cluster[i]); > + master->cluster[i]->has_new = 1; > + } > > /* Skip button controls and read-only controls. */ > if (ctrl->type == V4L2_CTRL_TYPE_BUTTON || -- Regards, Laurent Pinchart ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFC PATCH 3/5] v4l2-ctrls: v4l2_ctrl_handler_setup must set has_new to 1 2011-01-07 13:25 ` Laurent Pinchart @ 2011-01-07 21:22 ` Hans Verkuil 0 siblings, 0 replies; 13+ messages in thread From: Hans Verkuil @ 2011-01-07 21:22 UTC (permalink / raw) To: Laurent Pinchart; +Cc: linux-media, Jonathan Corbet On Friday, January 07, 2011 14:25:41 Laurent Pinchart wrote: > Hi Hans, > > On Friday 07 January 2011 13:47:33 Hans Verkuil wrote: > > Drivers can use the has_new field to determine if a new value was specified > > for a control. The v4l2_ctrl_handler_setup() must always set this to 1 > > since the setup has to force a full update of all controls. > > According to include/media/v4l2-ctrls.h, has_new is a "Internal flag: set when > there is a valid new value". Drivers should then not use it. > > If you want to use the flag in a driver, the comment should be changed and its > usage should be documented in Documentation/video4linux/v4l2-controls.txt. Good catch. I'll document this. Regards, Hans > > > Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> > > --- > > drivers/media/video/v4l2-ctrls.c | 4 +++- > > 1 files changed, 3 insertions(+), 1 deletions(-) > > > > diff --git a/drivers/media/video/v4l2-ctrls.c > > b/drivers/media/video/v4l2-ctrls.c index 8f81efc..64f56bb 100644 > > --- a/drivers/media/video/v4l2-ctrls.c > > +++ b/drivers/media/video/v4l2-ctrls.c > > @@ -1280,8 +1280,10 @@ int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler > > *hdl) if (ctrl->done) > > continue; > > > > - for (i = 0; i < master->ncontrols; i++) > > + for (i = 0; i < master->ncontrols; i++) { > > cur_to_new(master->cluster[i]); > > + master->cluster[i]->has_new = 1; > > + } > > > > /* Skip button controls and read-only controls. */ > > if (ctrl->type == V4L2_CTRL_TYPE_BUTTON || > > -- Hans Verkuil - video4linux developer - sponsored by Cisco ^ permalink raw reply [flat|nested] 13+ messages in thread
* [RFC PATCH 4/5] ov7670: use the control framework 2011-01-07 12:47 ` [RFC PATCH 1/5] v4l2-subdev: remove core.s_config and v4l2_i2c_new_subdev_cfg() Hans Verkuil 2011-01-07 12:47 ` [RFC PATCH 2/5] v4l2-subdev: add (un)register internal ops Hans Verkuil 2011-01-07 12:47 ` [RFC PATCH 3/5] v4l2-ctrls: v4l2_ctrl_handler_setup must set has_new to 1 Hans Verkuil @ 2011-01-07 12:47 ` Hans Verkuil 2011-01-07 12:47 ` [RFC PATCH 5/5] cafe_ccic: implement " Hans Verkuil ` (2 subsequent siblings) 5 siblings, 0 replies; 13+ messages in thread From: Hans Verkuil @ 2011-01-07 12:47 UTC (permalink / raw) To: linux-media; +Cc: Jonathan Corbet, Laurent Pinchart Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> --- drivers/media/video/ov7670.c | 296 ++++++++++++++++------------------------- 1 files changed, 116 insertions(+), 180 deletions(-) diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c index d4e7c11..4da8b62 100644 --- a/drivers/media/video/ov7670.c +++ b/drivers/media/video/ov7670.c @@ -19,6 +19,7 @@ #include <media/v4l2-device.h> #include <media/v4l2-chip-ident.h> #include <media/v4l2-mediabus.h> +#include <media/v4l2-ctrls.h> #include "ov7670.h" @@ -191,9 +192,23 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); struct ov7670_format_struct; /* coming later */ struct ov7670_info { struct v4l2_subdev sd; + struct v4l2_ctrl_handler hdl; + struct { + /* gain cluster */ + struct v4l2_ctrl *auto_gain; + struct v4l2_ctrl *gain; + }; + struct { + /* exposure cluster */ + struct v4l2_ctrl *auto_exposure; + struct v4l2_ctrl *exposure; + }; + struct { + /* saturation/hue cluster */ + struct v4l2_ctrl *saturation; + struct v4l2_ctrl *hue; + }; struct ov7670_format_struct *fmt; /* Current format */ - unsigned char sat; /* Saturation value */ - int hue; /* Hue value */ int min_width; /* Filter out smaller sizes */ int min_height; /* Filter out smaller sizes */ int clock_speed; /* External clock speed (MHz) */ @@ -206,6 +221,11 @@ static inline struct ov7670_info *to_state(struct v4l2_subdev *sd) return container_of(sd, struct ov7670_info, sd); } +static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl) +{ + return &container_of(ctrl->handler, struct ov7670_info, hdl)->sd; +} + /* @@ -1043,23 +1063,23 @@ static int ov7670_cosine(int theta) static void ov7670_calc_cmatrix(struct ov7670_info *info, - int matrix[CMATRIX_LEN]) + int matrix[CMATRIX_LEN], int sat, int hue) { int i; /* * Apply the current saturation setting first. */ for (i = 0; i < CMATRIX_LEN; i++) - matrix[i] = (info->fmt->cmatrix[i]*info->sat) >> 7; + matrix[i] = (info->fmt->cmatrix[i] * sat) >> 7; /* * Then, if need be, rotate the hue value. */ - if (info->hue != 0) { + if (hue != 0) { int sinth, costh, tmpmatrix[CMATRIX_LEN]; memcpy(tmpmatrix, matrix, CMATRIX_LEN*sizeof(int)); - sinth = ov7670_sine(info->hue); - costh = ov7670_cosine(info->hue); + sinth = ov7670_sine(hue); + costh = ov7670_cosine(hue); matrix[0] = (matrix[3]*sinth + matrix[0]*costh)/1000; matrix[1] = (matrix[4]*sinth + matrix[1]*costh)/1000; @@ -1072,60 +1092,21 @@ static void ov7670_calc_cmatrix(struct ov7670_info *info, -static int ov7670_s_sat(struct v4l2_subdev *sd, int value) -{ - struct ov7670_info *info = to_state(sd); - int matrix[CMATRIX_LEN]; - int ret; - - info->sat = value; - ov7670_calc_cmatrix(info, matrix); - ret = ov7670_store_cmatrix(sd, matrix); - return ret; -} - -static int ov7670_g_sat(struct v4l2_subdev *sd, __s32 *value) -{ - struct ov7670_info *info = to_state(sd); - - *value = info->sat; - return 0; -} - -static int ov7670_s_hue(struct v4l2_subdev *sd, int value) +static int ov7670_s_sat_hue(struct v4l2_subdev *sd, int sat, int hue) { struct ov7670_info *info = to_state(sd); int matrix[CMATRIX_LEN]; int ret; - if (value < -180 || value > 180) - return -EINVAL; - info->hue = value; - ov7670_calc_cmatrix(info, matrix); + ov7670_calc_cmatrix(info, matrix, sat, hue); ret = ov7670_store_cmatrix(sd, matrix); return ret; } -static int ov7670_g_hue(struct v4l2_subdev *sd, __s32 *value) -{ - struct ov7670_info *info = to_state(sd); - - *value = info->hue; - return 0; -} - - /* * Some weird registers seem to store values in a sign/magnitude format! */ -static unsigned char ov7670_sm_to_abs(unsigned char v) -{ - if ((v & 0x80) == 0) - return v + 128; - return 128 - (v & 0x7f); -} - static unsigned char ov7670_abs_to_sm(unsigned char v) { @@ -1147,40 +1128,11 @@ static int ov7670_s_brightness(struct v4l2_subdev *sd, int value) return ret; } -static int ov7670_g_brightness(struct v4l2_subdev *sd, __s32 *value) -{ - unsigned char v = 0; - int ret = ov7670_read(sd, REG_BRIGHT, &v); - - *value = ov7670_sm_to_abs(v); - return ret; -} - static int ov7670_s_contrast(struct v4l2_subdev *sd, int value) { return ov7670_write(sd, REG_CONTRAS, (unsigned char) value); } -static int ov7670_g_contrast(struct v4l2_subdev *sd, __s32 *value) -{ - unsigned char v = 0; - int ret = ov7670_read(sd, REG_CONTRAS, &v); - - *value = v; - return ret; -} - -static int ov7670_g_hflip(struct v4l2_subdev *sd, __s32 *value) -{ - int ret; - unsigned char v = 0; - - ret = ov7670_read(sd, REG_MVFP, &v); - *value = (v & MVFP_MIRROR) == MVFP_MIRROR; - return ret; -} - - static int ov7670_s_hflip(struct v4l2_subdev *sd, int value) { unsigned char v = 0; @@ -1196,19 +1148,6 @@ static int ov7670_s_hflip(struct v4l2_subdev *sd, int value) return ret; } - - -static int ov7670_g_vflip(struct v4l2_subdev *sd, __s32 *value) -{ - int ret; - unsigned char v = 0; - - ret = ov7670_read(sd, REG_MVFP, &v); - *value = (v & MVFP_FLIP) == MVFP_FLIP; - return ret; -} - - static int ov7670_s_vflip(struct v4l2_subdev *sd, int value) { unsigned char v = 0; @@ -1257,16 +1196,6 @@ static int ov7670_s_gain(struct v4l2_subdev *sd, int value) /* * Tweak autogain. */ -static int ov7670_g_autogain(struct v4l2_subdev *sd, __s32 *value) -{ - int ret; - unsigned char com8; - - ret = ov7670_read(sd, REG_COM8, &com8); - *value = (com8 & COM8_AGC) != 0; - return ret; -} - static int ov7670_s_autogain(struct v4l2_subdev *sd, int value) { int ret; @@ -1325,20 +1254,6 @@ static int ov7670_s_exp(struct v4l2_subdev *sd, int value) /* * Tweak autoexposure. */ -static int ov7670_g_autoexp(struct v4l2_subdev *sd, __s32 *value) -{ - int ret; - unsigned char com8; - enum v4l2_exposure_auto_type *atype = (enum v4l2_exposure_auto_type *) value; - - ret = ov7670_read(sd, REG_COM8, &com8); - if (com8 & COM8_AEC) - *atype = V4L2_EXPOSURE_AUTO; - else - *atype = V4L2_EXPOSURE_MANUAL; - return ret; -} - static int ov7670_s_autoexp(struct v4l2_subdev *sd, enum v4l2_exposure_auto_type value) { @@ -1357,90 +1272,69 @@ static int ov7670_s_autoexp(struct v4l2_subdev *sd, } - -static int ov7670_queryctrl(struct v4l2_subdev *sd, - struct v4l2_queryctrl *qc) +static int ov7670_g_volatile_ctrl(struct v4l2_ctrl *ctrl) { - /* Fill in min, max, step and default value for these controls. */ - switch (qc->id) { - case V4L2_CID_BRIGHTNESS: - return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128); - case V4L2_CID_CONTRAST: - return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64); - case V4L2_CID_VFLIP: - case V4L2_CID_HFLIP: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); - case V4L2_CID_SATURATION: - return v4l2_ctrl_query_fill(qc, 0, 256, 1, 128); - case V4L2_CID_HUE: - return v4l2_ctrl_query_fill(qc, -180, 180, 5, 0); - case V4L2_CID_GAIN: - return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128); - case V4L2_CID_AUTOGAIN: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); - case V4L2_CID_EXPOSURE: - return v4l2_ctrl_query_fill(qc, 0, 65535, 1, 500); - case V4L2_CID_EXPOSURE_AUTO: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); - } - return -EINVAL; -} + struct v4l2_subdev *sd = to_sd(ctrl); + struct ov7670_info *info = to_state(sd); -static int ov7670_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - return ov7670_g_brightness(sd, &ctrl->value); - case V4L2_CID_CONTRAST: - return ov7670_g_contrast(sd, &ctrl->value); - case V4L2_CID_SATURATION: - return ov7670_g_sat(sd, &ctrl->value); - case V4L2_CID_HUE: - return ov7670_g_hue(sd, &ctrl->value); - case V4L2_CID_VFLIP: - return ov7670_g_vflip(sd, &ctrl->value); - case V4L2_CID_HFLIP: - return ov7670_g_hflip(sd, &ctrl->value); - case V4L2_CID_GAIN: - return ov7670_g_gain(sd, &ctrl->value); case V4L2_CID_AUTOGAIN: - return ov7670_g_autogain(sd, &ctrl->value); - case V4L2_CID_EXPOSURE: - return ov7670_g_exp(sd, &ctrl->value); + if (!ctrl->cur.val) + return 0; + return ov7670_g_gain(sd, &info->gain->cur.val); case V4L2_CID_EXPOSURE_AUTO: - return ov7670_g_autoexp(sd, &ctrl->value); + if (ctrl->cur.val == V4L2_EXPOSURE_MANUAL) + return 0; + return ov7670_g_exp(sd, &info->exposure->cur.val); } return -EINVAL; } -static int ov7670_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +static int ov7670_s_ctrl(struct v4l2_ctrl *ctrl) { + struct v4l2_subdev *sd = to_sd(ctrl); + struct ov7670_info *info = to_state(sd); + switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: - return ov7670_s_brightness(sd, ctrl->value); + return ov7670_s_brightness(sd, ctrl->val); case V4L2_CID_CONTRAST: - return ov7670_s_contrast(sd, ctrl->value); + return ov7670_s_contrast(sd, ctrl->val); case V4L2_CID_SATURATION: - return ov7670_s_sat(sd, ctrl->value); - case V4L2_CID_HUE: - return ov7670_s_hue(sd, ctrl->value); + return ov7670_s_sat_hue(sd, + info->saturation->val, info->hue->val); case V4L2_CID_VFLIP: - return ov7670_s_vflip(sd, ctrl->value); + return ov7670_s_vflip(sd, ctrl->val); case V4L2_CID_HFLIP: - return ov7670_s_hflip(sd, ctrl->value); - case V4L2_CID_GAIN: - return ov7670_s_gain(sd, ctrl->value); + return ov7670_s_hflip(sd, ctrl->val); case V4L2_CID_AUTOGAIN: - return ov7670_s_autogain(sd, ctrl->value); - case V4L2_CID_EXPOSURE: - return ov7670_s_exp(sd, ctrl->value); + /* Only set manual gain if auto gain is not explicitly + turned on. */ + if (!ctrl->has_new || !ctrl->val) { + ctrl->val = 0; + /* ov7670_s_gain turns off auto gain */ + return ov7670_s_gain(sd, info->gain->val); + } + return ov7670_s_autogain(sd, ctrl->val); case V4L2_CID_EXPOSURE_AUTO: + /* Only set manual exposure if auto exposure is not explicitly + turned on. */ + if (!ctrl->has_new || ctrl->val == V4L2_EXPOSURE_MANUAL) { + ctrl->val = V4L2_EXPOSURE_MANUAL; + /* ov7670_s_exp turns off auto exposure */ + return ov7670_s_exp(sd, info->exposure->val); + } return ov7670_s_autoexp(sd, - (enum v4l2_exposure_auto_type) ctrl->value); + (enum v4l2_exposure_auto_type)ctrl->val); } return -EINVAL; } +static const struct v4l2_ctrl_ops ov7670_ctrl_ops = { + .s_ctrl = ov7670_s_ctrl, + .g_volatile_ctrl = ov7670_g_volatile_ctrl, +}; + static int ov7670_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) { @@ -1483,9 +1377,13 @@ static int ov7670_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *r static const struct v4l2_subdev_core_ops ov7670_core_ops = { .g_chip_ident = ov7670_g_chip_ident, - .g_ctrl = ov7670_g_ctrl, - .s_ctrl = ov7670_s_ctrl, - .queryctrl = ov7670_queryctrl, + .g_ext_ctrls = v4l2_subdev_g_ext_ctrls, + .try_ext_ctrls = v4l2_subdev_try_ext_ctrls, + .s_ext_ctrls = v4l2_subdev_s_ext_ctrls, + .g_ctrl = v4l2_subdev_g_ctrl, + .s_ctrl = v4l2_subdev_s_ctrl, + .queryctrl = v4l2_subdev_queryctrl, + .querymenu = v4l2_subdev_querymenu, .reset = ov7670_reset, .init = ov7670_init, #ifdef CONFIG_VIDEO_ADV_DEBUG @@ -1553,8 +1451,44 @@ static int ov7670_probe(struct i2c_client *client, client->addr << 1, client->adapter->name); info->fmt = &ov7670_formats[0]; - info->sat = 128; /* Review this */ info->clkrc = info->clock_speed / 30; + + v4l2_ctrl_handler_init(&info->hdl, 10); + v4l2_ctrl_new_std(&info->hdl, &ov7670_ctrl_ops, + V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); + v4l2_ctrl_new_std(&info->hdl, &ov7670_ctrl_ops, + V4L2_CID_CONTRAST, 0, 127, 1, 64); + v4l2_ctrl_new_std(&info->hdl, &ov7670_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); + v4l2_ctrl_new_std(&info->hdl, &ov7670_ctrl_ops, + V4L2_CID_HFLIP, 0, 1, 1, 0); + info->saturation = v4l2_ctrl_new_std(&info->hdl, &ov7670_ctrl_ops, + V4L2_CID_SATURATION, 0, 256, 1, 128); + info->hue = v4l2_ctrl_new_std(&info->hdl, &ov7670_ctrl_ops, + V4L2_CID_HUE, -180, 180, 5, 0); + info->gain = v4l2_ctrl_new_std(&info->hdl, &ov7670_ctrl_ops, + V4L2_CID_GAIN, 0, 255, 1, 128); + info->auto_gain = v4l2_ctrl_new_std(&info->hdl, &ov7670_ctrl_ops, + V4L2_CID_AUTOGAIN, 0, 1, 1, 1); + info->exposure = v4l2_ctrl_new_std(&info->hdl, &ov7670_ctrl_ops, + V4L2_CID_EXPOSURE, 0, 65535, 1, 500); + info->auto_exposure = v4l2_ctrl_new_std_menu(&info->hdl, &ov7670_ctrl_ops, + V4L2_CID_EXPOSURE_AUTO, 1, 0, 0); + sd->ctrl_handler = &info->hdl; + if (info->hdl.error) { + int err = info->hdl.error; + + v4l2_ctrl_handler_free(&info->hdl); + kfree(info); + return err; + } + info->gain->is_volatile = true; + info->exposure->is_volatile = true; + v4l2_ctrl_cluster(2, &info->auto_gain); + v4l2_ctrl_cluster(2, &info->auto_exposure); + v4l2_ctrl_cluster(2, &info->saturation); + v4l2_ctrl_handler_setup(&info->hdl); + return 0; } @@ -1562,9 +1496,11 @@ static int ov7670_probe(struct i2c_client *client, static int ov7670_remove(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct ov7670_info *info = to_state(sd); v4l2_device_unregister_subdev(sd); - kfree(to_state(sd)); + v4l2_ctrl_handler_free(&info->hdl); + kfree(info); return 0; } -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [RFC PATCH 5/5] cafe_ccic: implement the control framework. 2011-01-07 12:47 ` [RFC PATCH 1/5] v4l2-subdev: remove core.s_config and v4l2_i2c_new_subdev_cfg() Hans Verkuil ` (2 preceding siblings ...) 2011-01-07 12:47 ` [RFC PATCH 4/5] ov7670: use the control framework Hans Verkuil @ 2011-01-07 12:47 ` Hans Verkuil 2011-01-07 13:53 ` [RFC PATCH 1/5] v4l2-subdev: remove core.s_config and v4l2_i2c_new_subdev_cfg() Laurent Pinchart 2011-01-07 22:29 ` Sylwester Nawrocki 5 siblings, 0 replies; 13+ messages in thread From: Hans Verkuil @ 2011-01-07 12:47 UTC (permalink / raw) To: linux-media; +Cc: Jonathan Corbet, Laurent Pinchart And also swapped the out_free and out_unreg labels as they were in the wrong order. Tested with the OLPC laptop. Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> --- drivers/media/video/cafe_ccic.c | 59 +++++++------------------------------- 1 files changed, 11 insertions(+), 48 deletions(-) diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 7488b47..44ec342 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -35,6 +35,7 @@ #include <linux/slab.h> #include <media/v4l2-device.h> #include <media/v4l2-ioctl.h> +#include <media/v4l2-ctrls.h> #include <media/v4l2-chip-ident.h> #include <linux/device.h> #include <linux/wait.h> @@ -145,6 +146,7 @@ struct cafe_sio_buffer { struct cafe_camera { struct v4l2_device v4l2_dev; + struct v4l2_ctrl_handler ctrl_handler; enum cafe_state state; unsigned long flags; /* Buffer status, mainly (dev_lock) */ int users; /* How many open FDs */ @@ -1466,48 +1468,6 @@ static unsigned int cafe_v4l_poll(struct file *filp, -static int cafe_vidioc_queryctrl(struct file *filp, void *priv, - struct v4l2_queryctrl *qc) -{ - struct cafe_camera *cam = priv; - int ret; - - mutex_lock(&cam->s_mutex); - ret = sensor_call(cam, core, queryctrl, qc); - mutex_unlock(&cam->s_mutex); - return ret; -} - - -static int cafe_vidioc_g_ctrl(struct file *filp, void *priv, - struct v4l2_control *ctrl) -{ - struct cafe_camera *cam = priv; - int ret; - - mutex_lock(&cam->s_mutex); - ret = sensor_call(cam, core, g_ctrl, ctrl); - mutex_unlock(&cam->s_mutex); - return ret; -} - - -static int cafe_vidioc_s_ctrl(struct file *filp, void *priv, - struct v4l2_control *ctrl) -{ - struct cafe_camera *cam = priv; - int ret; - - mutex_lock(&cam->s_mutex); - ret = sensor_call(cam, core, s_ctrl, ctrl); - mutex_unlock(&cam->s_mutex); - return ret; -} - - - - - static int cafe_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { @@ -1792,9 +1752,6 @@ static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = { .vidioc_dqbuf = cafe_vidioc_dqbuf, .vidioc_streamon = cafe_vidioc_streamon, .vidioc_streamoff = cafe_vidioc_streamoff, - .vidioc_queryctrl = cafe_vidioc_queryctrl, - .vidioc_g_ctrl = cafe_vidioc_g_ctrl, - .vidioc_s_ctrl = cafe_vidioc_s_ctrl, .vidioc_g_parm = cafe_vidioc_g_parm, .vidioc_s_parm = cafe_vidioc_s_parm, .vidioc_enum_framesizes = cafe_vidioc_enum_framesizes, @@ -2031,6 +1988,10 @@ static int cafe_pci_probe(struct pci_dev *pdev, INIT_LIST_HEAD(&cam->sb_avail); INIT_LIST_HEAD(&cam->sb_full); tasklet_init(&cam->s_tasklet, cafe_frame_tasklet, (unsigned long) cam); + ret = v4l2_ctrl_handler_init(&cam->ctrl_handler, 10); + if (ret) + goto out_unreg; + cam->v4l2_dev.ctrl_handler = &cam->ctrl_handler; /* * Get set up on the PCI bus. */ @@ -2087,10 +2048,10 @@ static int cafe_pci_probe(struct pci_dev *pdev, cam->vdev.debug = 0; /* cam->vdev.debug = V4L2_DEBUG_IOCTL_ARG;*/ cam->vdev.v4l2_dev = &cam->v4l2_dev; + video_set_drvdata(&cam->vdev, cam); ret = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1); if (ret) goto out_unlock; - video_set_drvdata(&cam->vdev, cam); /* * If so requested, try to get our DMA buffers now. @@ -2113,9 +2074,10 @@ out_freeirq: free_irq(pdev->irq, cam); out_iounmap: pci_iounmap(pdev, cam->regs); -out_free: - v4l2_device_unregister(&cam->v4l2_dev); out_unreg: + v4l2_ctrl_handler_free(&cam->ctrl_handler); + v4l2_device_unregister(&cam->v4l2_dev); +out_free: kfree(cam); out: return ret; @@ -2154,6 +2116,7 @@ static void cafe_pci_remove(struct pci_dev *pdev) if (cam->users > 0) cam_warn(cam, "Removing a device with users!\n"); cafe_shutdown(cam); + v4l2_ctrl_handler_free(&cam->ctrl_handler); v4l2_device_unregister(&cam->v4l2_dev); kfree(cam); /* No unlock - it no longer exists */ -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [RFC PATCH 1/5] v4l2-subdev: remove core.s_config and v4l2_i2c_new_subdev_cfg() 2011-01-07 12:47 ` [RFC PATCH 1/5] v4l2-subdev: remove core.s_config and v4l2_i2c_new_subdev_cfg() Hans Verkuil ` (3 preceding siblings ...) 2011-01-07 12:47 ` [RFC PATCH 5/5] cafe_ccic: implement " Hans Verkuil @ 2011-01-07 13:53 ` Laurent Pinchart 2011-01-07 21:21 ` Hans Verkuil 2011-01-07 22:29 ` Sylwester Nawrocki 5 siblings, 1 reply; 13+ messages in thread From: Laurent Pinchart @ 2011-01-07 13:53 UTC (permalink / raw) To: Hans Verkuil; +Cc: linux-media, Jonathan Corbet Hi Hans, On Friday 07 January 2011 13:47:31 Hans Verkuil wrote: [snip] > diff --git a/drivers/media/video/cx25840/cx25840-core.c > b/drivers/media/video/cx25840/cx25840-core.c index dfb198d..9b384ac 100644 > --- a/drivers/media/video/cx25840/cx25840-core.c > +++ b/drivers/media/video/cx25840/cx25840-core.c > @@ -1682,20 +1682,6 @@ static int cx25840_log_status(struct v4l2_subdev > *sd) return 0; > } > > -static int cx25840_s_config(struct v4l2_subdev *sd, int irq, void > *platform_data) -{ > - struct cx25840_state *state = to_state(sd); > - struct i2c_client *client = v4l2_get_subdevdata(sd); > - > - if (platform_data) { > - struct cx25840_platform_data *pdata = platform_data; > - > - state->pvr150_workaround = pdata->pvr150_workaround; > - set_input(client, state->vid_input, state->aud_input); > - } > - return 0; > -} > - > static int cx23885_irq_handler(struct v4l2_subdev *sd, u32 status, > bool *handled) > { [snip] > @@ -2019,6 +2003,12 @@ static int cx25840_probe(struct i2c_client *client, > v4l2_ctrl_cluster(2, &state->volume); > v4l2_ctrl_handler_setup(&state->hdl); > > + if (client->dev.platform_data) { > + struct cx25840_platform_data *pdata = client->dev.platform_data; > + > + state->pvr150_workaround = pdata->pvr150_workaround; > + } > + No need to call set_input() anymore ? > cx25840_ir_probe(sd); > return 0; > } [snip] > diff --git a/drivers/media/video/mt9v011_regs.h > b/drivers/media/video/mt9v011_regs.h new file mode 100644 > index 0000000..d6a5a08 > --- /dev/null > +++ b/drivers/media/video/mt9v011_regs.h > @@ -0,0 +1,36 @@ > +/* > + * mt9v011 -Micron 1/4-Inch VGA Digital Image Sensor > + * > + * Copyright (c) 2009 Mauro Carvalho Chehab (mchehab@redhat.com) > + * This code is placed under the terms of the GNU General Public License > v2 + */ > + > +#ifndef MT9V011_REGS_H_ > +#define MT9V011_REGS_H_ > + > +#define R00_MT9V011_CHIP_VERSION 0x00 > +#define R01_MT9V011_ROWSTART 0x01 > +#define R02_MT9V011_COLSTART 0x02 > +#define R03_MT9V011_HEIGHT 0x03 > +#define R04_MT9V011_WIDTH 0x04 > +#define R05_MT9V011_HBLANK 0x05 > +#define R06_MT9V011_VBLANK 0x06 > +#define R07_MT9V011_OUT_CTRL 0x07 > +#define R09_MT9V011_SHUTTER_WIDTH 0x09 > +#define R0A_MT9V011_CLK_SPEED 0x0a > +#define R0B_MT9V011_RESTART 0x0b > +#define R0C_MT9V011_SHUTTER_DELAY 0x0c > +#define R0D_MT9V011_RESET 0x0d > +#define R1E_MT9V011_DIGITAL_ZOOM 0x1e > +#define R20_MT9V011_READ_MODE 0x20 > +#define R2B_MT9V011_GREEN_1_GAIN 0x2b > +#define R2C_MT9V011_BLUE_GAIN 0x2c > +#define R2D_MT9V011_RED_GAIN 0x2d > +#define R2E_MT9V011_GREEN_2_GAIN 0x2e > +#define R35_MT9V011_GLOBAL_GAIN 0x35 > +#define RF1_MT9V011_CHIP_ENABLE 0xf1 > + > +#define MT9V011_VERSION 0x8232 > +#define MT9V011_REV_B_VERSION 0x8243 What about merging this into mt9v011.c ? > + > +#endif -- Regards, Laurent Pinchart ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFC PATCH 1/5] v4l2-subdev: remove core.s_config and v4l2_i2c_new_subdev_cfg() 2011-01-07 13:53 ` [RFC PATCH 1/5] v4l2-subdev: remove core.s_config and v4l2_i2c_new_subdev_cfg() Laurent Pinchart @ 2011-01-07 21:21 ` Hans Verkuil 2011-01-07 21:28 ` Laurent Pinchart 0 siblings, 1 reply; 13+ messages in thread From: Hans Verkuil @ 2011-01-07 21:21 UTC (permalink / raw) To: Laurent Pinchart; +Cc: linux-media, Jonathan Corbet On Friday, January 07, 2011 14:53:06 Laurent Pinchart wrote: > Hi Hans, > > On Friday 07 January 2011 13:47:31 Hans Verkuil wrote: > > [snip] > > > diff --git a/drivers/media/video/cx25840/cx25840-core.c > > b/drivers/media/video/cx25840/cx25840-core.c index dfb198d..9b384ac 100644 > > --- a/drivers/media/video/cx25840/cx25840-core.c > > +++ b/drivers/media/video/cx25840/cx25840-core.c > > @@ -1682,20 +1682,6 @@ static int cx25840_log_status(struct v4l2_subdev > > *sd) return 0; > > } > > > > -static int cx25840_s_config(struct v4l2_subdev *sd, int irq, void > > *platform_data) -{ > > - struct cx25840_state *state = to_state(sd); > > - struct i2c_client *client = v4l2_get_subdevdata(sd); > > - > > - if (platform_data) { > > - struct cx25840_platform_data *pdata = platform_data; > > - > > - state->pvr150_workaround = pdata->pvr150_workaround; > > - set_input(client, state->vid_input, state->aud_input); > > - } > > - return 0; > > -} > > - > > static int cx23885_irq_handler(struct v4l2_subdev *sd, u32 status, > > bool *handled) > > { > > [snip] > > > @@ -2019,6 +2003,12 @@ static int cx25840_probe(struct i2c_client *client, > > v4l2_ctrl_cluster(2, &state->volume); > > v4l2_ctrl_handler_setup(&state->hdl); > > > > + if (client->dev.platform_data) { > > + struct cx25840_platform_data *pdata = client->dev.platform_data; > > + > > + state->pvr150_workaround = pdata->pvr150_workaround; > > + } > > + > > No need to call set_input() anymore ? No. :-) This s_config was only called from ivtv, and in that particular case the set_input wasn't needed at all. > > > cx25840_ir_probe(sd); > > return 0; > > } > > [snip] > > > diff --git a/drivers/media/video/mt9v011_regs.h > > b/drivers/media/video/mt9v011_regs.h new file mode 100644 > > index 0000000..d6a5a08 > > --- /dev/null > > +++ b/drivers/media/video/mt9v011_regs.h > > @@ -0,0 +1,36 @@ > > +/* > > + * mt9v011 -Micron 1/4-Inch VGA Digital Image Sensor > > + * > > + * Copyright (c) 2009 Mauro Carvalho Chehab (mchehab@redhat.com) > > + * This code is placed under the terms of the GNU General Public License > > v2 + */ > > + > > +#ifndef MT9V011_REGS_H_ > > +#define MT9V011_REGS_H_ > > + > > +#define R00_MT9V011_CHIP_VERSION 0x00 > > +#define R01_MT9V011_ROWSTART 0x01 > > +#define R02_MT9V011_COLSTART 0x02 > > +#define R03_MT9V011_HEIGHT 0x03 > > +#define R04_MT9V011_WIDTH 0x04 > > +#define R05_MT9V011_HBLANK 0x05 > > +#define R06_MT9V011_VBLANK 0x06 > > +#define R07_MT9V011_OUT_CTRL 0x07 > > +#define R09_MT9V011_SHUTTER_WIDTH 0x09 > > +#define R0A_MT9V011_CLK_SPEED 0x0a > > +#define R0B_MT9V011_RESTART 0x0b > > +#define R0C_MT9V011_SHUTTER_DELAY 0x0c > > +#define R0D_MT9V011_RESET 0x0d > > +#define R1E_MT9V011_DIGITAL_ZOOM 0x1e > > +#define R20_MT9V011_READ_MODE 0x20 > > +#define R2B_MT9V011_GREEN_1_GAIN 0x2b > > +#define R2C_MT9V011_BLUE_GAIN 0x2c > > +#define R2D_MT9V011_RED_GAIN 0x2d > > +#define R2E_MT9V011_GREEN_2_GAIN 0x2e > > +#define R35_MT9V011_GLOBAL_GAIN 0x35 > > +#define RF1_MT9V011_CHIP_ENABLE 0xf1 > > + > > +#define MT9V011_VERSION 0x8232 > > +#define MT9V011_REV_B_VERSION 0x8243 > > What about merging this into mt9v011.c ? I went back and forth about this. If you think I should, then I can merge it. Regards, Hans -- Hans Verkuil - video4linux developer - sponsored by Cisco ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFC PATCH 1/5] v4l2-subdev: remove core.s_config and v4l2_i2c_new_subdev_cfg() 2011-01-07 21:21 ` Hans Verkuil @ 2011-01-07 21:28 ` Laurent Pinchart 0 siblings, 0 replies; 13+ messages in thread From: Laurent Pinchart @ 2011-01-07 21:28 UTC (permalink / raw) To: Hans Verkuil; +Cc: linux-media, Jonathan Corbet Hi Hans, On Friday 07 January 2011 22:21:39 Hans Verkuil wrote: > On Friday, January 07, 2011 14:53:06 Laurent Pinchart wrote: > > On Friday 07 January 2011 13:47:31 Hans Verkuil wrote: [snip] > > > diff --git a/drivers/media/video/mt9v011_regs.h > > > b/drivers/media/video/mt9v011_regs.h new file mode 100644 > > > index 0000000..d6a5a08 > > > --- /dev/null > > > +++ b/drivers/media/video/mt9v011_regs.h > > > @@ -0,0 +1,36 @@ > > > +/* > > > + * mt9v011 -Micron 1/4-Inch VGA Digital Image Sensor > > > + * > > > + * Copyright (c) 2009 Mauro Carvalho Chehab (mchehab@redhat.com) > > > + * This code is placed under the terms of the GNU General Public > > > License v2 + */ > > > + > > > +#ifndef MT9V011_REGS_H_ > > > +#define MT9V011_REGS_H_ > > > + > > > +#define R00_MT9V011_CHIP_VERSION 0x00 > > > +#define R01_MT9V011_ROWSTART 0x01 > > > +#define R02_MT9V011_COLSTART 0x02 > > > +#define R03_MT9V011_HEIGHT 0x03 > > > +#define R04_MT9V011_WIDTH 0x04 > > > +#define R05_MT9V011_HBLANK 0x05 > > > +#define R06_MT9V011_VBLANK 0x06 > > > +#define R07_MT9V011_OUT_CTRL 0x07 > > > +#define R09_MT9V011_SHUTTER_WIDTH 0x09 > > > +#define R0A_MT9V011_CLK_SPEED 0x0a > > > +#define R0B_MT9V011_RESTART 0x0b > > > +#define R0C_MT9V011_SHUTTER_DELAY 0x0c > > > +#define R0D_MT9V011_RESET 0x0d > > > +#define R1E_MT9V011_DIGITAL_ZOOM 0x1e > > > +#define R20_MT9V011_READ_MODE 0x20 > > > +#define R2B_MT9V011_GREEN_1_GAIN 0x2b > > > +#define R2C_MT9V011_BLUE_GAIN 0x2c > > > +#define R2D_MT9V011_RED_GAIN 0x2d > > > +#define R2E_MT9V011_GREEN_2_GAIN 0x2e > > > +#define R35_MT9V011_GLOBAL_GAIN 0x35 > > > +#define RF1_MT9V011_CHIP_ENABLE 0xf1 > > > + > > > +#define MT9V011_VERSION 0x8232 > > > +#define MT9V011_REV_B_VERSION 0x8243 > > > > What about merging this into mt9v011.c ? > > I went back and forth about this. If you think I should, then I can merge > it. There's few constants, and they're only used from a single source file. I would merge them there. -- Regards, Laurent Pinchart ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFC PATCH 1/5] v4l2-subdev: remove core.s_config and v4l2_i2c_new_subdev_cfg() 2011-01-07 12:47 ` [RFC PATCH 1/5] v4l2-subdev: remove core.s_config and v4l2_i2c_new_subdev_cfg() Hans Verkuil ` (4 preceding siblings ...) 2011-01-07 13:53 ` [RFC PATCH 1/5] v4l2-subdev: remove core.s_config and v4l2_i2c_new_subdev_cfg() Laurent Pinchart @ 2011-01-07 22:29 ` Sylwester Nawrocki 5 siblings, 0 replies; 13+ messages in thread From: Sylwester Nawrocki @ 2011-01-07 22:29 UTC (permalink / raw) To: Hans Verkuil; +Cc: linux-media, Jonathan Corbet, Laurent Pinchart Hi Hans, On 01/07/2011 01:47 PM, Hans Verkuil wrote: > The core.s_config op was meant for legacy drivers that needed to work with old > pre-2.6.26 kernels. This is no longer relevant. Unfortunately, this op was > incorrectly called from several drivers. > > Replace those occurences with proper i2c_board_info structs and call > v4l2_i2c_new_subdev_board. > > After these changes v4l2_i2c_new_subdev_cfg() was no longer used, so remove > that function as well. > > Signed-off-by: Hans Verkuil<hverkuil@xs4all.nl> > --- > drivers/media/video/cafe_ccic.c | 11 +++- > drivers/media/video/cx25840/cx25840-core.c | 22 ++------ > drivers/media/video/em28xx/em28xx-cards.c | 18 ++++--- > drivers/media/video/ivtv/ivtv-i2c.c | 9 +++- > drivers/media/video/mt9v011.c | 29 ++++------- > drivers/media/video/mt9v011.h | 36 ------------- > drivers/media/video/mt9v011_regs.h | 36 +++++++++++++ > drivers/media/video/ov7670.c | 74 ++++++++++++---------------- > drivers/media/video/sr030pc30.c | 10 ---- > drivers/media/video/v4l2-common.c | 19 +------ > include/media/mt9v011.h | 17 ++++++ > include/media/v4l2-common.h | 13 +----- > include/media/v4l2-subdev.h | 6 +-- > 13 files changed, 130 insertions(+), 170 deletions(-) > delete mode 100644 drivers/media/video/mt9v011.h > create mode 100644 drivers/media/video/mt9v011_regs.h > create mode 100644 include/media/mt9v011.h > ... > > diff --git a/drivers/media/video/sr030pc30.c b/drivers/media/video/sr030pc30.c > index 864696b..c901721 100644 > --- a/drivers/media/video/sr030pc30.c > +++ b/drivers/media/video/sr030pc30.c > @@ -714,15 +714,6 @@ static int sr030pc30_base_config(struct v4l2_subdev *sd) > return ret; > } > > -static int sr030pc30_s_config(struct v4l2_subdev *sd, > - int irq, void *platform_data) > -{ > - struct sr030pc30_info *info = to_sr030pc30(sd); > - > - info->pdata = platform_data; > - return 0; > -} > - > static int sr030pc30_s_stream(struct v4l2_subdev *sd, int enable) > { > return 0; > @@ -763,7 +754,6 @@ static int sr030pc30_s_power(struct v4l2_subdev *sd, int on) > } > > static const struct v4l2_subdev_core_ops sr030pc30_core_ops = { > - .s_config = sr030pc30_s_config, > .s_power = sr030pc30_s_power, > .queryctrl = sr030pc30_queryctrl, > .s_ctrl = sr030pc30_s_ctrl, > I've just had prepared a patch removing s_config as well as an empty s_stream op. So now there is only one left for me ;) Thanks for handling that, and sorry for the trouble. I've got also prepared a patch converting sr030pc30 driver to the control framework, just need to find a time slot to test it. An another one replacing the set_power callback with the regulator API. Regards, Sylwester ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2011-01-07 22:29 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-01-07 12:47 [RFC PATCH 0/5] Use control framework in cafe_ccic and s_config removal Hans Verkuil 2011-01-07 12:47 ` [RFC PATCH 1/5] v4l2-subdev: remove core.s_config and v4l2_i2c_new_subdev_cfg() Hans Verkuil 2011-01-07 12:47 ` [RFC PATCH 2/5] v4l2-subdev: add (un)register internal ops Hans Verkuil 2011-01-07 13:37 ` Laurent Pinchart 2011-01-07 12:47 ` [RFC PATCH 3/5] v4l2-ctrls: v4l2_ctrl_handler_setup must set has_new to 1 Hans Verkuil 2011-01-07 13:25 ` Laurent Pinchart 2011-01-07 21:22 ` Hans Verkuil 2011-01-07 12:47 ` [RFC PATCH 4/5] ov7670: use the control framework Hans Verkuil 2011-01-07 12:47 ` [RFC PATCH 5/5] cafe_ccic: implement " Hans Verkuil 2011-01-07 13:53 ` [RFC PATCH 1/5] v4l2-subdev: remove core.s_config and v4l2_i2c_new_subdev_cfg() Laurent Pinchart 2011-01-07 21:21 ` Hans Verkuil 2011-01-07 21:28 ` Laurent Pinchart 2011-01-07 22:29 ` Sylwester Nawrocki
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox