diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-04-25 16:27:13 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-04-25 16:27:13 -0700 |
commit | 4ea956963f4fca59050a22fcc65f00a85d586e63 (patch) | |
tree | 6fc32daed4499e7b98b9ce465a884f56882905de /drivers/staging | |
parent | c8cc58e289ed3b5bc50258f52776cf3dfa3bad66 (diff) | |
parent | 73b41dc51fbeffa4a216b20193274cfe92b5d95b (diff) |
Merge tag 'media/v6.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab:
- Removal of some old unused sensor drivers: ad9389b, m5mols, mt9m032,
mt9t001, noon010pc30, s5k6aa, sr030pc30 and vs6624
- New i.MX8 image sensor interface driver
- Some new RC keymaps
- lots of cleanups at atomisp driver to make it support standard
features present on other webcam drivers
- the cx18 and saa7146 now uses VB2
- lots of cleanups and driver improvements
* tag 'media/v6.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (460 commits)
media: ov5670: Fix probe on ACPI
media: nxp: imx8-isi: Remove 300ms sleep after enabling channel
media: nxp: imx8-isi: Replace udelay() with fsleep()
media: nxp: imx8-isi: Drop partial support for i.MX8QM and i.MX8QXP
media: nxp: Add i.MX8 ISI driver
media: dt-bindings: media: Add i.MX8 ISI DT bindings
media: atomisp: gmin_platform: Add Lenovo Ideapad Miix 310 gmin_vars
media: atomisp: gmin_platform: Make DMI quirks take precedence over the _DSM table
media: atomisp: Remove struct atomisp_sub_device index field
media: atomisp: Drop support for streaming from 2 sensors at once
media: atomisp: Remove atomisp_try_fmt() call from atomisp_set_fmt()
media: atomisp: Remove unused ATOM_ISP_MAX_WIDTH_TMP and ATOM_ISP_MAX_HEIGHT_TMP
media: atomisp: Remove snr_mbus_fmt local var from atomisp_try_fmt()
media: atomisp: Remove custom V4L2_CID_FMT_AUTO control
media: atomisp: Remove continuous mode related code from atomisp_set_fmt()
media: atomisp: Remove duplicate atomisp_[start|stop]_streaming() prototypes
media: atomisp: gc0310: Switch over to ACPI powermanagement
media: atomisp: gc0310: Use devm_kzalloc() for data struct
media: atomisp: gc0310: Add runtime-pm support
media: atomisp: gc0310: Delay power-on till streaming is started
...
Diffstat (limited to 'drivers/staging')
41 files changed, 1174 insertions, 3375 deletions
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c index 0d90683ed227..273155308fe3 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c @@ -3,6 +3,7 @@ * Support for GalaxyCore GC0310 VGA camera sensor. * * Copyright (c) 2013 Intel Corporation. All Rights Reserved. + * Copyright (c) 2023 Hans de Goede <hdegoede@redhat.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version @@ -26,234 +27,59 @@ #include <linux/device.h> #include <linux/delay.h> #include <linux/slab.h> +#include <linux/gpio/consumer.h> +#include <linux/gpio/machine.h> #include <linux/i2c.h> #include <linux/moduleparam.h> +#include <linux/pm_runtime.h> #include <media/v4l2-device.h> #include <linux/io.h> #include "../include/linux/atomisp_gmin_platform.h" #include "gc0310.h" -/* i2c read/write stuff */ -static int gc0310_read_reg(struct i2c_client *client, - u16 data_length, u8 reg, u8 *val) -{ - int err; - struct i2c_msg msg[2]; - unsigned char data[1]; - - if (!client->adapter) { - dev_err(&client->dev, "%s error, no client->adapter\n", - __func__); - return -ENODEV; - } - - if (data_length != GC0310_8BIT) { - dev_err(&client->dev, "%s error, invalid data length\n", - __func__); - return -EINVAL; - } - - memset(msg, 0, sizeof(msg)); - - msg[0].addr = client->addr; - msg[0].flags = 0; - msg[0].len = I2C_MSG_LENGTH; - msg[0].buf = data; - - /* high byte goes out first */ - data[0] = (u8)(reg & 0xff); - - msg[1].addr = client->addr; - msg[1].len = data_length; - msg[1].flags = I2C_M_RD; - msg[1].buf = data; - - err = i2c_transfer(client->adapter, msg, 2); - if (err != 2) { - if (err >= 0) - err = -EIO; - dev_err(&client->dev, - "read from offset 0x%x error %d", reg, err); - return err; - } - - *val = 0; - /* high byte comes first */ - if (data_length == GC0310_8BIT) - *val = (u8)data[0]; - - return 0; -} - -static int gc0310_i2c_write(struct i2c_client *client, u16 len, u8 *data) -{ - struct i2c_msg msg; - const int num_msg = 1; - int ret; - - msg.addr = client->addr; - msg.flags = 0; - msg.len = len; - msg.buf = data; - ret = i2c_transfer(client->adapter, &msg, 1); - - return ret == num_msg ? 0 : -EIO; -} - -static int gc0310_write_reg(struct i2c_client *client, u16 data_length, - u8 reg, u8 val) -{ - int ret; - unsigned char data[2] = {0}; - u8 *wreg = (u8 *)data; - const u16 len = data_length + sizeof(u8); /* 8-bit address + data */ - - if (data_length != GC0310_8BIT) { - dev_err(&client->dev, - "%s error, invalid data_length\n", __func__); - return -EINVAL; - } - - /* high byte goes out first */ - *wreg = (u8)(reg & 0xff); - - if (data_length == GC0310_8BIT) - data[1] = (u8)(val); - - ret = gc0310_i2c_write(client, len, data); - if (ret) - dev_err(&client->dev, - "write error: wrote 0x%x to offset 0x%x error %d", - val, reg, ret); - - return ret; -} - /* * gc0310_write_reg_array - Initializes a list of GC0310 registers * @client: i2c driver client structure * @reglist: list of registers to be written - * - * This function initializes a list of registers. When consecutive addresses - * are found in a row on the list, this function creates a buffer and sends - * consecutive data in a single i2c_transfer(). - * - * __gc0310_flush_reg_array, __gc0310_buf_reg_array() and - * __gc0310_write_reg_is_consecutive() are internal functions to - * gc0310_write_reg_array_fast() and should be not used anywhere else. - * + * @count: number of register, value pairs in the list */ - -static int __gc0310_flush_reg_array(struct i2c_client *client, - struct gc0310_write_ctrl *ctrl) -{ - u16 size; - - if (ctrl->index == 0) - return 0; - - size = sizeof(u8) + ctrl->index; /* 8-bit address + data */ - ctrl->buffer.addr = (u8)(ctrl->buffer.addr); - ctrl->index = 0; - - return gc0310_i2c_write(client, size, (u8 *)&ctrl->buffer); -} - -static int __gc0310_buf_reg_array(struct i2c_client *client, - struct gc0310_write_ctrl *ctrl, - const struct gc0310_reg *next) +static int gc0310_write_reg_array(struct i2c_client *client, + const struct gc0310_reg *reglist, int count) { - int size; + int i, err; - switch (next->type) { - case GC0310_8BIT: - size = 1; - ctrl->buffer.data[ctrl->index] = (u8)next->val; - break; - default: - return -EINVAL; + for (i = 0; i < count; i++) { + err = i2c_smbus_write_byte_data(client, reglist[i].reg, reglist[i].val); + if (err) { + dev_err(&client->dev, "write error: wrote 0x%x to offset 0x%x error %d", + reglist[i].val, reglist[i].reg, err); + return err; + } } - /* When first item is added, we need to store its starting address */ - if (ctrl->index == 0) - ctrl->buffer.addr = next->reg; - - ctrl->index += size; - - /* - * Buffer cannot guarantee free space for u32? Better flush it to avoid - * possible lack of memory for next item. - */ - if (ctrl->index + sizeof(u8) >= GC0310_MAX_WRITE_BUF_SIZE) - return __gc0310_flush_reg_array(client, ctrl); - return 0; } -static int __gc0310_write_reg_is_consecutive(struct i2c_client *client, - struct gc0310_write_ctrl *ctrl, - const struct gc0310_reg *next) +static int gc0310_exposure_set(struct gc0310_device *dev, u32 exp) { - if (ctrl->index == 0) - return 1; - - return ctrl->buffer.addr + ctrl->index == next->reg; -} - -static int gc0310_write_reg_array(struct i2c_client *client, - const struct gc0310_reg *reglist) -{ - const struct gc0310_reg *next = reglist; - struct gc0310_write_ctrl ctrl; - int err; - - ctrl.index = 0; - for (; next->type != GC0310_TOK_TERM; next++) { - switch (next->type & GC0310_TOK_MASK) { - case GC0310_TOK_DELAY: - err = __gc0310_flush_reg_array(client, &ctrl); - if (err) - return err; - msleep(next->val); - break; - default: - /* - * If next address is not consecutive, data needs to be - * flushed before proceed. - */ - if (!__gc0310_write_reg_is_consecutive(client, &ctrl, - next)) { - err = __gc0310_flush_reg_array(client, &ctrl); - if (err) - return err; - } - err = __gc0310_buf_reg_array(client, &ctrl, next); - if (err) { - dev_err(&client->dev, "%s: write error, aborted\n", - __func__); - return err; - } - break; - } - } + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); - return __gc0310_flush_reg_array(client, &ctrl); + return i2c_smbus_write_word_swapped(client, GC0310_AEC_PK_EXPO_H, exp); } -static int gc0310_set_gain(struct v4l2_subdev *sd, int gain) - +static int gc0310_gain_set(struct gc0310_device *dev, u32 gain) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); u8 again, dgain; + int ret; - if (gain < 0x20) - gain = 0x20; - if (gain > 0x80) - gain = 0x80; + /* Taken from original driver, this never sets dgain lower then 32? */ - if (gain >= 0x20 && gain < 0x40) { + /* Change 0 - 95 to 32 - 127 */ + gain += 32; + + if (gain < 64) { again = 0x0; /* sqrt(2) */ dgain = gain; } else { @@ -261,507 +87,109 @@ static int gc0310_set_gain(struct v4l2_subdev *sd, int gain) dgain = gain / 2; } - dev_dbg(&client->dev, "gain=0x%x again=0x%x dgain=0x%x\n", gain, again, dgain); - - /* set analog gain */ - ret = gc0310_write_reg(client, GC0310_8BIT, - GC0310_AGC_ADJ, again); - if (ret) - return ret; - - /* set digital gain */ - ret = gc0310_write_reg(client, GC0310_8BIT, - GC0310_DGC_ADJ, dgain); - if (ret) - return ret; - - return 0; -} - -static int __gc0310_set_exposure(struct v4l2_subdev *sd, int coarse_itg, - int gain, int digitgain) - -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - - dev_dbg(&client->dev, "coarse_itg=%d gain=%d digitgain=%d\n", coarse_itg, gain, digitgain); - - /* set exposure */ - ret = gc0310_write_reg(client, GC0310_8BIT, - GC0310_AEC_PK_EXPO_L, - coarse_itg & 0xff); + ret = i2c_smbus_write_byte_data(client, GC0310_AGC_ADJ, again); if (ret) return ret; - ret = gc0310_write_reg(client, GC0310_8BIT, - GC0310_AEC_PK_EXPO_H, - (coarse_itg >> 8) & 0x0f); - if (ret) - return ret; - - ret = gc0310_set_gain(sd, gain); - if (ret) - return ret; - - return ret; -} - -static int gc0310_set_exposure(struct v4l2_subdev *sd, int exposure, - int gain, int digitgain) -{ - struct gc0310_device *dev = to_gc0310_sensor(sd); - int ret; - - mutex_lock(&dev->input_lock); - ret = __gc0310_set_exposure(sd, exposure, gain, digitgain); - mutex_unlock(&dev->input_lock); - - return ret; -} - -static long gc0310_s_exposure(struct v4l2_subdev *sd, - struct atomisp_exposure *exposure) -{ - int exp = exposure->integration_time[0]; - int gain = exposure->gain[0]; - int digitgain = exposure->gain[1]; - - /* we should not accept the invalid value below. */ - if (gain == 0) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - - v4l2_err(client, "%s: invalid value\n", __func__); - return -EINVAL; - } - - return gc0310_set_exposure(sd, exp, gain, digitgain); -} - -/* TO DO */ -static int gc0310_v_flip(struct v4l2_subdev *sd, s32 value) -{ - return 0; -} - -/* TO DO */ -static int gc0310_h_flip(struct v4l2_subdev *sd, s32 value) -{ - return 0; -} - -static long gc0310_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) -{ - switch (cmd) { - case ATOMISP_IOC_S_EXPOSURE: - return gc0310_s_exposure(sd, arg); - default: - return -EINVAL; - } - return 0; -} - -/* This returns the exposure time being used. This should only be used - * for filling in EXIF data, not for actual image processing. - */ -static int gc0310_q_exposure(struct v4l2_subdev *sd, s32 *value) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - u8 reg_v; - int ret; - - /* get exposure */ - ret = gc0310_read_reg(client, GC0310_8BIT, - GC0310_AEC_PK_EXPO_L, - ®_v); - if (ret) - goto err; - - *value = reg_v; - ret = gc0310_read_reg(client, GC0310_8BIT, - GC0310_AEC_PK_EXPO_H, - ®_v); - if (ret) - goto err; - - *value = *value + (reg_v << 8); -err: - return ret; + return i2c_smbus_write_byte_data(client, GC0310_DGC_ADJ, dgain); } static int gc0310_s_ctrl(struct v4l2_ctrl *ctrl) { struct gc0310_device *dev = - container_of(ctrl->handler, struct gc0310_device, ctrl_handler); - struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); - int ret = 0; + container_of(ctrl->handler, struct gc0310_device, ctrls.handler); + int ret; + + /* Only apply changes to the controls if the device is powered up */ + if (!pm_runtime_get_if_in_use(dev->sd.dev)) + return 0; switch (ctrl->id) { - case V4L2_CID_VFLIP: - dev_dbg(&client->dev, "%s: CID_VFLIP:%d.\n", - __func__, ctrl->val); - ret = gc0310_v_flip(&dev->sd, ctrl->val); + case V4L2_CID_EXPOSURE: + ret = gc0310_exposure_set(dev, ctrl->val); break; - case V4L2_CID_HFLIP: - dev_dbg(&client->dev, "%s: CID_HFLIP:%d.\n", - __func__, ctrl->val); - ret = gc0310_h_flip(&dev->sd, ctrl->val); + case V4L2_CID_GAIN: + ret = gc0310_gain_set(dev, ctrl->val); break; default: ret = -EINVAL; - } - return ret; -} - -static int gc0310_g_volatile_ctrl(struct v4l2_ctrl *ctrl) -{ - struct gc0310_device *dev = - container_of(ctrl->handler, struct gc0310_device, ctrl_handler); - int ret = 0; - - switch (ctrl->id) { - case V4L2_CID_EXPOSURE_ABSOLUTE: - ret = gc0310_q_exposure(&dev->sd, &ctrl->val); break; - default: - ret = -EINVAL; } + pm_runtime_put(dev->sd.dev); return ret; } static const struct v4l2_ctrl_ops ctrl_ops = { .s_ctrl = gc0310_s_ctrl, - .g_volatile_ctrl = gc0310_g_volatile_ctrl }; -static const struct v4l2_ctrl_config gc0310_controls[] = { - { - .ops = &ctrl_ops, - .id = V4L2_CID_EXPOSURE_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "exposure", - .min = 0x0, - .max = 0xffff, - .step = 0x01, - .def = 0x00, - .flags = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flip", - .min = 0, - .max = 1, - .step = 1, - .def = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Mirror", - .min = 0, - .max = 1, - .step = 1, - .def = 0, - }, -}; - -static int gc0310_init(struct v4l2_subdev *sd) -{ - int ret; - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct gc0310_device *dev = to_gc0310_sensor(sd); - - mutex_lock(&dev->input_lock); - - /* set initial registers */ - ret = gc0310_write_reg_array(client, gc0310_reset_register); - - /* restore settings */ - gc0310_res = gc0310_res_preview; - N_RES = N_RES_PREVIEW; - - mutex_unlock(&dev->input_lock); - - return ret; -} - -static int power_ctrl(struct v4l2_subdev *sd, bool flag) -{ - int ret = 0; - struct gc0310_device *dev = to_gc0310_sensor(sd); - - if (!dev || !dev->platform_data) - return -ENODEV; - - if (flag) { - /* The upstream module driver (written to Crystal - * Cove) had this logic to pulse the rails low first. - * This appears to break things on the MRD7 with the - * X-Powers PMIC... - * - * ret = dev->platform_data->v1p8_ctrl(sd, 0); - * ret |= dev->platform_data->v2p8_ctrl(sd, 0); - * mdelay(50); - */ - ret |= dev->platform_data->v1p8_ctrl(sd, 1); - ret |= dev->platform_data->v2p8_ctrl(sd, 1); - usleep_range(10000, 15000); - } - - if (!flag || ret) { - ret |= dev->platform_data->v1p8_ctrl(sd, 0); - ret |= dev->platform_data->v2p8_ctrl(sd, 0); - } - return ret; -} - -static int gpio_ctrl(struct v4l2_subdev *sd, bool flag) -{ - int ret; - struct gc0310_device *dev = to_gc0310_sensor(sd); - - if (!dev || !dev->platform_data) - return -ENODEV; - - /* GPIO0 == "reset" (active low), GPIO1 == "power down" */ - if (flag) { - /* Pulse reset, then release power down */ - ret = dev->platform_data->gpio0_ctrl(sd, 0); - usleep_range(5000, 10000); - ret |= dev->platform_data->gpio0_ctrl(sd, 1); - usleep_range(10000, 15000); - ret |= dev->platform_data->gpio1_ctrl(sd, 0); - usleep_range(10000, 15000); - } else { - ret = dev->platform_data->gpio1_ctrl(sd, 1); - ret |= dev->platform_data->gpio0_ctrl(sd, 0); - } - return ret; -} - -static int power_up(struct v4l2_subdev *sd) -{ - struct gc0310_device *dev = to_gc0310_sensor(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - - if (!dev->platform_data) { - dev_err(&client->dev, - "no camera_sensor_platform_data"); - return -ENODEV; - } - - if (dev->power_on) - return 0; /* Already on */ - - /* power control */ - ret = power_ctrl(sd, 1); - if (ret) - goto fail_power; - - /* flis clock control */ - ret = dev->platform_data->flisclk_ctrl(sd, 1); - if (ret) - goto fail_clk; - - /* gpio ctrl */ - ret = gpio_ctrl(sd, 1); - if (ret) { - ret = gpio_ctrl(sd, 1); - if (ret) - goto fail_gpio; - } - - msleep(100); - - dev->power_on = true; - return 0; - -fail_gpio: - dev->platform_data->flisclk_ctrl(sd, 0); -fail_clk: - power_ctrl(sd, 0); -fail_power: - dev_err(&client->dev, "sensor power-up failed\n"); - - return ret; -} - -static int power_down(struct v4l2_subdev *sd) -{ - struct gc0310_device *dev = to_gc0310_sensor(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret = 0; - - if (!dev->platform_data) { - dev_err(&client->dev, - "no camera_sensor_platform_data"); - return -ENODEV; - } - - if (!dev->power_on) - return 0; /* Already off */ - - /* gpio ctrl */ - ret = gpio_ctrl(sd, 0); - if (ret) { - ret = gpio_ctrl(sd, 0); - if (ret) - dev_err(&client->dev, "gpio failed 2\n"); - } - - ret = dev->platform_data->flisclk_ctrl(sd, 0); - if (ret) - dev_err(&client->dev, "flisclk failed\n"); - - /* power control */ - ret = power_ctrl(sd, 0); - if (ret) - dev_err(&client->dev, "vprog failed.\n"); - - dev->power_on = false; - return ret; -} - -static int gc0310_s_power(struct v4l2_subdev *sd, int on) +static struct v4l2_mbus_framefmt * +gc0310_get_pad_format(struct gc0310_device *dev, + struct v4l2_subdev_state *state, + unsigned int pad, enum v4l2_subdev_format_whence which) { - int ret; - - if (on == 0) - return power_down(sd); - - ret = power_up(sd); - if (ret) - return ret; + if (which == V4L2_SUBDEV_FORMAT_TRY) + return v4l2_subdev_get_try_format(&dev->sd, state, pad); - return gc0310_init(sd); + return &dev->mode.fmt; } -/* TODO: remove it. */ -static int startup(struct v4l2_subdev *sd) +/* The GC0310 currently only supports 1 fixed fmt */ +static void gc0310_fill_format(struct v4l2_mbus_framefmt *fmt) { - struct gc0310_device *dev = to_gc0310_sensor(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret = 0; - - ret = gc0310_write_reg_array(client, dev->res->regs); - if (ret) { - dev_err(&client->dev, "gc0310 write register err.\n"); - return ret; - } - - return ret; + memset(fmt, 0, sizeof(*fmt)); + fmt->width = GC0310_NATIVE_WIDTH; + fmt->height = GC0310_NATIVE_HEIGHT; + fmt->field = V4L2_FIELD_NONE; + fmt->code = MEDIA_BUS_FMT_SGRBG8_1X8; } static int gc0310_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { - struct v4l2_mbus_framefmt *fmt = &format->format; struct gc0310_device *dev = to_gc0310_sensor(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct camera_mipi_info *gc0310_info = NULL; - struct gc0310_resolution *res; - int ret = 0; - - if (format->pad) - return -EINVAL; + struct v4l2_mbus_framefmt *fmt; - if (!fmt) - return -EINVAL; - - gc0310_info = v4l2_get_subdev_hostdata(sd); - if (!gc0310_info) - return -EINVAL; - - mutex_lock(&dev->input_lock); - - res = v4l2_find_nearest_size(gc0310_res_preview, - ARRAY_SIZE(gc0310_res_preview), width, - height, fmt->width, fmt->height); - if (!res) - res = &gc0310_res_preview[N_RES - 1]; - - fmt->width = res->width; - fmt->height = res->height; - dev->res = res; - - fmt->code = MEDIA_BUS_FMT_SGRBG8_1X8; - - if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - sd_state->pads->try_fmt = *fmt; - mutex_unlock(&dev->input_lock); - return 0; - } - - /* s_power has not been called yet for std v4l2 clients (camorama) */ - power_up(sd); - - dev_dbg(&client->dev, "%s: before gc0310_write_reg_array %s\n", - __func__, dev->res->desc); - ret = startup(sd); - if (ret) { - dev_err(&client->dev, "gc0310 startup err\n"); - goto err; - } + fmt = gc0310_get_pad_format(dev, sd_state, format->pad, format->which); + gc0310_fill_format(fmt); -err: - mutex_unlock(&dev->input_lock); - return ret; + format->format = *fmt; + return 0; } static int gc0310_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { - struct v4l2_mbus_framefmt *fmt = &format->format; struct gc0310_device *dev = to_gc0310_sensor(sd); + struct v4l2_mbus_framefmt *fmt; - if (format->pad) - return -EINVAL; - - if (!fmt) - return -EINVAL; - - fmt->width = dev->res->width; - fmt->height = dev->res->height; - fmt->code = MEDIA_BUS_FMT_SGRBG8_1X8; - + fmt = gc0310_get_pad_format(dev, sd_state, format->pad, format->which); + format->format = *fmt; return 0; } static int gc0310_detect(struct i2c_client *client) { struct i2c_adapter *adapter = client->adapter; - u8 high, low; int ret; - u16 id; if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) return -ENODEV; - ret = gc0310_read_reg(client, GC0310_8BIT, - GC0310_SC_CMMN_CHIP_ID_H, &high); - if (ret) { - dev_err(&client->dev, "read sensor_id_high failed\n"); + ret = i2c_smbus_read_word_swapped(client, GC0310_SC_CMMN_CHIP_ID_H); + if (ret < 0) { + dev_err(&client->dev, "read sensor_id failed: %d\n", ret); return -ENODEV; } - ret = gc0310_read_reg(client, GC0310_8BIT, - GC0310_SC_CMMN_CHIP_ID_L, &low); - if (ret) { - dev_err(&client->dev, "read sensor_id_low failed\n"); - return -ENODEV; - } - id = ((((u16)high) << 8) | (u16)low); - dev_dbg(&client->dev, "sensor ID = 0x%x\n", id); - if (id != GC0310_ID) { - dev_err(&client->dev, "sensor ID error, read id = 0x%x, target id = 0x%x\n", id, - GC0310_ID); + dev_dbg(&client->dev, "sensor ID = 0x%x\n", ret); + + if (ret != GC0310_ID) { + dev_err(&client->dev, "sensor ID error, read id = 0x%x, target id = 0x%x\n", + ret, GC0310_ID); return -ENODEV; } @@ -774,116 +202,90 @@ static int gc0310_s_stream(struct v4l2_subdev *sd, int enable) { struct gc0310_device *dev = to_gc0310_sensor(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; + int ret = 0; dev_dbg(&client->dev, "%s S enable=%d\n", __func__, enable); mutex_lock(&dev->input_lock); - if (enable) { - /* enable per frame MIPI and sensor ctrl reset */ - ret = gc0310_write_reg(client, GC0310_8BIT, - 0xFE, 0x30); - if (ret) { - mutex_unlock(&dev->input_lock); - return ret; - } - } - - ret = gc0310_write_reg(client, GC0310_8BIT, - GC0310_RESET_RELATED, GC0310_REGISTER_PAGE_3); - if (ret) { - mutex_unlock(&dev->input_lock); - return ret; + if (dev->is_streaming == enable) { + dev_warn(&client->dev, "stream already %s\n", enable ? "started" : "stopped"); + goto error_unlock; } - ret = gc0310_write_reg(client, GC0310_8BIT, GC0310_SW_STREAM, - enable ? GC0310_START_STREAMING : - GC0310_STOP_STREAMING); - if (ret) { - mutex_unlock(&dev->input_lock); - return ret; - } + if (enable) { + ret = pm_runtime_get_sync(&client->dev); + if (ret < 0) + goto error_power_down; - ret = gc0310_write_reg(client, GC0310_8BIT, - GC0310_RESET_RELATED, GC0310_REGISTER_PAGE_0); - if (ret) { - mutex_unlock(&dev->input_lock); - return ret; - } + msleep(100); - mutex_unlock(&dev->input_lock); - return ret; -} - -static int gc0310_s_config(struct v4l2_subdev *sd, - int irq, void *platform_data) -{ - struct gc0310_device *dev = to_gc0310_sensor(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret = 0; + ret = gc0310_write_reg_array(client, gc0310_reset_register, + ARRAY_SIZE(gc0310_reset_register)); + if (ret) + goto error_power_down; - if (!platform_data) - return -ENODEV; + ret = gc0310_write_reg_array(client, gc0310_VGA_30fps, + ARRAY_SIZE(gc0310_VGA_30fps)); + if (ret) + goto error_power_down; - dev->platform_data = - (struct camera_sensor_platform_data *)platform_data; + /* restore value of all ctrls */ + ret = __v4l2_ctrl_handler_setup(&dev->ctrls.handler); + if (ret) + goto error_power_down; - mutex_lock(&dev->input_lock); - /* power off the module, then power on it in future - * as first power on by board may not fulfill the - * power on sequqence needed by the module - */ - dev->power_on = true; /* force power_down() to run */ - ret = power_down(sd); - if (ret) { - dev_err(&client->dev, "gc0310 power-off err.\n"); - goto fail_power_off; + /* enable per frame MIPI and sensor ctrl reset */ + ret = i2c_smbus_write_byte_data(client, 0xFE, 0x30); + if (ret) + goto error_power_down; } - ret = power_up(sd); - if (ret) { - dev_err(&client->dev, "gc0310 power-up err.\n"); - goto fail_power_on; - } + ret = i2c_smbus_write_byte_data(client, GC0310_RESET_RELATED, GC0310_REGISTER_PAGE_3); + if (ret) + goto error_power_down; - ret = dev->platform_data->csi_cfg(sd, 1); + ret = i2c_smbus_write_byte_data(client, GC0310_SW_STREAM, + enable ? GC0310_START_STREAMING : GC0310_STOP_STREAMING); if (ret) - goto fail_csi_cfg; + goto error_power_down; - /* config & detect sensor */ - ret = gc0310_detect(client); - if (ret) { - dev_err(&client->dev, "gc0310_detect err s_config.\n"); - goto fail_csi_cfg; - } + ret = i2c_smbus_write_byte_data(client, GC0310_RESET_RELATED, GC0310_REGISTER_PAGE_0); + if (ret) + goto error_power_down; - /* turn off sensor, after probed */ - ret = power_down(sd); - if (ret) { - dev_err(&client->dev, "gc0310 power-off err.\n"); - goto fail_csi_cfg; - } - mutex_unlock(&dev->input_lock); + if (!enable) + pm_runtime_put(&client->dev); + dev->is_streaming = enable; + mutex_unlock(&dev->input_lock); return 0; -fail_csi_cfg: - dev->platform_data->csi_cfg(sd, 0); -fail_power_on: - power_down(sd); - dev_err(&client->dev, "sensor power-gating failed\n"); -fail_power_off: +error_power_down: + pm_runtime_put(&client->dev); + dev->is_streaming = false; +error_unlock: mutex_unlock(&dev->input_lock); return ret; } +static int gc0310_s_config(struct v4l2_subdev *sd) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + int ret; + + ret = pm_runtime_get_sync(&client->dev); + if (ret >= 0) + ret = gc0310_detect(client); + + pm_runtime_put(&client->dev); + return ret; +} + static int gc0310_g_frame_interval(struct v4l2_subdev *sd, struct v4l2_subdev_frame_interval *interval) { - struct gc0310_device *dev = to_gc0310_sensor(sd); - interval->interval.numerator = 1; - interval->interval.denominator = dev->res->fps; + interval->interval.denominator = GC0310_FPS; return 0; } @@ -892,7 +294,8 @@ static int gc0310_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { - if (code->index >= MAX_FMTS) + /* We support only a single format */ + if (code->index) return -EINVAL; code->code = MEDIA_BUS_FMT_SGRBG8_1X8; @@ -903,27 +306,21 @@ static int gc0310_enum_frame_size(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { - int index = fse->index; - - if (index >= N_RES) + /* We support only a single resolution */ + if (fse->index) return -EINVAL; - fse->min_width = gc0310_res[index].width; - fse->min_height = gc0310_res[index].height; - fse->max_width = gc0310_res[index].width; - fse->max_height = gc0310_res[index].height; + fse->min_width = GC0310_NATIVE_WIDTH; + fse->max_width = GC0310_NATIVE_WIDTH; + fse->min_height = GC0310_NATIVE_HEIGHT; + fse->max_height = GC0310_NATIVE_HEIGHT; return 0; } static int gc0310_g_skip_frames(struct v4l2_subdev *sd, u32 *frames) { - struct gc0310_device *dev = to_gc0310_sensor(sd); - - mutex_lock(&dev->input_lock); - *frames = dev->res->skip_frames; - mutex_unlock(&dev->input_lock); - + *frames = GC0310_SKIP_FRAMES; return 0; } @@ -936,11 +333,6 @@ static const struct v4l2_subdev_video_ops gc0310_video_ops = { .g_frame_interval = gc0310_g_frame_interval, }; -static const struct v4l2_subdev_core_ops gc0310_core_ops = { - .s_power = gc0310_s_power, - .ioctl = gc0310_ioctl, -}; - static const struct v4l2_subdev_pad_ops gc0310_pad_ops = { .enum_mbus_code = gc0310_enum_mbus_code, .enum_frame_size = gc0310_enum_frame_size, @@ -949,12 +341,31 @@ static const struct v4l2_subdev_pad_ops gc0310_pad_ops = { }; static const struct v4l2_subdev_ops gc0310_ops = { - .core = &gc0310_core_ops, .video = &gc0310_video_ops, .pad = &gc0310_pad_ops, .sensor = &gc0310_sensor_ops, }; +static int gc0310_init_controls(struct gc0310_device *dev) +{ + struct v4l2_ctrl_handler *hdl = &dev->ctrls.handler; + + v4l2_ctrl_handler_init(hdl, 2); + + /* Use the same lock for controls as for everything else */ + hdl->lock = &dev->input_lock; + dev->sd.ctrl_handler = hdl; + + dev->ctrls.exposure = + v4l2_ctrl_new_std(hdl, &ctrl_ops, V4L2_CID_EXPOSURE, 0, 4095, 1, 1023); + + /* 32 steps at base gain 1 + 64 half steps at base gain 2 */ + dev->ctrls.gain = + v4l2_ctrl_new_std(hdl, &ctrl_ops, V4L2_CID_GAIN, 0, 95, 1, 31); + + return hdl->error; +} + static void gc0310_remove(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); @@ -962,11 +373,11 @@ static void gc0310_remove(struct i2c_client *client) dev_dbg(&client->dev, "gc0310_remove...\n"); - dev->platform_data->csi_cfg(sd, 0); - + atomisp_unregister_subdev(sd); v4l2_device_unregister_subdev(sd); media_entity_cleanup(&dev->sd.entity); - v4l2_ctrl_handler_free(&dev->ctrl_handler); + v4l2_ctrl_handler_free(&dev->ctrls.handler); + pm_runtime_disable(&client->dev); kfree(dev); } @@ -974,70 +385,91 @@ static int gc0310_probe(struct i2c_client *client) { struct gc0310_device *dev; int ret; - void *pdata; - unsigned int i; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = devm_kzalloc(&client->dev, sizeof(*dev), GFP_KERNEL); if (!dev) return -ENOMEM; - mutex_init(&dev->input_lock); + ret = v4l2_get_acpi_sensor_info(&client->dev, NULL); + if (ret) + return ret; - dev->res = &gc0310_res_preview[0]; - v4l2_i2c_subdev_init(&dev->sd, client, &gc0310_ops); + dev->reset = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(dev->reset)) + return dev_err_probe(&client->dev, PTR_ERR(dev->reset), + "getting reset GPIO\n"); - pdata = gmin_camera_platform_data(&dev->sd, - ATOMISP_INPUT_FORMAT_RAW_8, - atomisp_bayer_order_grbg); - if (!pdata) { - ret = -EINVAL; - goto out_free; - } + dev->powerdown = devm_gpiod_get(&client->dev, "powerdown", GPIOD_OUT_HIGH); + if (IS_ERR(dev->powerdown)) + return dev_err_probe(&client->dev, PTR_ERR(dev->powerdown), + "getting powerdown GPIO\n"); - ret = gc0310_s_config(&dev->sd, client->irq, pdata); - if (ret) - goto out_free; + mutex_init(&dev->input_lock); + v4l2_i2c_subdev_init(&dev->sd, client, &gc0310_ops); + gc0310_fill_format(&dev->mode.fmt); - ret = atomisp_register_i2c_module(&dev->sd, pdata, RAW_CAMERA); - if (ret) - goto out_free; + pm_runtime_set_suspended(&client->dev); + pm_runtime_enable(&client->dev); + pm_runtime_set_autosuspend_delay(&client->dev, 1000); + pm_runtime_use_autosuspend(&client->dev); + + ret = gc0310_s_config(&dev->sd); + if (ret) { + gc0310_remove(client); + return ret; + } dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; dev->pad.flags = MEDIA_PAD_FL_SOURCE; - dev->format.code = MEDIA_BUS_FMT_SGRBG8_1X8; dev->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; - ret = - v4l2_ctrl_handler_init(&dev->ctrl_handler, - ARRAY_SIZE(gc0310_controls)); + + ret = gc0310_init_controls(dev); if (ret) { gc0310_remove(client); return ret; } - for (i = 0; i < ARRAY_SIZE(gc0310_controls); i++) - v4l2_ctrl_new_custom(&dev->ctrl_handler, &gc0310_controls[i], - NULL); + ret = media_entity_pads_init(&dev->sd.entity, 1, &dev->pad); + if (ret) { + gc0310_remove(client); + return ret; + } - if (dev->ctrl_handler.error) { + ret = atomisp_register_sensor_no_gmin(&dev->sd, 1, ATOMISP_INPUT_FORMAT_RAW_8, + atomisp_bayer_order_grbg); + if (ret) { gc0310_remove(client); - return dev->ctrl_handler.error; + return ret; } - /* Use same lock for controls as for everything else. */ - dev->ctrl_handler.lock = &dev->input_lock; - dev->sd.ctrl_handler = &dev->ctrl_handler; + return 0; +} - ret = media_entity_pads_init(&dev->sd.entity, 1, &dev->pad); - if (ret) - gc0310_remove(client); +static int gc0310_suspend(struct device *dev) +{ + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct gc0310_device *gc0310_dev = to_gc0310_sensor(sd); - return ret; -out_free: - v4l2_device_unregister_subdev(&dev->sd); - kfree(dev); - return ret; + gpiod_set_value_cansleep(gc0310_dev->powerdown, 1); + gpiod_set_value_cansleep(gc0310_dev->reset, 1); + return 0; +} + +static int gc0310_resume(struct device *dev) +{ + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct gc0310_device *gc0310_dev = to_gc0310_sensor(sd); + + usleep_range(10000, 15000); + gpiod_set_value_cansleep(gc0310_dev->reset, 0); + usleep_range(10000, 15000); + gpiod_set_value_cansleep(gc0310_dev->powerdown, 0); + + return 0; } +static DEFINE_RUNTIME_DEV_PM_OPS(gc0310_pm_ops, gc0310_suspend, gc0310_resume, NULL); + static const struct acpi_device_id gc0310_acpi_match[] = { {"XXGC0310"}, {"INT0310"}, @@ -1048,6 +480,7 @@ MODULE_DEVICE_TABLE(acpi, gc0310_acpi_match); static struct i2c_driver gc0310_driver = { .driver = { .name = "gc0310", + .pm = pm_sleep_ptr(&gc0310_pm_ops), .acpi_match_table = gc0310_acpi_match, }, .probe_new = gc0310_probe, diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c index aeb38599fe13..63de214916f5 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c @@ -3,6 +3,7 @@ * Support for OmniVision OV2680 1080p HD camera sensor. * * Copyright (c) 2013 Intel Corporation. All Rights Reserved. + * Copyright (c) 2023 Hans de Goede <hdegoede@redhat.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version @@ -418,7 +419,7 @@ static int ov2680_s_stream(struct v4l2_subdev *sd, int enable) if (enable) { ret = pm_runtime_get_sync(sensor->sd.dev); if (ret < 0) - goto error_unlock; + goto error_power_down; ret = ov2680_set_mode(sensor); if (ret) @@ -446,6 +447,7 @@ static int ov2680_s_stream(struct v4l2_subdev *sd, int enable) error_power_down: pm_runtime_put(sensor->sd.dev); + sensor->is_streaming = false; error_unlock: mutex_unlock(&sensor->input_lock); return ret; @@ -614,21 +616,6 @@ static void ov2680_remove(struct i2c_client *client) pm_runtime_disable(&client->dev); } -/* - * Unlike other sensors which have both a rest and powerdown input pins, - * the OV2680 only has a powerdown input. But some ACPI tables still list - * 2 GPIOs for the OV2680 and it is unclear which to use. So try to get - * up to 2 GPIOs (1 mandatory, 1 optional) and control them in sync. - */ -static const struct acpi_gpio_params ov2680_first_gpio = { 0, 0, true }; -static const struct acpi_gpio_params ov2680_second_gpio = { 1, 0, true }; - -static const struct acpi_gpio_mapping ov2680_gpio_mapping[] = { - { "powerdown-gpios", &ov2680_first_gpio, 1 }, - { "powerdown-alt-gpios", &ov2680_second_gpio, 1 }, - { }, -}; - static int ov2680_probe(struct i2c_client *client) { struct device *dev = &client->dev; @@ -644,26 +631,24 @@ static int ov2680_probe(struct i2c_client *client) sensor->client = client; v4l2_i2c_subdev_init(&sensor->sd, client, &ov2680_ops); - ret = devm_acpi_dev_add_driver_gpios(&client->dev, ov2680_gpio_mapping); + ret = v4l2_get_acpi_sensor_info(dev, NULL); if (ret) return ret; - sensor->powerdown = devm_gpiod_get(dev, "powerdown", GPIOD_OUT_HIGH); + sensor->powerdown = devm_gpiod_get_optional(dev, "powerdown", GPIOD_OUT_HIGH); if (IS_ERR(sensor->powerdown)) return dev_err_probe(dev, PTR_ERR(sensor->powerdown), "getting powerdown GPIO\n"); - sensor->powerdown_alt = devm_gpiod_get_optional(dev, "powerdown-alt", GPIOD_OUT_HIGH); - if (IS_ERR(sensor->powerdown_alt)) - return dev_err_probe(dev, PTR_ERR(sensor->powerdown_alt), "getting powerdown-alt GPIO\n"); - pm_runtime_set_suspended(dev); pm_runtime_enable(dev); pm_runtime_set_autosuspend_delay(dev, 1000); pm_runtime_use_autosuspend(dev); ret = ov2680_s_config(&sensor->sd); - if (ret) + if (ret) { + ov2680_remove(client); return ret; + } sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; sensor->pad.flags = MEDIA_PAD_FL_SOURCE; @@ -699,7 +684,6 @@ static int ov2680_suspend(struct device *dev) struct ov2680_device *sensor = to_ov2680_sensor(sd); gpiod_set_value_cansleep(sensor->powerdown, 1); - gpiod_set_value_cansleep(sensor->powerdown_alt, 1); return 0; } @@ -712,7 +696,6 @@ static int ov2680_resume(struct device *dev) usleep_range(5000, 6000); gpiod_set_value_cansleep(sensor->powerdown, 0); - gpiod_set_value_cansleep(sensor->powerdown_alt, 0); /* according to DS, 20ms is needed between PWDN and i2c access */ msleep(20); diff --git a/drivers/staging/media/atomisp/i2c/gc0310.h b/drivers/staging/media/atomisp/i2c/gc0310.h index cae480ae6fba..d40406289598 100644 --- a/drivers/staging/media/atomisp/i2c/gc0310.h +++ b/drivers/staging/media/atomisp/i2c/gc0310.h @@ -33,34 +33,14 @@ #include "../include/linux/atomisp_platform.h" -/* Defines for register writes and register array processing */ -#define I2C_MSG_LENGTH 1 -#define I2C_RETRY_COUNT 5 +#define GC0310_NATIVE_WIDTH 656 +#define GC0310_NATIVE_HEIGHT 496 -#define GC0310_FOCAL_LENGTH_NUM 278 /*2.78mm*/ +#define GC0310_FPS 30 +#define GC0310_SKIP_FRAMES 3 -#define MAX_FMTS 1 +#define GC0310_FOCAL_LENGTH_NUM 278 /* 2.78mm */ -/* - * focal length bits definition: - * bits 31-16: numerator, bits 15-0: denominator - */ -#define GC0310_FOCAL_LENGTH_DEFAULT 0x1160064 - -/* - * current f-number bits definition: - * bits 31-16: numerator, bits 15-0: denominator - */ -#define GC0310_F_NUMBER_DEFAULT 0x1a000a - -/* - * f-number range bits definition: - * bits 31-24: max f-number numerator - * bits 23-16: max f-number denominator - * bits 15-8: min f-number numerator - * bits 7-0: min f-number denominator - */ -#define GC0310_F_NUMBER_RANGE 0x1a0a1a0a #define GC0310_ID 0xa310 #define GC0310_RESET_RELATED 0xFE @@ -105,84 +85,43 @@ #define GC0310_START_STREAMING 0x94 /* 8-bit enable */ #define GC0310_STOP_STREAMING 0x0 /* 8-bit disable */ -#define GC0310_BIN_FACTOR_MAX 3 - -struct regval_list { - u16 reg_num; - u8 value; -}; - -struct gc0310_resolution { - u8 *desc; - const struct gc0310_reg *regs; - int res; - int width; - int height; - int fps; - int pix_clk_freq; - u32 skip_frames; - u16 pixels_per_line; - u16 lines_per_frame; - bool used; -}; - -struct gc0310_format { - u8 *desc; - u32 pixelformat; - struct gc0310_reg *regs; -}; - /* * gc0310 device structure. */ struct gc0310_device { struct v4l2_subdev sd; struct media_pad pad; - struct v4l2_mbus_framefmt format; struct mutex input_lock; - struct v4l2_ctrl_handler ctrl_handler; + bool is_streaming; - struct camera_sensor_platform_data *platform_data; - struct gc0310_resolution *res; - u8 type; - bool power_on; -}; + struct gpio_desc *reset; + struct gpio_desc *powerdown; -enum gc0310_tok_type { - GC0310_8BIT = 0x0001, - GC0310_TOK_TERM = 0xf000, /* terminating token for reg list */ - GC0310_TOK_DELAY = 0xfe00, /* delay token for reg list */ - GC0310_TOK_MASK = 0xfff0 + struct gc0310_mode { + struct v4l2_mbus_framefmt fmt; + } mode; + + struct gc0310_ctrls { + struct v4l2_ctrl_handler handler; + struct v4l2_ctrl *exposure; + struct v4l2_ctrl *gain; + } ctrls; }; /** * struct gc0310_reg - MI sensor register format - * @type: type of the register * @reg: 16-bit offset to register * @val: 8/16/32-bit register value * * Define a structure for sensor register initialization values */ struct gc0310_reg { - enum gc0310_tok_type type; u8 reg; u8 val; /* @set value for read/mod/write, @mask */ }; #define to_gc0310_sensor(x) container_of(x, struct gc0310_device, sd) -#define GC0310_MAX_WRITE_BUF_SIZE 30 - -struct gc0310_write_buffer { - u8 addr; - u8 data[GC0310_MAX_WRITE_BUF_SIZE]; -}; - -struct gc0310_write_ctrl { - int index; - struct gc0310_write_buffer buffer; -}; - /* * Register settings for various resolution */ @@ -190,206 +129,181 @@ static const struct gc0310_reg gc0310_reset_register[] = { ///////////////////////////////////////////////// ///////////////// system reg ///////////////// ///////////////////////////////////////////////// - {GC0310_8BIT, 0xfe, 0xf0}, - {GC0310_8BIT, 0xfe, 0xf0}, - {GC0310_8BIT, 0xfe, 0x00}, - - {GC0310_8BIT, 0xfc, 0x0e}, //4e - {GC0310_8BIT, 0xfc, 0x0e}, //16//4e // [0]apwd [6]regf_clk_gate - {GC0310_8BIT, 0xf2, 0x80}, //sync output - {GC0310_8BIT, 0xf3, 0x00}, //1f//01 data output - {GC0310_8BIT, 0xf7, 0x33}, //f9 - {GC0310_8BIT, 0xf8, 0x05}, //00 - {GC0310_8BIT, 0xf9, 0x0e}, // 0x8e //0f - {GC0310_8BIT, 0xfa, 0x11}, + { 0xfe, 0xf0 }, + { 0xfe, 0xf0 }, + { 0xfe, 0x00 }, + + { 0xfc, 0x0e }, /* 4e */ + { 0xfc, 0x0e }, /* 16//4e // [0]apwd [6]regf_clk_gate */ + { 0xf2, 0x80 }, /* sync output */ + { 0xf3, 0x00 }, /* 1f//01 data output */ + { 0xf7, 0x33 }, /* f9 */ + { 0xf8, 0x05 }, /* 00 */ + { 0xf9, 0x0e }, /* 0x8e //0f */ + { 0xfa, 0x11 }, ///////////////////////////////////////////////// /////////////////// MIPI //////////////////// ///////////////////////////////////////////////// - {GC0310_8BIT, 0xfe, 0x03}, - {GC0310_8BIT, 0x01, 0x03}, ///mipi 1lane - {GC0310_8BIT, 0x02, 0x22}, // 0x33 - {GC0310_8BIT, 0x03, 0x94}, - {GC0310_8BIT, 0x04, 0x01}, // fifo_prog - {GC0310_8BIT, 0x05, 0x00}, //fifo_prog - {GC0310_8BIT, 0x06, 0x80}, //b0 //YUV ISP data - {GC0310_8BIT, 0x11, 0x2a},//1e //LDI set YUV422 - {GC0310_8BIT, 0x12, 0x90},//00 //04 //00 //04//00 //LWC[7:0] // - {GC0310_8BIT, 0x13, 0x02},//05 //05 //LWC[15:8] - {GC0310_8BIT, 0x15, 0x12}, // 0x10 //DPHYY_MODE read_ready - {GC0310_8BIT, 0x17, 0x01}, - {GC0310_8BIT, 0x40, 0x08}, - {GC0310_8BIT, 0x41, 0x00}, - {GC0310_8BIT, 0x42, 0x00}, - {GC0310_8BIT, 0x43, 0x00}, - {GC0310_8BIT, 0x21, 0x02}, // 0x01 - {GC0310_8BIT, 0x22, 0x02}, // 0x01 - {GC0310_8BIT, 0x23, 0x01}, // 0x05 //Nor:0x05 DOU:0x06 - {GC0310_8BIT, 0x29, 0x00}, - {GC0310_8BIT, 0x2A, 0x25}, // 0x05 //data zero 0x7a de - {GC0310_8BIT, 0x2B, 0x02}, - - {GC0310_8BIT, 0xfe, 0x00}, + { 0xfe, 0x03 }, + { 0x01, 0x03 }, /* mipi 1lane */ + { 0x02, 0x22 }, /* 0x33 */ + { 0x03, 0x94 }, + { 0x04, 0x01 }, /* fifo_prog */ + { 0x05, 0x00 }, /* fifo_prog */ + { 0x06, 0x80 }, /* b0 //YUV ISP data */ + { 0x11, 0x2a }, /* 1e //LDI set YUV422 */ + { 0x12, 0x90 }, /* 00 //04 //00 //04//00 //LWC[7:0] */ + { 0x13, 0x02 }, /* 05 //05 //LWC[15:8] */ + { 0x15, 0x12 }, /* 0x10 //DPHYY_MODE read_ready */ + { 0x17, 0x01 }, + { 0x40, 0x08 }, + { 0x41, 0x00 }, + { 0x42, 0x00 }, + { 0x43, 0x00 }, + { 0x21, 0x02 }, /* 0x01 */ + { 0x22, 0x02 }, /* 0x01 */ + { 0x23, 0x01 }, /* 0x05 //Nor:0x05 DOU:0x06 */ + { 0x29, 0x00 }, + { 0x2A, 0x25 }, /* 0x05 //data zero 0x7a de */ + { 0x2B, 0x02 }, + + { 0xfe, 0x00 }, ///////////////////////////////////////////////// ///////////////// CISCTL reg ///////////////// ///////////////////////////////////////////////// - {GC0310_8BIT, 0x00, 0x2f}, //2f//0f//02//01 - {GC0310_8BIT, 0x01, 0x0f}, //06 - {GC0310_8BIT, 0x02, 0x04}, - {GC0310_8BIT, 0x4f, 0x00}, //AEC 0FF - {GC0310_8BIT, 0x03, 0x01}, // 0x03 //04 - {GC0310_8BIT, 0x04, 0xc0}, // 0xe8 //58 - {GC0310_8BIT, 0x05, 0x00}, - {GC0310_8BIT, 0x06, 0xb2}, // 0x0a //HB - {GC0310_8BIT, 0x07, 0x00}, - {GC0310_8BIT, 0x08, 0x0c}, // 0x89 //VB - {GC0310_8BIT, 0x09, 0x00}, //row start - {GC0310_8BIT, 0x0a, 0x00}, // - {GC0310_8BIT, 0x0b, 0x00}, //col start - {GC0310_8BIT, 0x0c, 0x00}, - {GC0310_8BIT, 0x0d, 0x01}, //height - {GC0310_8BIT, 0x0e, 0xf2}, // 0xf7 //height - {GC0310_8BIT, 0x0f, 0x02}, //width - {GC0310_8BIT, 0x10, 0x94}, // 0xa0 //height - {GC0310_8BIT, 0x17, 0x14}, - {GC0310_8BIT, 0x18, 0x1a}, //0a//[4]double reset - {GC0310_8BIT, 0x19, 0x14}, //AD pipeline - {GC0310_8BIT, 0x1b, 0x48}, - {GC0310_8BIT, 0x1e, 0x6b}, //3b//col bias - {GC0310_8BIT, 0x1f, 0x28}, //20//00//08//txlow - {GC0310_8BIT, 0x20, 0x89}, //88//0c//[3:2]DA15 - {GC0310_8BIT, 0x21, 0x49}, //48//[3] txhigh - {GC0310_8BIT, 0x22, 0xb0}, - {GC0310_8BIT, 0x23, 0x04}, //[1:0]vcm_r - {GC0310_8BIT, 0x24, 0x16}, //15 - {GC0310_8BIT, 0x34, 0x20}, //[6:4] rsg high//range + { 0x00, 0x2f }, /* 2f//0f//02//01 */ + { 0x01, 0x0f }, /* 06 */ + { 0x02, 0x04 }, + { 0x4f, 0x00 }, /* AEC 0FF */ + { 0x03, 0x01 }, /* 0x03 //04 */ + { 0x04, 0xc0 }, /* 0xe8 //58 */ + { 0x05, 0x00 }, + { 0x06, 0xb2 }, /* 0x0a //HB */ + { 0x07, 0x00 }, + { 0x08, 0x0c }, /* 0x89 //VB */ + { 0x09, 0x00 }, /* row start */ + { 0x0a, 0x00 }, + { 0x0b, 0x00 }, /* col start */ + { 0x0c, 0x00 }, + { 0x0d, 0x01 }, /* height */ + { 0x0e, 0xf2 }, /* 0xf7 //height */ + { 0x0f, 0x02 }, /* width */ + { 0x10, 0x94 }, /* 0xa0 //height */ + { 0x17, 0x14 }, + { 0x18, 0x1a }, /* 0a//[4]double reset */ + { 0x19, 0x14 }, /* AD pipeline */ + { 0x1b, 0x48 }, + { 0x1e, 0x6b }, /* 3b//col bias */ + { 0x1f, 0x28 }, /* 20//00//08//txlow */ + { 0x20, 0x89 }, /* 88//0c//[3:2]DA15 */ + { 0x21, 0x49 }, /* 48//[3] txhigh */ + { 0x22, 0xb0 }, + { 0x23, 0x04 }, /* [1:0]vcm_r */ + { 0x24, 0x16 }, /* 15 */ + { 0x34, 0x20 }, /* [6:4] rsg high//range */ ///////////////////////////////////////////////// //////////////////// BLK //////////////////// ///////////////////////////////////////////////// - {GC0310_8BIT, 0x26, 0x23}, //[1]dark_current_en [0]offset_en - {GC0310_8BIT, 0x28, 0xff}, //BLK_limie_value - {GC0310_8BIT, 0x29, 0x00}, //global offset - {GC0310_8BIT, 0x33, 0x18}, //offset_ratio - {GC0310_8BIT, 0x37, 0x20}, //dark_current_ratio - {GC0310_8BIT, 0x2a, 0x00}, - {GC0310_8BIT, 0x2b, 0x00}, - {GC0310_8BIT, 0x2c, 0x00}, - {GC0310_8BIT, 0x2d, 0x00}, - {GC0310_8BIT, 0x2e, 0x00}, - {GC0310_8BIT, 0x2f, 0x00}, - {GC0310_8BIT, 0x30, 0x00}, - {GC0310_8BIT, 0x31, 0x00}, - {GC0310_8BIT, 0x47, 0x80}, //a7 - {GC0310_8BIT, 0x4e, 0x66}, //select_row - {GC0310_8BIT, 0xa8, 0x02}, //win_width_dark, same with crop_win_width - {GC0310_8BIT, 0xa9, 0x80}, + { 0x26, 0x23 }, /* [1]dark_current_en [0]offset_en */ + { 0x28, 0xff }, /* BLK_limie_value */ + { 0x29, 0x00 }, /* global offset */ + { 0x33, 0x18 }, /* offset_ratio */ + { 0x37, 0x20 }, /* dark_current_ratio */ + { 0x2a, 0x00 }, + { 0x2b, 0x00 }, + { 0x2c, 0x00 }, + { 0x2d, 0x00 }, + { 0x2e, 0x00 }, + { 0x2f, 0x00 }, + { 0x30, 0x00 }, + { 0x31, 0x00 }, + { 0x47, 0x80 }, /* a7 */ + { 0x4e, 0x66 }, /* select_row */ + { 0xa8, 0x02 }, /* win_width_dark, same with crop_win_width */ + { 0xa9, 0x80 }, ///////////////////////////////////////////////// ////////////////// ISP reg /////////////////// ///////////////////////////////////////////////// - {GC0310_8BIT, 0x40, 0x06}, // 0xff //ff //48 - {GC0310_8BIT, 0x41, 0x00}, // 0x21 //00//[0]curve_en - {GC0310_8BIT, 0x42, 0x04}, // 0xcf //0a//[1]awn_en - {GC0310_8BIT, 0x44, 0x18}, // 0x18 //02 - {GC0310_8BIT, 0x46, 0x02}, // 0x03 //sync - {GC0310_8BIT, 0x49, 0x03}, - {GC0310_8BIT, 0x4c, 0x20}, //00[5]pretect exp - {GC0310_8BIT, 0x50, 0x01}, //crop enable - {GC0310_8BIT, 0x51, 0x00}, - {GC0310_8BIT, 0x52, 0x00}, - {GC0310_8BIT, 0x53, 0x00}, - {GC0310_8BIT, 0x54, 0x01}, - {GC0310_8BIT, 0x55, 0x01}, //crop window height - {GC0310_8BIT, 0x56, 0xf0}, - {GC0310_8BIT, 0x57, 0x02}, //crop window width - {GC0310_8BIT, 0x58, 0x90}, + { 0x40, 0x06 }, /* 0xff //ff //48 */ + { 0x41, 0x00 }, /* 0x21 //00//[0]curve_en */ + { 0x42, 0x04 }, /* 0xcf //0a//[1]awn_en */ + { 0x44, 0x18 }, /* 0x18 //02 */ + { 0x46, 0x02 }, /* 0x03 //sync */ + { 0x49, 0x03 }, + { 0x4c, 0x20 }, /* 00[5]pretect exp */ + { 0x50, 0x01 }, /* crop enable */ + { 0x51, 0x00 }, + { 0x52, 0x00 }, + { 0x53, 0x00 }, + { 0x54, 0x01 }, + { 0x55, 0x01 }, /* crop window height */ + { 0x56, 0xf0 }, + { 0x57, 0x02 }, /* crop window width */ + { 0x58, 0x90 }, ///////////////////////////////////////////////// /////////////////// GAIN //////////////////// ///////////////////////////////////////////////// - {GC0310_8BIT, 0x70, 0x70}, //70 //80//global gain - {GC0310_8BIT, 0x71, 0x20}, // pregain gain - {GC0310_8BIT, 0x72, 0x40}, // post gain - {GC0310_8BIT, 0x5a, 0x84}, //84//analog gain 0 - {GC0310_8BIT, 0x5b, 0xc9}, //c9 - {GC0310_8BIT, 0x5c, 0xed}, //ed//not use pga gain highest level - {GC0310_8BIT, 0x77, 0x40}, // R gain 0x74 //awb gain - {GC0310_8BIT, 0x78, 0x40}, // G gain - {GC0310_8BIT, 0x79, 0x40}, // B gain 0x5f - - {GC0310_8BIT, 0x48, 0x00}, - {GC0310_8BIT, 0xfe, 0x01}, - {GC0310_8BIT, 0x0a, 0x45}, //[7]col gain mode - - {GC0310_8BIT, 0x3e, 0x40}, - {GC0310_8BIT, 0x3f, 0x5c}, - {GC0310_8BIT, 0x40, 0x7b}, - {GC0310_8BIT, 0x41, 0xbd}, - {GC0310_8BIT, 0x42, 0xf6}, - {GC0310_8BIT, 0x43, 0x63}, - {GC0310_8BIT, 0x03, 0x60}, - {GC0310_8BIT, 0x44, 0x03}, + { 0x70, 0x70 }, /* 70 //80//global gain */ + { 0x71, 0x20 }, /* pregain gain */ + { 0x72, 0x40 }, /* post gain */ + { 0x5a, 0x84 }, /* 84//analog gain 0 */ + { 0x5b, 0xc9 }, /* c9 */ + { 0x5c, 0xed }, /* ed//not use pga gain highest level */ + { 0x77, 0x40 }, /* R gain 0x74 //awb gain */ + { 0x78, 0x40 }, /* G gain */ + { 0x79, 0x40 }, /* B gain 0x5f */ + + { 0x48, 0x00 }, + { 0xfe, 0x01 }, + { 0x0a, 0x45 }, /* [7]col gain mode */ + + { 0x3e, 0x40 }, + { 0x3f, 0x5c }, + { 0x40, 0x7b }, + { 0x41, 0xbd }, + { 0x42, 0xf6 }, + { 0x43, 0x63 }, + { 0x03, 0x60 }, + { 0x44, 0x03 }, ///////////////////////////////////////////////// ///////////////// dark sun ////////////////// ///////////////////////////////////////////////// - {GC0310_8BIT, 0xfe, 0x01}, - {GC0310_8BIT, 0x45, 0xa4}, // 0xf7 - {GC0310_8BIT, 0x46, 0xf0}, // 0xff //f0//sun value th - {GC0310_8BIT, 0x48, 0x03}, //sun mode - {GC0310_8BIT, 0x4f, 0x60}, //sun_clamp - {GC0310_8BIT, 0xfe, 0x00}, - - {GC0310_TOK_TERM, 0, 0}, + { 0xfe, 0x01 }, + { 0x45, 0xa4 }, /* 0xf7 */ + { 0x46, 0xf0 }, /* 0xff //f0//sun value th */ + { 0x48, 0x03 }, /* sun mode */ + { 0x4f, 0x60 }, /* sun_clamp */ + { 0xfe, 0x00 }, }; static struct gc0310_reg const gc0310_VGA_30fps[] = { - {GC0310_8BIT, 0xfe, 0x00}, - {GC0310_8BIT, 0x0d, 0x01}, //height - {GC0310_8BIT, 0x0e, 0xf2}, // 0xf7 //height - {GC0310_8BIT, 0x0f, 0x02}, //width - {GC0310_8BIT, 0x10, 0x94}, // 0xa0 //height - - {GC0310_8BIT, 0x50, 0x01}, //crop enable - {GC0310_8BIT, 0x51, 0x00}, - {GC0310_8BIT, 0x52, 0x00}, - {GC0310_8BIT, 0x53, 0x00}, - {GC0310_8BIT, 0x54, 0x01}, - {GC0310_8BIT, 0x55, 0x01}, //crop window height - {GC0310_8BIT, 0x56, 0xf0}, - {GC0310_8BIT, 0x57, 0x02}, //crop window width - {GC0310_8BIT, 0x58, 0x90}, - - {GC0310_8BIT, 0xfe, 0x03}, - {GC0310_8BIT, 0x12, 0x90},//00 //04 //00 //04//00 //LWC[7:0] // - {GC0310_8BIT, 0x13, 0x02},//05 //05 //LWC[15:8] - - {GC0310_8BIT, 0xfe, 0x00}, - - {GC0310_TOK_TERM, 0, 0}, -}; - -static struct gc0310_resolution gc0310_res_preview[] = { - { - .desc = "gc0310_VGA_30fps", - .width = 656, // 648, - .height = 496, // 488, - .fps = 30, - //.pix_clk_freq = 73, - .used = 0, -#if 0 - .pixels_per_line = 0x0314, - .lines_per_frame = 0x0213, -#endif - .skip_frames = 2, - .regs = gc0310_VGA_30fps, - }, + { 0xfe, 0x00 }, + { 0x0d, 0x01 }, /* height */ + { 0x0e, 0xf2 }, /* 0xf7 //height */ + { 0x0f, 0x02 }, /* width */ + { 0x10, 0x94 }, /* 0xa0 //height */ + + { 0x50, 0x01 }, /* crop enable */ + { 0x51, 0x00 }, + { 0x52, 0x00 }, + { 0x53, 0x00 }, + { 0x54, 0x01 }, + { 0x55, 0x01 }, /* crop window height */ + { 0x56, 0xf0 }, + { 0x57, 0x02 }, /* crop window width */ + { 0x58, 0x90 }, + + { 0xfe, 0x03 }, + { 0x12, 0x90 }, /* 00 //04 //00 //04//00 //LWC[7:0] */ + { 0x13, 0x02 }, /* 05 //05 //LWC[15:8] */ + + { 0xfe, 0x00 }, }; -#define N_RES_PREVIEW (ARRAY_SIZE(gc0310_res_preview)) - -static struct gc0310_resolution *gc0310_res = gc0310_res_preview; -static unsigned long N_RES = N_RES_PREVIEW; #endif diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h index a37af0a74a53..baf49eb0659e 100644 --- a/drivers/staging/media/atomisp/i2c/ov2680.h +++ b/drivers/staging/media/atomisp/i2c/ov2680.h @@ -114,7 +114,6 @@ struct ov2680_device { struct mutex input_lock; struct i2c_client *client; struct gpio_desc *powerdown; - struct gpio_desc *powerdown_alt; bool is_streaming; struct ov2680_mode { diff --git a/drivers/staging/media/atomisp/include/linux/atomisp.h b/drivers/staging/media/atomisp/include/linux/atomisp.h index 63b1bcd35399..c7ec56a1c064 100644 --- a/drivers/staging/media/atomisp/include/linux/atomisp.h +++ b/drivers/staging/media/atomisp/include/linux/atomisp.h @@ -299,26 +299,6 @@ struct atomisp_3a_statistics { u32 isp_config_id; /* isp config ID */ }; -/** - * struct atomisp_cont_capture_conf - continuous capture parameters - * @num_captures: number of still images to capture - * @skip_frames: number of frames to skip between 2 captures - * @offset: offset in ring buffer to start capture - * - * For example, to capture 1 frame from past, current, and 1 from future - * and skip one frame between each capture, parameters would be: - * num_captures:3 - * skip_frames:1 - * offset:-2 - */ - -struct atomisp_cont_capture_conf { - int num_captures; - unsigned int skip_frames; - int offset; - __u32 reserved[5]; -}; - struct atomisp_ae_window { int x_left; int x_right; @@ -958,9 +938,6 @@ struct atomisp_sensor_ae_bracketing_lut { #define ATOMISP_IOC_S_PARAMETERS \ _IOW('v', BASE_VIDIOC_PRIVATE + 32, struct atomisp_parameters) -#define ATOMISP_IOC_S_CONT_CAPTURE_CONFIG \ - _IOWR('v', BASE_VIDIOC_PRIVATE + 33, struct atomisp_cont_capture_conf) - #define ATOMISP_IOC_G_METADATA \ _IOWR('v', BASE_VIDIOC_PRIVATE + 34, struct atomisp_metadata) @@ -1079,8 +1056,6 @@ struct atomisp_sensor_ae_bracketing_lut { #define V4L2_2A_STATUS_AE_READY BIT(0) #define V4L2_2A_STATUS_AWB_READY BIT(1) -#define V4L2_CID_FMT_AUTO (V4L2_CID_CAMERA_LASTP1 + 19) - #define V4L2_CID_RUN_MODE (V4L2_CID_CAMERA_LASTP1 + 20) #define ATOMISP_RUN_MODE_VIDEO 1 #define ATOMISP_RUN_MODE_STILL_CAPTURE 2 @@ -1107,8 +1082,6 @@ struct atomisp_sensor_ae_bracketing_lut { /* Lock and unlock raw buffer */ #define V4L2_CID_ENABLE_RAW_BUFFER_LOCK (V4L2_CID_CAMERA_LASTP1 + 29) -#define V4L2_CID_DEPTH_MODE (V4L2_CID_CAMERA_LASTP1 + 30) - #define V4L2_CID_EXPOSURE_ZONE_NUM (V4L2_CID_CAMERA_LASTP1 + 31) /* Disable digital zoom */ #define V4L2_CID_DISABLE_DZ (V4L2_CID_CAMERA_LASTP1 + 32) @@ -1127,7 +1100,6 @@ struct atomisp_sensor_ae_bracketing_lut { #define V4L2_EVENT_ATOMISP_3A_STATS_READY (V4L2_EVENT_PRIVATE_START + 1) #define V4L2_EVENT_ATOMISP_METADATA_READY (V4L2_EVENT_PRIVATE_START + 2) -#define V4L2_EVENT_ATOMISP_RAW_BUFFERS_ALLOC_DONE (V4L2_EVENT_PRIVATE_START + 3) #define V4L2_EVENT_ATOMISP_ACC_COMPLETE (V4L2_EVENT_PRIVATE_START + 4) #define V4L2_EVENT_ATOMISP_PAUSE_BUFFER (V4L2_EVENT_PRIVATE_START + 5) #define V4L2_EVENT_ATOMISP_CSS_RESET (V4L2_EVENT_PRIVATE_START + 6) diff --git a/drivers/staging/media/atomisp/include/linux/atomisp_platform.h b/drivers/staging/media/atomisp/include/linux/atomisp_platform.h index 539b21d39d3b..e8e965f73fc8 100644 --- a/drivers/staging/media/atomisp/include/linux/atomisp_platform.h +++ b/drivers/staging/media/atomisp/include/linux/atomisp_platform.h @@ -111,12 +111,9 @@ enum atomisp_input_format { enum intel_v4l2_subdev_type { RAW_CAMERA = 1, - SOC_CAMERA = 2, - CAMERA_MOTOR = 3, - LED_FLASH = 4, - XENON_FLASH = 5, - FILE_INPUT = 6, - TEST_PATTERN = 7, + CAMERA_MOTOR = 2, + LED_FLASH = 3, + TEST_PATTERN = 4, }; struct intel_v4l2_subdev_id { @@ -216,6 +213,8 @@ int atomisp_register_sensor_no_gmin(struct v4l2_subdev *subdev, u32 lanes, enum atomisp_bayer_order bayer_order); void atomisp_unregister_subdev(struct v4l2_subdev *subdev); +int v4l2_get_acpi_sensor_info(struct device *dev, char **module_id_str); + /* API from old platform_camera.h, new CPUID implementation */ #define __IS_SOC(x) (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && \ boot_cpu_data.x86 == 6 && \ diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c index 47f18ac5e40e..aa790ae746f3 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c @@ -79,8 +79,6 @@ union host { } ptr; }; -static int atomisp_set_raw_buffer_bitmap(struct atomisp_sub_device *asd, int exp_id); - /* * get sensor:dis71430/ov2720 related info from v4l2_subdev->priv data field. * subdev->priv is set in mrst.c @@ -198,19 +196,12 @@ int atomisp_freq_scaling(struct atomisp_device *isp, enum atomisp_dfs_mode mode, bool force) { - struct pci_dev *pdev = to_pci_dev(isp->dev); - /* FIXME! Only use subdev[0] status yet */ - struct atomisp_sub_device *asd = &isp->asd[0]; const struct atomisp_dfs_config *dfs; unsigned int new_freq; struct atomisp_freq_scaling_rule curr_rules; int i, ret; unsigned short fps = 0; - if ((pdev->device & ATOMISP_PCI_DEVICE_SOC_MASK) == - ATOMISP_PCI_DEVICE_SOC_CHT && ATOMISP_USE_YUVPP(asd)) - isp->dfs = &dfs_config_cht_soc; - dfs = isp->dfs; if (dfs->lowest_freq == 0 || dfs->max_freq_at_vmin == 0 || @@ -230,7 +221,7 @@ int atomisp_freq_scaling(struct atomisp_device *isp, goto done; } - fps = atomisp_get_sensor_fps(asd); + fps = atomisp_get_sensor_fps(&isp->asd); if (fps == 0) { dev_info(isp->dev, "Sensor didn't report FPS. Using DFS max mode.\n"); @@ -238,22 +229,10 @@ int atomisp_freq_scaling(struct atomisp_device *isp, goto done; } - curr_rules.width = asd->fmt[asd->capture_pad].fmt.width; - curr_rules.height = asd->fmt[asd->capture_pad].fmt.height; + curr_rules.width = isp->asd.fmt[isp->asd.capture_pad].fmt.width; + curr_rules.height = isp->asd.fmt[isp->asd.capture_pad].fmt.height; curr_rules.fps = fps; - curr_rules.run_mode = asd->run_mode->val; - /* - * For continuous mode, we need to make the capture setting applied - * since preview mode, because there is no chance to do this when - * starting image capture. - */ - if (asd->continuous_mode->val) { - if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) - curr_rules.run_mode = ATOMISP_RUN_MODE_SDV; - else - curr_rules.run_mode = - ATOMISP_RUN_MODE_CONTINUOUS_CAPTURE; - } + curr_rules.run_mode = isp->asd.run_mode->val; /* search for the target frequency by looping freq rules*/ for (i = 0; i < dfs->dfs_table_size; i++) { @@ -470,37 +449,13 @@ static void clear_irq_reg(struct atomisp_device *isp) pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, msg_ret); } -static struct atomisp_sub_device * -__get_asd_from_port(struct atomisp_device *isp, enum mipi_port_id port) -{ - int i; - - /* Check which isp subdev to send eof */ - for (i = 0; i < isp->num_of_streams; i++) { - struct atomisp_sub_device *asd = &isp->asd[i]; - struct camera_mipi_info *mipi_info; - - mipi_info = atomisp_to_sensor_mipi_info( - isp->inputs[asd->input_curr].camera); - - if (asd->streaming == ATOMISP_DEVICE_STREAMING_ENABLED && - __get_mipi_port(isp, mipi_info->port) == port) { - return asd; - } - } - - return NULL; -} - /* interrupt handling function*/ irqreturn_t atomisp_isr(int irq, void *dev) { struct atomisp_device *isp = (struct atomisp_device *)dev; - struct atomisp_sub_device *asd; struct atomisp_css_event eof_event; unsigned int irq_infos = 0; unsigned long flags; - unsigned int i; int err; spin_lock_irqsave(&isp->lock, flags); @@ -520,18 +475,10 @@ irqreturn_t atomisp_isr(int irq, void *dev) if (!atomisp_streaming_count(isp)) goto out_nowake; - for (i = 0; i < isp->num_of_streams; i++) { - asd = &isp->asd[i]; - - if (asd->streaming != ATOMISP_DEVICE_STREAMING_ENABLED) - continue; - /* - * Current SOF only support one stream, so the SOF only valid - * either solely one stream is running - */ + if (isp->asd.streaming == ATOMISP_DEVICE_STREAMING_ENABLED) { if (irq_infos & IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF) { - atomic_inc(&asd->sof_count); - atomisp_sof_event(asd); + atomic_inc(&isp->asd.sof_count); + atomisp_sof_event(&isp->asd); /* If sequence_temp and sequence are the same * there where no frames lost so we can increase @@ -541,14 +488,14 @@ irqreturn_t atomisp_isr(int irq, void *dev) * NOTE: There is assumption here that ISP will not * start processing next frame from sensor before old * one is completely done. */ - if (atomic_read(&asd->sequence) == atomic_read( - &asd->sequence_temp)) - atomic_set(&asd->sequence_temp, - atomic_read(&asd->sof_count)); + if (atomic_read(&isp->asd.sequence) == + atomic_read(&isp->asd.sequence_temp)) + atomic_set(&isp->asd.sequence_temp, + atomic_read(&isp->asd.sof_count)); } if (irq_infos & IA_CSS_IRQ_INFO_EVENTS_READY) - atomic_set(&asd->sequence, - atomic_read(&asd->sequence_temp)); + atomic_set(&isp->asd.sequence, + atomic_read(&isp->asd.sequence_temp)); } if (irq_infos & IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF) { @@ -573,21 +520,10 @@ irqreturn_t atomisp_isr(int irq, void *dev) } if (irq_infos & IA_CSS_IRQ_INFO_ISYS_EVENTS_READY) { - while (ia_css_dequeue_isys_event(&eof_event.event) == - 0) { - /* EOF Event does not have the css_pipe returned */ - asd = __get_asd_from_port(isp, eof_event.event.port); - if (!asd) { - dev_err(isp->dev, "%s: ISYS event, but no subdev.event:%d", - __func__, eof_event.event.type); - continue; - } - - atomisp_eof_event(asd, eof_event.event.exp_id); - dev_dbg_ratelimited(isp->dev, - "%s ISYS event: EOF exp_id %d, asd %d\n", - __func__, eof_event.event.exp_id, - asd->index); + while (ia_css_dequeue_isys_event(&eof_event.event) == 0) { + atomisp_eof_event(&isp->asd, eof_event.event.exp_id); + dev_dbg_ratelimited(isp->dev, "ISYS event: EOF exp_id %d\n", + eof_event.event.exp_id); } irq_infos &= ~IA_CSS_IRQ_INFO_ISYS_EVENTS_READY; @@ -742,19 +678,6 @@ static void atomisp_recover_params_queue(struct atomisp_video_pipe *pipe) atomisp_handle_parameter_and_buffer(pipe); } -enum atomisp_metadata_type -atomisp_get_metadata_type(struct atomisp_sub_device *asd, - enum ia_css_pipe_id pipe_id) -{ - if (!asd->continuous_mode->val) - return ATOMISP_MAIN_METADATA; - - if (pipe_id == IA_CSS_PIPE_ID_CAPTURE) /* online capture pipe */ - return ATOMISP_SEC_METADATA; - else - return ATOMISP_MAIN_METADATA; -} - void atomisp_buf_done(struct atomisp_sub_device *asd, int error, enum ia_css_buffer_type buf_type, enum ia_css_pipe_id css_pipe_id, @@ -826,7 +749,7 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error, if (error) break; - md_type = atomisp_get_metadata_type(asd, css_pipe_id); + md_type = ATOMISP_MAIN_METADATA; list_for_each_entry_safe(md_iter, _md_buf_tmp, &asd->metadata_in_css[md_type], list) { if (md_iter->metadata == @@ -883,15 +806,6 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error, pipe = vb_to_pipe(&frame->vb.vb2_buf); - /* FIXME: - * YUVPP doesn't set postview exp_id correctlly in SDV mode. - * This is a WORKAROUND to set exp_id. see HSDES-1503911606. - */ - if (IS_BYT && buf_type == IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME && - asd->continuous_mode->val && ATOMISP_USE_YUVPP(asd)) - frame->exp_id = (asd->postview_exp_id++) % - (ATOMISP_MAX_EXP_ID + 1); - dev_dbg(isp->dev, "%s: vf frame with exp_id %d is ready\n", __func__, frame->exp_id); if (asd->params.flash_state == ATOMISP_FLASH_ONGOING) { @@ -908,18 +822,6 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error, __func__); } pipe->frame_config_id[frame->vb.vb2_buf.index] = frame->isp_config_id; - if (css_pipe_id == IA_CSS_PIPE_ID_CAPTURE && - asd->pending_capture_request > 0) { - err = atomisp_css_offline_capture_configure(asd, - asd->params.offline_parm.num_captures, - asd->params.offline_parm.skip_frames, - asd->params.offline_parm.offset); - - asd->pending_capture_request--; - - dev_dbg(isp->dev, "Trigger capture again for new buffer. err=%d\n", - err); - } break; case IA_CSS_BUFFER_TYPE_OUTPUT_FRAME: case IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME: @@ -934,15 +836,6 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error, pipe = vb_to_pipe(&frame->vb.vb2_buf); - /* FIXME: - * YUVPP doesn't set preview exp_id correctlly in ZSL mode. - * This is a WORKAROUND to set exp_id. see HSDES-1503911606. - */ - if (IS_BYT && buf_type == IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME && - asd->continuous_mode->val && ATOMISP_USE_YUVPP(asd)) - frame->exp_id = (asd->preview_exp_id++) % - (ATOMISP_MAX_EXP_ID + 1); - dev_dbg(isp->dev, "%s: main frame with exp_id %d is ready\n", __func__, frame->exp_id); @@ -993,35 +886,6 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error, asd->params.last_frame_status = asd->frame_status[i]; - if (asd->continuous_mode->val) { - if (css_pipe_id == IA_CSS_PIPE_ID_PREVIEW || - css_pipe_id == IA_CSS_PIPE_ID_VIDEO) { - asd->latest_preview_exp_id = frame->exp_id; - } else if (css_pipe_id == - IA_CSS_PIPE_ID_CAPTURE) { - if (asd->run_mode->val == - ATOMISP_RUN_MODE_VIDEO) - dev_dbg(isp->dev, "SDV capture raw buffer id: %u\n", - frame->exp_id); - else - dev_dbg(isp->dev, "ZSL capture raw buffer id: %u\n", - frame->exp_id); - } - } - /* - * Only after enabled the raw buffer lock - * and in continuous mode. - * in preview/video pipe, each buffer will - * be locked automatically, so record it here. - */ - if (((css_pipe_id == IA_CSS_PIPE_ID_PREVIEW) || - (css_pipe_id == IA_CSS_PIPE_ID_VIDEO)) && - asd->enable_raw_buffer_lock->val && - asd->continuous_mode->val) { - atomisp_set_raw_buffer_bitmap(asd, frame->exp_id); - WARN_ON(frame->exp_id > ATOMISP_MAX_EXP_ID); - } - if (asd->params.css_update_params_needed) { atomisp_apply_css_parameters(asd, &asd->params.css_param); @@ -1080,43 +944,13 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error, atomisp_qbuffers_to_css(asd); } -void atomisp_delayed_init_work(struct work_struct *work) -{ - struct atomisp_sub_device *asd = container_of(work, - struct atomisp_sub_device, - delayed_init_work); - /* - * to SOC camera, use yuvpp pipe and no support continuous mode. - */ - if (!ATOMISP_USE_YUVPP(asd)) { - struct v4l2_event event = {0}; - struct ia_css_stream *stream; - - stream = asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream; - - - if (ia_css_alloc_continuous_frame_remain(stream)) - return; - - ia_css_update_continuous_frames(stream); - - event.type = V4L2_EVENT_ATOMISP_RAW_BUFFERS_ALLOC_DONE; - v4l2_event_queue(asd->subdev.devnode, &event); - } - - /* signal streamon after delayed init is done */ - asd->delayed_init = ATOMISP_DELAYED_INIT_DONE; - complete(&asd->init_done); -} - static void __atomisp_css_recover(struct atomisp_device *isp, bool isp_timeout) { struct pci_dev *pdev = to_pci_dev(isp->dev); enum ia_css_pipe_id css_pipe_id; - bool stream_restart[MAX_STREAM_NUM] = {0}; - bool depth_mode = false; - int i, ret, depth_cnt = 0; + bool stream_restart = false; unsigned long flags; + int ret; lockdep_assert_held(&isp->mutex); @@ -1125,52 +959,37 @@ static void __atomisp_css_recover(struct atomisp_device *isp, bool isp_timeout) atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, false); - BUG_ON(isp->num_of_streams > MAX_STREAM_NUM); - - for (i = 0; i < isp->num_of_streams; i++) { - struct atomisp_sub_device *asd = &isp->asd[i]; - - if (asd->streaming != ATOMISP_DEVICE_STREAMING_ENABLED && - !asd->stream_prepared) - continue; - - depth_cnt++; - - if (asd->delayed_init == ATOMISP_DELAYED_INIT_QUEUED) - cancel_work_sync(&asd->delayed_init_work); - - complete(&asd->init_done); - asd->delayed_init = ATOMISP_DELAYED_INIT_NOT_QUEUED; - - stream_restart[asd->index] = true; + if (isp->asd.streaming == ATOMISP_DEVICE_STREAMING_ENABLED || + isp->asd.stream_prepared) { + stream_restart = true; spin_lock_irqsave(&isp->lock, flags); - asd->streaming = ATOMISP_DEVICE_STREAMING_STOPPING; + isp->asd.streaming = ATOMISP_DEVICE_STREAMING_STOPPING; spin_unlock_irqrestore(&isp->lock, flags); /* stream off sensor */ ret = v4l2_subdev_call( - isp->inputs[asd->input_curr]. + isp->inputs[isp->asd.input_curr]. camera, video, s_stream, 0); if (ret) dev_warn(isp->dev, "can't stop streaming on sensor!\n"); - atomisp_clear_css_buffer_counters(asd); + atomisp_clear_css_buffer_counters(&isp->asd); - css_pipe_id = atomisp_get_css_pipe_id(asd); - atomisp_css_stop(asd, css_pipe_id, true); + css_pipe_id = atomisp_get_css_pipe_id(&isp->asd); + atomisp_css_stop(&isp->asd, css_pipe_id, true); spin_lock_irqsave(&isp->lock, flags); - asd->streaming = ATOMISP_DEVICE_STREAMING_DISABLED; + isp->asd.streaming = ATOMISP_DEVICE_STREAMING_DISABLED; spin_unlock_irqrestore(&isp->lock, flags); - asd->preview_exp_id = 1; - asd->postview_exp_id = 1; + isp->asd.preview_exp_id = 1; + isp->asd.postview_exp_id = 1; /* notify HAL the CSS reset */ dev_dbg(isp->dev, - "send reset event to %s\n", asd->subdev.devnode->name); - atomisp_reset_event(asd); + "send reset event to %s\n", isp->asd.subdev.devnode->name); + atomisp_reset_event(&isp->asd); } /* clear irq */ @@ -1186,34 +1005,20 @@ static void __atomisp_css_recover(struct atomisp_device *isp, bool isp_timeout) atomisp_reset(isp); isp->isp_timeout = false; - if (!isp_timeout) { - for (i = 0; i < isp->num_of_streams; i++) { - if (isp->asd[i].depth_mode->val) - return; - } - } - - for (i = 0; i < isp->num_of_streams; i++) { - struct atomisp_sub_device *asd = &isp->asd[i]; + if (stream_restart) { + atomisp_css_input_set_mode(&isp->asd, IA_CSS_INPUT_MODE_BUFFERED_SENSOR); - if (!stream_restart[i]) - continue; - - if (isp->inputs[asd->input_curr].type != FILE_INPUT) - atomisp_css_input_set_mode(asd, - IA_CSS_INPUT_MODE_BUFFERED_SENSOR); - - css_pipe_id = atomisp_get_css_pipe_id(asd); - if (atomisp_css_start(asd, css_pipe_id, true)) { + css_pipe_id = atomisp_get_css_pipe_id(&isp->asd); + if (atomisp_css_start(&isp->asd, css_pipe_id, true)) { dev_warn(isp->dev, "start SP failed, so do not set streaming to be enable!\n"); } else { spin_lock_irqsave(&isp->lock, flags); - asd->streaming = ATOMISP_DEVICE_STREAMING_ENABLED; + isp->asd.streaming = ATOMISP_DEVICE_STREAMING_ENABLED; spin_unlock_irqrestore(&isp->lock, flags); } - atomisp_csi2_configure(asd); + atomisp_csi2_configure(&isp->asd); } atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, @@ -1222,51 +1027,25 @@ static void __atomisp_css_recover(struct atomisp_device *isp, bool isp_timeout) if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_AUTO, true) < 0) dev_dbg(isp->dev, "DFS auto failed while recovering!\n"); - for (i = 0; i < isp->num_of_streams; i++) { - struct atomisp_sub_device *asd; - - asd = &isp->asd[i]; - - if (!stream_restart[i]) - continue; - - if (asd->continuous_mode->val && - asd->delayed_init == ATOMISP_DELAYED_INIT_NOT_QUEUED) { - reinit_completion(&asd->init_done); - asd->delayed_init = ATOMISP_DELAYED_INIT_QUEUED; - queue_work(asd->delayed_init_workq, - &asd->delayed_init_work); - } + if (stream_restart) { /* * dequeueing buffers is not needed. CSS will recycle * buffers that it has. */ - atomisp_flush_bufs_and_wakeup(asd); + atomisp_flush_bufs_and_wakeup(&isp->asd); /* Requeue unprocessed per-frame parameters. */ - atomisp_recover_params_queue(&asd->video_out_capture); - atomisp_recover_params_queue(&asd->video_out_preview); - atomisp_recover_params_queue(&asd->video_out_video_capture); - - if ((asd->depth_mode->val) && - (depth_cnt == ATOMISP_DEPTH_SENSOR_STREAMON_COUNT)) { - depth_mode = true; - continue; - } + atomisp_recover_params_queue(&isp->asd.video_out_capture); + atomisp_recover_params_queue(&isp->asd.video_out_preview); + atomisp_recover_params_queue(&isp->asd.video_out_video_capture); ret = v4l2_subdev_call( - isp->inputs[asd->input_curr].camera, video, + isp->inputs[isp->asd.input_curr].camera, video, s_stream, 1); if (ret) dev_warn(isp->dev, "can't start streaming on sensor!\n"); } - - if (depth_mode) { - if (atomisp_stream_on_master_slave_sensor(isp, true)) - dev_warn(isp->dev, - "master slave sensor stream on failed!\n"); - } } void atomisp_assert_recovery_work(struct work_struct *work) @@ -1321,10 +1100,6 @@ irqreturn_t atomisp_isr_thread(int irq, void *isp_ptr) { struct atomisp_device *isp = isp_ptr; unsigned long flags; - bool frame_done_found[MAX_STREAM_NUM] = {0}; - bool css_pipe_done[MAX_STREAM_NUM] = {0}; - unsigned int i; - struct atomisp_sub_device *asd; dev_dbg(isp->dev, ">%s\n", __func__); @@ -1363,15 +1138,11 @@ irqreturn_t atomisp_isr_thread(int irq, void *isp_ptr) * time, instead, dequue one and process one, then another */ mutex_lock(&isp->mutex); - if (atomisp_css_isr_thread(isp, frame_done_found, css_pipe_done)) + if (atomisp_css_isr_thread(isp)) goto out; - for (i = 0; i < isp->num_of_streams; i++) { - asd = &isp->asd[i]; - if (asd->streaming != ATOMISP_DEVICE_STREAMING_ENABLED) - continue; - atomisp_setup_flash(asd); - } + if (isp->asd.streaming == ATOMISP_DEVICE_STREAMING_ENABLED) + atomisp_setup_flash(&isp->asd); out: mutex_unlock(&isp->mutex); dev_dbg(isp->dev, "<%s\n", __func__); @@ -1779,11 +1550,6 @@ int atomisp_formats(struct atomisp_sub_device *asd, int flag, void atomisp_free_internal_buffers(struct atomisp_sub_device *asd) { atomisp_free_css_parameters(&asd->params.css_param); - - if (asd->raw_output_frame) { - ia_css_frame_free(asd->raw_output_frame); - asd->raw_output_frame = NULL; - } } static void atomisp_update_grid_info(struct atomisp_sub_device *asd, @@ -2023,8 +1789,6 @@ int atomisp_get_dvs2_bq_resolutions(struct atomisp_sub_device *asd, struct atomisp_dvs2_bq_resolutions *bq_res) { struct ia_css_pipe_config *pipe_cfg = NULL; - struct ia_css_stream_config *stream_cfg = NULL; - struct ia_css_stream_input_config *input_config = NULL; struct ia_css_stream *stream = asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream; @@ -2035,9 +1799,6 @@ int atomisp_get_dvs2_bq_resolutions(struct atomisp_sub_device *asd, pipe_cfg = &asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL] .pipe_configs[IA_CSS_PIPE_ID_VIDEO]; - stream_cfg = &asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL] - .stream_config; - input_config = &stream_cfg->input_config; if (!bq_res) return -EINVAL; @@ -2049,132 +1810,27 @@ int atomisp_get_dvs2_bq_resolutions(struct atomisp_sub_device *asd, bq_res->envelope_bq.width_bq = 0; bq_res->envelope_bq.height_bq = 0; /* the GDC input resolution */ - if (!asd->continuous_mode->val) { - bq_res->source_bq.width_bq = bq_res->output_bq.width_bq + - pipe_cfg->dvs_envelope.width / 2; - bq_res->source_bq.height_bq = bq_res->output_bq.height_bq + - pipe_cfg->dvs_envelope.height / 2; - /* - * Bad pixels caused by spatial filter processing - * ISP filter resolution should be given by CSS/FW, but for now - * there is not such API to query, and it is fixed value, so - * hardcoded here. - */ - bq_res->ispfilter_bq.width_bq = 12 / 2; - bq_res->ispfilter_bq.height_bq = 12 / 2; - /* spatial filter shift, always 4 pixels */ - bq_res->gdc_shift_bq.width_bq = 4 / 2; - bq_res->gdc_shift_bq.height_bq = 4 / 2; - - if (asd->params.video_dis_en) { - bq_res->envelope_bq.width_bq = pipe_cfg->dvs_envelope.width - / 2 - bq_res->ispfilter_bq.width_bq; - bq_res->envelope_bq.height_bq = pipe_cfg->dvs_envelope.height - / 2 - bq_res->ispfilter_bq.height_bq; - } - } else { - unsigned int w_padding; - unsigned int gdc_effective_input = 0; - - /* For GDC: - * gdc_effective_input = effective_input + envelope - * - * From the comment and formula in BZ1786, - * we see the source_bq should be: - * effective_input / bayer_ds_ratio - */ - bq_res->source_bq.width_bq = - (input_config->effective_res.width * - pipe_cfg->bayer_ds_out_res.width / - input_config->effective_res.width + 1) / 2; - bq_res->source_bq.height_bq = - (input_config->effective_res.height * - pipe_cfg->bayer_ds_out_res.height / - input_config->effective_res.height + 1) / 2; - - if (!asd->params.video_dis_en) { - /* - * We adjust the ispfilter_bq to: - * ispfilter_bq = 128/BDS - * we still need firmware team to provide an offical - * formula for SDV. - */ - bq_res->ispfilter_bq.width_bq = 128 * - pipe_cfg->bayer_ds_out_res.width / - input_config->effective_res.width / 2; - bq_res->ispfilter_bq.height_bq = 128 * - pipe_cfg->bayer_ds_out_res.width / - input_config->effective_res.width / 2; - - if (IS_HWREVISION(asd->isp, ATOMISP_HW_REVISION_ISP2401)) { - /* No additional left padding for ISYS2401 */ - bq_res->gdc_shift_bq.width_bq = 4 / 2; - bq_res->gdc_shift_bq.height_bq = 4 / 2; - } else { - /* - * For the w_padding and gdc_shift_bq cacluation - * Please see the BZ 1786 and 4358 for more info. - * Just test that this formula can work now, - * but we still have no offical formula. - * - * w_padding = ceiling(gdc_effective_input - * /128, 1) * 128 - effective_width - * gdc_shift_bq = w_padding/BDS/2 + ispfilter_bq/2 - */ - gdc_effective_input = - input_config->effective_res.width + - pipe_cfg->dvs_envelope.width; - w_padding = roundup(gdc_effective_input, 128) - - input_config->effective_res.width; - w_padding = w_padding * - pipe_cfg->bayer_ds_out_res.width / - input_config->effective_res.width + 1; - w_padding = roundup(w_padding / 2, 1); - - bq_res->gdc_shift_bq.width_bq = bq_res->ispfilter_bq.width_bq / 2 - + w_padding; - bq_res->gdc_shift_bq.height_bq = 4 / 2; - } - } else { - unsigned int dvs_w, dvs_h, dvs_w_max, dvs_h_max; - - bq_res->ispfilter_bq.width_bq = 8 / 2; - bq_res->ispfilter_bq.height_bq = 8 / 2; - - if (IS_HWREVISION(asd->isp, ATOMISP_HW_REVISION_ISP2401)) { - /* No additional left padding for ISYS2401 */ - bq_res->gdc_shift_bq.width_bq = 4 / 2; - bq_res->gdc_shift_bq.height_bq = 4 / 2; - } else { - w_padding = - roundup(input_config->effective_res.width, 128) - - input_config->effective_res.width; - if (w_padding < 12) - w_padding = 12; - bq_res->gdc_shift_bq.width_bq = 4 / 2 + - ((w_padding - 12) * - pipe_cfg->bayer_ds_out_res.width / - input_config->effective_res.width + 1) / 2; - bq_res->gdc_shift_bq.height_bq = 4 / 2; - } + bq_res->source_bq.width_bq = bq_res->output_bq.width_bq + + pipe_cfg->dvs_envelope.width / 2; + bq_res->source_bq.height_bq = bq_res->output_bq.height_bq + + pipe_cfg->dvs_envelope.height / 2; + /* + * Bad pixels caused by spatial filter processing + * ISP filter resolution should be given by CSS/FW, but for now + * there is not such API to query, and it is fixed value, so + * hardcoded here. + */ + bq_res->ispfilter_bq.width_bq = 12 / 2; + bq_res->ispfilter_bq.height_bq = 12 / 2; + /* spatial filter shift, always 4 pixels */ + bq_res->gdc_shift_bq.width_bq = 4 / 2; + bq_res->gdc_shift_bq.height_bq = 4 / 2; - dvs_w = pipe_cfg->bayer_ds_out_res.width - - pipe_cfg->output_info[0].res.width; - dvs_h = pipe_cfg->bayer_ds_out_res.height - - pipe_cfg->output_info[0].res.height; - dvs_w_max = rounddown( - pipe_cfg->output_info[0].res.width / 5, - ATOM_ISP_STEP_WIDTH); - dvs_h_max = rounddown( - pipe_cfg->output_info[0].res.height / 5, - ATOM_ISP_STEP_HEIGHT); - bq_res->envelope_bq.width_bq = - min((dvs_w / 2), (dvs_w_max / 2)) - - bq_res->ispfilter_bq.width_bq; - bq_res->envelope_bq.height_bq = - min((dvs_h / 2), (dvs_h_max / 2)) - - bq_res->ispfilter_bq.height_bq; - } + if (asd->params.video_dis_en) { + bq_res->envelope_bq.width_bq = pipe_cfg->dvs_envelope.width / 2 - + bq_res->ispfilter_bq.width_bq; + bq_res->envelope_bq.height_bq = pipe_cfg->dvs_envelope.height / 2 - + bq_res->ispfilter_bq.height_bq; } dev_dbg(asd->isp->dev, @@ -3640,10 +3296,8 @@ int atomisp_set_parameters(struct video_device *vdev, return -EINVAL; } - dev_dbg(asd->isp->dev, - "%s: set parameter(per_frame_setting %d) for asd%d with isp_config_id %d of %s\n", - __func__, arg->per_frame_setting, asd->index, - arg->isp_config_id, vdev->name); + dev_dbg(asd->isp->dev, "set parameter(per_frame_setting %d) isp_config_id %d of %s\n", + arg->per_frame_setting, arg->isp_config_id, vdev->name); if (IS_ISP2401) { if (atomisp_is_vf_pipe(pipe) && arg->per_frame_setting) { @@ -3751,28 +3405,8 @@ int atomisp_param(struct atomisp_sub_device *asd, int flag, } /* update dvs envelop info */ - if (!asd->continuous_mode->val) { - config->dvs_envelop.width = vp_cfg->dvs_envelope.width; - config->dvs_envelop.height = - vp_cfg->dvs_envelope.height; - } else { - unsigned int dvs_w, dvs_h, dvs_w_max, dvs_h_max; - - dvs_w = vp_cfg->bayer_ds_out_res.width - - vp_cfg->output_info[0].res.width; - dvs_h = vp_cfg->bayer_ds_out_res.height - - vp_cfg->output_info[0].res.height; - dvs_w_max = rounddown( - vp_cfg->output_info[0].res.width / 5, - ATOM_ISP_STEP_WIDTH); - dvs_h_max = rounddown( - vp_cfg->output_info[0].res.height / 5, - ATOM_ISP_STEP_HEIGHT); - - config->dvs_envelop.width = min(dvs_w, dvs_w_max); - config->dvs_envelop.height = min(dvs_h, dvs_h_max); - } - + config->dvs_envelop.width = vp_cfg->dvs_envelope.width; + config->dvs_envelop.height = vp_cfg->dvs_envelope.height; return 0; } @@ -4254,16 +3888,12 @@ int atomisp_try_fmt(struct video_device *vdev, struct v4l2_pix_format *f, struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; struct v4l2_subdev_pad_config pad_cfg; struct v4l2_subdev_state pad_state = { - .pads = &pad_cfg - }; + .pads = &pad_cfg, + }; struct v4l2_subdev_format format = { .which = V4L2_SUBDEV_FORMAT_TRY, }; - - struct v4l2_mbus_framefmt *snr_mbus_fmt = &format.format; const struct atomisp_format_bridge *fmt; - struct atomisp_input_stream_info *stream_info = - (struct atomisp_input_stream_info *)snr_mbus_fmt->reserved; int ret; if (!asd) { @@ -4284,14 +3914,15 @@ int atomisp_try_fmt(struct video_device *vdev, struct v4l2_pix_format *f, if (f->width <= 0 || f->height <= 0) return -EINVAL; - snr_mbus_fmt->code = fmt->mbus_code; - snr_mbus_fmt->width = f->width; - snr_mbus_fmt->height = f->height; + format.format.code = fmt->mbus_code; + format.format.width = f->width; + format.format.height = f->height; - __atomisp_init_stream_info(ATOMISP_INPUT_STREAM_GENERAL, stream_info); + __atomisp_init_stream_info(ATOMISP_INPUT_STREAM_GENERAL, + (struct atomisp_input_stream_info *)format.format.reserved); dev_dbg(isp->dev, "try_mbus_fmt: asking for %ux%u\n", - snr_mbus_fmt->width, snr_mbus_fmt->height); + format.format.width, format.format.height); ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, pad, set_fmt, &pad_state, &format); @@ -4299,12 +3930,12 @@ int atomisp_try_fmt(struct video_device *vdev, struct v4l2_pix_format *f, return ret; dev_dbg(isp->dev, "try_mbus_fmt: got %ux%u\n", - snr_mbus_fmt->width, snr_mbus_fmt->height); + format.format.width, format.format.height); - fmt = atomisp_get_format_bridge_from_mbus(snr_mbus_fmt->code); + fmt = atomisp_get_format_bridge_from_mbus(format.format.code); if (!fmt) { dev_err(isp->dev, "unknown sensor format 0x%8.8x\n", - snr_mbus_fmt->code); + format.format.code); return -EINVAL; } @@ -4318,15 +3949,15 @@ int atomisp_try_fmt(struct video_device *vdev, struct v4l2_pix_format *f, */ if (f->pixelformat == V4L2_PIX_FMT_JPEG || f->pixelformat == V4L2_PIX_FMT_CUSTOM_M10MO_RAW) { - f->width = snr_mbus_fmt->width; - f->height = snr_mbus_fmt->height; + f->width = format.format.width; + f->height = format.format.height; return 0; } - if (!res_overflow || (snr_mbus_fmt->width < f->width && - snr_mbus_fmt->height < f->height)) { - f->width = snr_mbus_fmt->width; - f->height = snr_mbus_fmt->height; + if (!res_overflow || (format.format.width < f->width && + format.format.height < f->height)) { + f->width = format.format.width; + f->height = format.format.height; /* Set the flag when resolution requested is * beyond the max value supported by sensor */ @@ -4439,43 +4070,6 @@ static inline int atomisp_set_sensor_mipi_to_isp( return 0; } -static int __enable_continuous_mode(struct atomisp_sub_device *asd, - bool enable) -{ - struct atomisp_device *isp = asd->isp; - - dev_dbg(isp->dev, - "continuous mode %d, raw buffers %d, stop preview %d\n", - enable, asd->continuous_raw_buffer_size->val, - !asd->continuous_viewfinder->val); - - if (!IS_ISP2401) - atomisp_css_capture_set_mode(asd, IA_CSS_CAPTURE_MODE_PRIMARY); - else - atomisp_update_capture_mode(asd); - - /* in case of ANR, force capture pipe to offline mode */ - atomisp_css_capture_enable_online(asd, ATOMISP_INPUT_STREAM_GENERAL, - asd->params.low_light ? false : !enable); - atomisp_css_preview_enable_online(asd, ATOMISP_INPUT_STREAM_GENERAL, - !enable); - atomisp_css_enable_continuous(asd, enable); - atomisp_css_enable_cvf(asd, asd->continuous_viewfinder->val); - - atomisp_css_continuous_set_num_raw_frames(asd, - asd->continuous_raw_buffer_size->val); - - if (!enable) { - atomisp_css_enable_raw_binning(asd, false); - atomisp_css_input_set_two_pixels_per_clock(asd, false); - } - - if (isp->inputs[asd->input_curr].type != FILE_INPUT) - atomisp_css_input_set_mode(asd, IA_CSS_INPUT_MODE_BUFFERED_SENSOR); - - return atomisp_update_run_mode(asd); -} - static int configure_pp_input_nop(struct atomisp_sub_device *asd, unsigned int width, unsigned int height) { @@ -4517,17 +4111,6 @@ static int css_input_resolution_changed(struct atomisp_sub_device *asd, else atomisp_css_input_set_two_pixels_per_clock(asd, true); - if (asd->continuous_mode->val) { - /* Note for all checks: ffmt includes pad_w+pad_h */ - if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO || - (ffmt->width >= 2048 || ffmt->height >= 1536)) { - /* - * For preview pipe, enable only if resolution - * is >= 3M for ISP2400. - */ - atomisp_css_enable_raw_binning(asd, true); - } - } /* * If sensor input changed, which means metadata resolution changed * together. Release all metadata buffers here to let it re-allocated @@ -4551,7 +4134,6 @@ static int css_input_resolution_changed(struct atomisp_sub_device *asd, static int atomisp_set_fmt_to_isp(struct video_device *vdev, struct ia_css_frame_info *output_info, - struct ia_css_frame_info *raw_output_info, struct v4l2_pix_format *pix, unsigned int source_pad) { @@ -4592,8 +4174,7 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev, if (!format) return -EINVAL; - if (isp->inputs[asd->input_curr].type != TEST_PATTERN && - isp->inputs[asd->input_curr].type != FILE_INPUT) { + if (isp->inputs[asd->input_curr].type != TEST_PATTERN) { mipi_info = atomisp_to_sensor_mipi_info( isp->inputs[asd->input_curr].camera); if (!mipi_info) { @@ -4622,8 +4203,7 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev, * Configure viewfinder also when vfpp is disabled: the * CSS still requires viewfinder configuration. */ - if (asd->fmt_auto->val || - asd->vfpp->val != ATOMISP_VFPP_ENABLE) { + { struct v4l2_rect vf_size = {0}; struct v4l2_mbus_framefmt vf_ffmt = {0}; @@ -4670,12 +4250,6 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev, } } - if (asd->continuous_mode->val) { - ret = __enable_continuous_mode(asd, true); - if (ret) - return -EINVAL; - } - atomisp_css_input_set_mode(asd, IA_CSS_INPUT_MODE_BUFFERED_SENSOR); for (i = 0; i < IA_CSS_PIPE_ID_NUM; i++) @@ -4691,49 +4265,15 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev, get_frame_info = atomisp_css_video_get_output_frame_info; pipe_id = IA_CSS_PIPE_ID_VIDEO; } else if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) { - if (!asd->continuous_mode->val) { - configure_output = atomisp_css_video_configure_output; - get_frame_info = - atomisp_css_video_get_output_frame_info; - pipe_id = IA_CSS_PIPE_ID_VIDEO; - } else { - if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW || - source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VIDEO) { - configure_output = - atomisp_css_video_configure_output; - get_frame_info = - atomisp_css_video_get_output_frame_info; - configure_pp_input = - atomisp_css_video_configure_pp_input; - pipe_id = IA_CSS_PIPE_ID_VIDEO; - } else { - configure_output = - atomisp_css_capture_configure_output; - get_frame_info = - atomisp_css_capture_get_output_frame_info; - configure_pp_input = - atomisp_css_capture_configure_pp_input; - pipe_id = IA_CSS_PIPE_ID_CAPTURE; - - atomisp_update_capture_mode(asd); - atomisp_css_capture_enable_online(asd, - ATOMISP_INPUT_STREAM_GENERAL, - false); - } - } + configure_output = atomisp_css_video_configure_output; + get_frame_info = atomisp_css_video_get_output_frame_info; + pipe_id = IA_CSS_PIPE_ID_VIDEO; } else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW) { configure_output = atomisp_css_preview_configure_output; get_frame_info = atomisp_css_preview_get_output_frame_info; configure_pp_input = atomisp_css_preview_configure_pp_input; pipe_id = IA_CSS_PIPE_ID_PREVIEW; } else { - /* CSS doesn't support low light mode on SOC cameras, so disable - * it. FIXME: if this is done elsewhere, it gives corrupted - * colors into thumbnail image. - */ - if (isp->inputs[asd->input_curr].type == SOC_CAMERA) - asd->params.low_light = false; - if (format->sh_fmt == IA_CSS_FRAME_FORMAT_RAW) { atomisp_css_capture_set_mode(asd, IA_CSS_CAPTURE_MODE_RAW); atomisp_css_enable_dz(asd, false); @@ -4741,38 +4281,22 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev, atomisp_update_capture_mode(asd); } - if (!asd->continuous_mode->val) - /* in case of ANR, force capture pipe to offline mode */ - atomisp_css_capture_enable_online(asd, ATOMISP_INPUT_STREAM_GENERAL, - asd->params.low_light ? - false : asd->params.online_process); + /* in case of ANR, force capture pipe to offline mode */ + atomisp_css_capture_enable_online(asd, ATOMISP_INPUT_STREAM_GENERAL, + !asd->params.low_light); configure_output = atomisp_css_capture_configure_output; get_frame_info = atomisp_css_capture_get_output_frame_info; configure_pp_input = atomisp_css_capture_configure_pp_input; pipe_id = IA_CSS_PIPE_ID_CAPTURE; - if (!asd->params.online_process && - !asd->continuous_mode->val) { - ret = atomisp_css_capture_get_output_raw_frame_info(asd, - raw_output_info); - if (ret) - return ret; - } - if (!asd->continuous_mode->val && asd->run_mode->val - != ATOMISP_RUN_MODE_STILL_CAPTURE) { + if (asd->run_mode->val != ATOMISP_RUN_MODE_STILL_CAPTURE) { dev_err(isp->dev, "Need to set the running mode first\n"); asd->run_mode->val = ATOMISP_RUN_MODE_STILL_CAPTURE; } } - /* - * to SOC camera, use yuvpp pipe. - */ - if (ATOMISP_USE_YUVPP(asd)) - pipe_id = IA_CSS_PIPE_ID_YUVPP; - if (asd->copy_mode) ret = atomisp_css_copy_configure_output(asd, ATOMISP_INPUT_STREAM_GENERAL, pix->width, pix->height, @@ -4810,16 +4334,6 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev, } atomisp_update_grid_info(asd, pipe_id, source_pad); - - /* Free the raw_dump buffer first */ - ia_css_frame_free(asd->raw_output_frame); - asd->raw_output_frame = NULL; - - if (!asd->continuous_mode->val && !asd->params.online_process && - ia_css_frame_allocate_from_info(&asd->raw_output_frame, - raw_output_info)) - return -ENOMEM; - return 0; } @@ -4827,12 +4341,6 @@ static void atomisp_get_dis_envelop(struct atomisp_sub_device *asd, unsigned int width, unsigned int height, unsigned int *dvs_env_w, unsigned int *dvs_env_h) { - struct atomisp_device *isp = asd->isp; - - /* if subdev type is SOC camera,we do not need to set DVS */ - if (isp->inputs[asd->input_curr].type == SOC_CAMERA) - asd->params.video_dis_en = false; - if (asd->params.video_dis_en && asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) { /* envelope is 20% of the output resolution */ @@ -4849,7 +4357,7 @@ static void atomisp_get_dis_envelop(struct atomisp_sub_device *asd, } static void atomisp_check_copy_mode(struct atomisp_sub_device *asd, - int source_pad, struct v4l2_pix_format *f) + int source_pad, const struct v4l2_pix_format *f) { struct v4l2_mbus_framefmt *sink, *src; @@ -4872,8 +4380,7 @@ static void atomisp_check_copy_mode(struct atomisp_sub_device *asd, dev_dbg(asd->isp->dev, "copy_mode: %d\n", asd->copy_mode); } -static int atomisp_set_fmt_to_snr(struct video_device *vdev, - struct v4l2_pix_format *f, unsigned int pixelformat, +static int atomisp_set_fmt_to_snr(struct video_device *vdev, const struct v4l2_pix_format *f, unsigned int padding_w, unsigned int padding_h, unsigned int dvs_env_w, unsigned int dvs_env_h) { @@ -4882,8 +4389,8 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, const struct atomisp_format_bridge *format; struct v4l2_subdev_pad_config pad_cfg; struct v4l2_subdev_state pad_state = { - .pads = &pad_cfg - }; + .pads = &pad_cfg, + }; struct v4l2_subdev_format vformat = { .which = V4L2_SUBDEV_FORMAT_TRY, }; @@ -4906,7 +4413,7 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, v4l2_fh_init(&fh.vfh, vdev); - format = atomisp_get_format_bridge(pixelformat); + format = atomisp_get_format_bridge(f->pixelformat); if (!format) return -EINVAL; @@ -4981,13 +4488,9 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f) struct atomisp_sub_device *asd = pipe->asd; const struct atomisp_format_bridge *format_bridge; const struct atomisp_format_bridge *snr_format_bridge; - struct ia_css_frame_info output_info, raw_output_info; - struct v4l2_pix_format snr_fmt; - struct v4l2_pix_format backup_fmt, s_fmt; + struct ia_css_frame_info output_info; unsigned int dvs_env_w = 0, dvs_env_h = 0; unsigned int padding_w = pad_w, padding_h = pad_h; - bool res_overflow = false, crop_needs_override = false; - struct v4l2_mbus_framefmt *isp_sink_fmt; struct v4l2_mbus_framefmt isp_source_fmt = {0}; struct v4l2_subdev_format vformat = { .which = V4L2_SUBDEV_FORMAT_ACTIVE, @@ -5005,9 +4508,8 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f) return -EINVAL; dev_dbg(isp->dev, - "setting resolution %ux%u on pad %u for asd%d, bytesperline %u\n", - f->fmt.pix.width, f->fmt.pix.height, source_pad, - asd->index, f->fmt.pix.bytesperline); + "setting resolution %ux%u on pad %u bytesperline %u\n", + f->fmt.pix.width, f->fmt.pix.height, source_pad, f->fmt.pix.bytesperline); v4l2_fh_init(&fh.vfh, vdev); @@ -5042,105 +4544,7 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f) f->fmt.pix.width = vformat.format.width - padding_w; f->fmt.pix.height = vformat.format.height - padding_h; - snr_fmt = f->fmt.pix; - backup_fmt = snr_fmt; - - /**********************************************************************/ - - if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VF || - (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW - && asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO)) { - if (asd->fmt_auto->val) { - struct v4l2_rect *capture_comp; - struct v4l2_rect r = {0}; - - r.width = f->fmt.pix.width; - r.height = f->fmt.pix.height; - - if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW) - capture_comp = atomisp_subdev_get_rect( - &asd->subdev, NULL, - V4L2_SUBDEV_FORMAT_ACTIVE, - ATOMISP_SUBDEV_PAD_SOURCE_VIDEO, - V4L2_SEL_TGT_COMPOSE); - else - capture_comp = atomisp_subdev_get_rect( - &asd->subdev, NULL, - V4L2_SUBDEV_FORMAT_ACTIVE, - ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE, - V4L2_SEL_TGT_COMPOSE); - - if (capture_comp->width < r.width - || capture_comp->height < r.height) { - r.width = capture_comp->width; - r.height = capture_comp->height; - } - - atomisp_subdev_set_selection( - &asd->subdev, fh.state, - V4L2_SUBDEV_FORMAT_ACTIVE, source_pad, - V4L2_SEL_TGT_COMPOSE, 0, &r); - - f->fmt.pix.width = r.width; - f->fmt.pix.height = r.height; - } - - if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW) { - atomisp_css_video_configure_viewfinder(asd, - f->fmt.pix.width, f->fmt.pix.height, - format_bridge->planar ? f->fmt.pix.bytesperline - : f->fmt.pix.bytesperline * 8 - / format_bridge->depth, format_bridge->sh_fmt); - atomisp_css_video_get_viewfinder_frame_info(asd, - &output_info); - asd->copy_mode = false; - } else { - atomisp_css_capture_configure_viewfinder(asd, - f->fmt.pix.width, f->fmt.pix.height, - format_bridge->planar ? f->fmt.pix.bytesperline - : f->fmt.pix.bytesperline * 8 - / format_bridge->depth, format_bridge->sh_fmt); - atomisp_css_capture_get_viewfinder_frame_info(asd, - &output_info); - asd->copy_mode = false; - } - - goto done; - } - /* - * Check whether main resolution configured smaller - * than snapshot resolution. If so, force main resolution - * to be the same as snapshot resolution - */ - if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE) { - struct v4l2_rect *r; - - r = atomisp_subdev_get_rect( - &asd->subdev, NULL, - V4L2_SUBDEV_FORMAT_ACTIVE, - ATOMISP_SUBDEV_PAD_SOURCE_VF, V4L2_SEL_TGT_COMPOSE); - - if (r->width && r->height - && (r->width > f->fmt.pix.width - || r->height > f->fmt.pix.height)) - dev_warn(isp->dev, - "Main Resolution config smaller then Vf Resolution. Force to be equal with Vf Resolution."); - } - - /* Pipeline configuration done through subdevs. Bail out now. */ - if (!asd->fmt_auto->val) - goto set_fmt_to_isp; - - /* get sensor resolution and format */ - ret = atomisp_try_fmt(vdev, &snr_fmt, &res_overflow); - if (ret) { - dev_warn(isp->dev, "Try format failed with error %d\n", ret); - return ret; - } - f->fmt.pix.width = snr_fmt.width; - f->fmt.pix.height = snr_fmt.height; - - snr_format_bridge = atomisp_get_format_bridge(snr_fmt.pixelformat); + snr_format_bridge = atomisp_get_format_bridge_from_mbus(vformat.format.code); if (!snr_format_bridge) { dev_warn(isp->dev, "Can't find bridge format\n"); return -EINVAL; @@ -5151,10 +4555,6 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f) ATOMISP_SUBDEV_PAD_SINK)->code = snr_format_bridge->mbus_code; - isp_sink_fmt = atomisp_subdev_get_ffmt(&asd->subdev, NULL, - V4L2_SUBDEV_FORMAT_ACTIVE, - ATOMISP_SUBDEV_PAD_SINK); - isp_source_fmt.code = format_bridge->mbus_code; atomisp_subdev_set_ffmt(&asd->subdev, fh.state, V4L2_SUBDEV_FORMAT_ACTIVE, @@ -5165,80 +4565,22 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f) padding_h = 0; } - /* construct resolution supported by isp */ - if (res_overflow && !asd->continuous_mode->val) { - f->fmt.pix.width = rounddown( - clamp_t(u32, f->fmt.pix.width - padding_w, - ATOM_ISP_MIN_WIDTH, - ATOM_ISP_MAX_WIDTH), ATOM_ISP_STEP_WIDTH); - f->fmt.pix.height = rounddown( - clamp_t(u32, f->fmt.pix.height - padding_h, - ATOM_ISP_MIN_HEIGHT, - ATOM_ISP_MAX_HEIGHT), ATOM_ISP_STEP_HEIGHT); - } - atomisp_get_dis_envelop(asd, f->fmt.pix.width, f->fmt.pix.height, &dvs_env_w, &dvs_env_h); - if (asd->continuous_mode->val) { - struct v4l2_rect *r; + asd->capture_pad = source_pad; - r = atomisp_subdev_get_rect( - &asd->subdev, NULL, - V4L2_SUBDEV_FORMAT_ACTIVE, - ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE, - V4L2_SEL_TGT_COMPOSE); - /* - * The ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE should get resolutions - * properly set otherwise, it should not be the capture_pad. - */ - if (r->width && r->height) - asd->capture_pad = ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE; - else - asd->capture_pad = source_pad; - } else { - asd->capture_pad = source_pad; + ret = atomisp_set_fmt_to_snr(vdev, &f->fmt.pix, + padding_w, padding_h, dvs_env_w, dvs_env_h); + if (ret) { + dev_warn(isp->dev, + "Set format to sensor failed with %d\n", ret); + return -EINVAL; } - /* - * set format info to sensor - * In continuous mode, resolution is set only if it is higher than - * existing value. This because preview pipe will be configured after - * capture pipe and usually has lower resolution than capture pipe. - */ - if (!asd->continuous_mode->val || - isp_sink_fmt->width < (f->fmt.pix.width + padding_w + dvs_env_w) || - isp_sink_fmt->height < (f->fmt.pix.height + padding_h + - dvs_env_h)) { - /* - * For jpeg or custom raw format the sensor will return constant - * width and height. Because we already had quried try_mbus_fmt, - * f->fmt.pix.width and f->fmt.pix.height has been changed to - * this fixed width and height. So we cannot select the correct - * resolution with that information. So use the original width - * and height while set_mbus_fmt() so actual resolutions are - * being used in while set media bus format. - */ - s_fmt = f->fmt.pix; - if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_JPEG || - f->fmt.pix.pixelformat == V4L2_PIX_FMT_CUSTOM_M10MO_RAW) { - s_fmt.width = backup_fmt.width; - s_fmt.height = backup_fmt.height; - } - ret = atomisp_set_fmt_to_snr(vdev, &s_fmt, - f->fmt.pix.pixelformat, padding_w, - padding_h, dvs_env_w, dvs_env_h); - if (ret) { - dev_warn(isp->dev, - "Set format to sensor failed with %d\n", ret); - return -EINVAL; - } - atomisp_csi_lane_config(isp); - crop_needs_override = true; - } + atomisp_csi_lane_config(isp); - atomisp_check_copy_mode(asd, source_pad, &backup_fmt); - asd->yuvpp_mode = false; /* Reset variable */ + atomisp_check_copy_mode(asd, source_pad, &f->fmt.pix); isp_sink_crop = *atomisp_subdev_get_rect(&asd->subdev, NULL, V4L2_SUBDEV_FORMAT_ACTIVE, @@ -5250,27 +4592,10 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f) if (isp_sink_crop.width * 9 / 10 < f->fmt.pix.width || isp_sink_crop.height * 9 / 10 < f->fmt.pix.height || (atomisp_subdev_format_conversion(asd, source_pad) && - ((asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO && - !asd->continuous_mode->val) || + (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO || asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER))) { - /* for continuous mode, preview size might be smaller than - * still capture size. if preview size still needs crop, - * pick the larger one between crop size of preview and - * still capture. - */ - if (asd->continuous_mode->val - && source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW - && !crop_needs_override) { - isp_sink_crop.width = - max_t(unsigned int, f->fmt.pix.width, - isp_sink_crop.width); - isp_sink_crop.height = - max_t(unsigned int, f->fmt.pix.height, - isp_sink_crop.height); - } else { - isp_sink_crop.width = f->fmt.pix.width; - isp_sink_crop.height = f->fmt.pix.height; - } + isp_sink_crop.width = f->fmt.pix.width; + isp_sink_crop.height = f->fmt.pix.height; atomisp_subdev_set_selection(&asd->subdev, fh.state, V4L2_SUBDEV_FORMAT_ACTIVE, @@ -5314,45 +4639,40 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f) * which appears to be related by a hardware * performance limitation. It's unclear why this * particular code triggers the issue. */ - if (crop_needs_override) { - if (isp_sink_crop.width * main_compose.height > - isp_sink_crop.height * main_compose.width) { - sink_crop.height = isp_sink_crop.height; - sink_crop.width = DIV_NEAREST_STEP( - sink_crop.height * - f->fmt.pix.width, - f->fmt.pix.height, - ATOM_ISP_STEP_WIDTH); - } else { - sink_crop.width = isp_sink_crop.width; - sink_crop.height = DIV_NEAREST_STEP( - sink_crop.width * - f->fmt.pix.height, - f->fmt.pix.width, - ATOM_ISP_STEP_HEIGHT); - } - atomisp_subdev_set_selection(&asd->subdev, fh.state, - V4L2_SUBDEV_FORMAT_ACTIVE, - ATOMISP_SUBDEV_PAD_SINK, - V4L2_SEL_TGT_CROP, - V4L2_SEL_FLAG_KEEP_CONFIG, - &sink_crop); + if (isp_sink_crop.width * main_compose.height > + isp_sink_crop.height * main_compose.width) { + sink_crop.height = isp_sink_crop.height; + sink_crop.width = + DIV_NEAREST_STEP(sink_crop.height * f->fmt.pix.width, + f->fmt.pix.height, + ATOM_ISP_STEP_WIDTH); + } else { + sink_crop.width = isp_sink_crop.width; + sink_crop.height = + DIV_NEAREST_STEP(sink_crop.width * f->fmt.pix.height, + f->fmt.pix.width, + ATOM_ISP_STEP_HEIGHT); } atomisp_subdev_set_selection(&asd->subdev, fh.state, V4L2_SUBDEV_FORMAT_ACTIVE, + ATOMISP_SUBDEV_PAD_SINK, + V4L2_SEL_TGT_CROP, + V4L2_SEL_FLAG_KEEP_CONFIG, + &sink_crop); + + atomisp_subdev_set_selection(&asd->subdev, fh.state, + V4L2_SUBDEV_FORMAT_ACTIVE, source_pad, V4L2_SEL_TGT_COMPOSE, 0, &main_compose); } -set_fmt_to_isp: - ret = atomisp_set_fmt_to_isp(vdev, &output_info, &raw_output_info, - &f->fmt.pix, source_pad); + ret = atomisp_set_fmt_to_isp(vdev, &output_info, &f->fmt.pix, source_pad); if (ret) { dev_warn(isp->dev, "Can't set format on ISP. Error %d\n", ret); return -EINVAL; } -done: + pipe->pix.width = f->fmt.pix.width; pipe->pix.height = f->fmt.pix.height; pipe->pix.pixelformat = f->fmt.pix.pixelformat; @@ -5470,71 +4790,6 @@ out: return ret; } -int atomisp_offline_capture_configure(struct atomisp_sub_device *asd, - struct atomisp_cont_capture_conf *cvf_config) -{ - struct v4l2_ctrl *c; - - lockdep_assert_held(&asd->isp->mutex); - - /* - * In case of M10MO ZSL capture case, we need to issue a separate - * capture request to M10MO which will output captured jpeg image - */ - c = v4l2_ctrl_find( - asd->isp->inputs[asd->input_curr].camera->ctrl_handler, - V4L2_CID_START_ZSL_CAPTURE); - if (c) { - int ret; - - dev_dbg(asd->isp->dev, "%s trigger ZSL capture request\n", - __func__); - /* TODO: use the cvf_config */ - ret = v4l2_ctrl_s_ctrl(c, 1); - if (ret) - return ret; - - return v4l2_ctrl_s_ctrl(c, 0); - } - - asd->params.offline_parm = *cvf_config; - - if (asd->params.offline_parm.num_captures) { - if (asd->streaming == ATOMISP_DEVICE_STREAMING_DISABLED) { - unsigned int init_raw_num; - - if (asd->enable_raw_buffer_lock->val) { - init_raw_num = - ATOMISP_CSS2_NUM_OFFLINE_INIT_CONTINUOUS_FRAMES_LOCK_EN; - if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO && - asd->params.video_dis_en) - init_raw_num += - ATOMISP_CSS2_NUM_DVS_FRAME_DELAY; - } else { - init_raw_num = - ATOMISP_CSS2_NUM_OFFLINE_INIT_CONTINUOUS_FRAMES; - } - - /* TODO: this can be removed once user-space - * has been updated to use control API */ - asd->continuous_raw_buffer_size->val = - max_t(int, - asd->continuous_raw_buffer_size->val, - asd->params.offline_parm. - num_captures + init_raw_num); - asd->continuous_raw_buffer_size->val = - min_t(int, ATOMISP_CONT_RAW_FRAMES, - asd->continuous_raw_buffer_size->val); - } - asd->continuous_mode->val = true; - } else { - asd->continuous_mode->val = false; - __enable_continuous_mode(asd, false); - } - - return 0; -} - /* * set auto exposure metering window to camera sensor */ @@ -5631,53 +4886,6 @@ void atomisp_init_raw_buffer_bitmap(struct atomisp_sub_device *asd) spin_unlock_irqrestore(&asd->raw_buffer_bitmap_lock, flags); } -static int atomisp_set_raw_buffer_bitmap(struct atomisp_sub_device *asd, int exp_id) -{ - int *bitmap, bit; - unsigned long flags; - - if (__checking_exp_id(asd, exp_id)) - return -EINVAL; - - bitmap = asd->raw_buffer_bitmap + exp_id / 32; - bit = exp_id % 32; - spin_lock_irqsave(&asd->raw_buffer_bitmap_lock, flags); - (*bitmap) |= (1 << bit); - asd->raw_buffer_locked_count++; - spin_unlock_irqrestore(&asd->raw_buffer_bitmap_lock, flags); - - dev_dbg(asd->isp->dev, "%s: exp_id %d, raw_buffer_locked_count %d\n", - __func__, exp_id, asd->raw_buffer_locked_count); - - /* Check if the raw buffer after next is still locked!!! */ - exp_id += 2; - if (exp_id > ATOMISP_MAX_EXP_ID) - exp_id -= ATOMISP_MAX_EXP_ID; - bitmap = asd->raw_buffer_bitmap + exp_id / 32; - bit = exp_id % 32; - if ((*bitmap) & (1 << bit)) { - int ret; - - /* WORKAROUND unlock the raw buffer compulsively */ - ret = atomisp_css_exp_id_unlock(asd, exp_id); - if (ret) { - dev_err(asd->isp->dev, - "%s exp_id is wrapping back to %d but force unlock failed, err %d.\n", - __func__, exp_id, ret); - return ret; - } - - spin_lock_irqsave(&asd->raw_buffer_bitmap_lock, flags); - (*bitmap) &= ~(1 << bit); - asd->raw_buffer_locked_count--; - spin_unlock_irqrestore(&asd->raw_buffer_bitmap_lock, flags); - dev_warn(asd->isp->dev, - "%s exp_id is wrapping back to %d but it is still locked so force unlock it, raw_buffer_locked_count %d\n", - __func__, exp_id, asd->raw_buffer_locked_count); - } - return 0; -} - static int __is_raw_buffer_locked(struct atomisp_sub_device *asd, int exp_id) { int *bitmap, bit; @@ -5816,9 +5024,7 @@ static int atomisp_get_pipe_id(struct atomisp_video_pipe *pipe) return -EINVAL; } - if (ATOMISP_USE_YUVPP(asd)) { - return IA_CSS_PIPE_ID_YUVPP; - } else if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER) { + if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER) { return IA_CSS_PIPE_ID_VIDEO; } else if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_LOWLAT) { return IA_CSS_PIPE_ID_CAPTURE; diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.h b/drivers/staging/media/atomisp/pci/atomisp_cmd.h index 733b9f8cd06f..399b549bcf83 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_cmd.h +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.h @@ -72,7 +72,6 @@ irqreturn_t atomisp_isr_thread(int irq, void *isp_ptr); const struct atomisp_format_bridge *get_atomisp_format_bridge_from_mbus( u32 mbus_code); bool atomisp_is_mbuscode_raw(uint32_t code); -void atomisp_delayed_init_work(struct work_struct *work); /* Get internal fmt according to V4L2 fmt */ bool atomisp_is_viewfinder_support(struct atomisp_device *isp); @@ -268,9 +267,6 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f); int atomisp_set_shading_table(struct atomisp_sub_device *asd, struct atomisp_shading_table *shading_table); -int atomisp_offline_capture_configure(struct atomisp_sub_device *asd, - struct atomisp_cont_capture_conf *cvf_config); - void atomisp_free_internal_buffers(struct atomisp_sub_device *asd); int atomisp_s_ae_window(struct atomisp_sub_device *asd, @@ -317,11 +313,6 @@ void atomisp_init_raw_buffer_bitmap(struct atomisp_sub_device *asd); int atomisp_enable_dz_capt_pipe(struct atomisp_sub_device *asd, unsigned int *enable); -/* Function to get metadata type bu pipe id */ -enum atomisp_metadata_type -atomisp_get_metadata_type(struct atomisp_sub_device *asd, - enum ia_css_pipe_id pipe_id); - u32 atomisp_get_pixel_depth(u32 pixelformat); /* Function for HAL to inject a fake event to wake up poll thread */ diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat.h b/drivers/staging/media/atomisp/pci/atomisp_compat.h index 7316eb9f974a..218e8ac276c8 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_compat.h +++ b/drivers/staging/media/atomisp/pci/atomisp_compat.h @@ -196,9 +196,6 @@ void atomisp_css_input_set_two_pixels_per_clock( struct atomisp_sub_device *asd, bool two_ppc); -void atomisp_css_enable_raw_binning(struct atomisp_sub_device *asd, - bool enable); - void atomisp_css_enable_dz(struct atomisp_sub_device *asd, bool enable); void atomisp_css_capture_set_mode(struct atomisp_sub_device *asd, @@ -306,10 +303,6 @@ int atomisp_css_copy_get_output_frame_info( unsigned int stream_index, struct ia_css_frame_info *info); -int atomisp_css_capture_get_output_raw_frame_info( - struct atomisp_sub_device *asd, - struct ia_css_frame_info *info); - int atomisp_css_preview_get_output_frame_info( struct atomisp_sub_device *asd, struct ia_css_frame_info *info); @@ -423,9 +416,7 @@ int atomisp_css_get_dis_stat(struct atomisp_sub_device *asd, int atomisp_css_update_stream(struct atomisp_sub_device *asd); -int atomisp_css_isr_thread(struct atomisp_device *isp, - bool *frame_done_found, - bool *css_pipe_done); +int atomisp_css_isr_thread(struct atomisp_device *isp); bool atomisp_css_valid_sof(struct atomisp_device *isp); diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c index 61e2e63a0ef1..1dae2a7cfdd9 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c +++ b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c @@ -158,13 +158,6 @@ static void atomisp_css2_hw_load(hrt_address addr, void *to, uint32_t n) spin_unlock_irqrestore(&mmio_lock, flags); } -static int __printf(1, 0) atomisp_css2_dbg_ftrace_print(const char *fmt, - va_list args) -{ - ftrace_vprintk(fmt, args); - return 0; -} - static int __printf(1, 0) atomisp_vprintk(const char *fmt, va_list args) { vprintk(fmt, args); @@ -597,8 +590,6 @@ static void __apply_additional_pipe_config( .enable_reduced_pipe = true; stream_env->pipe_configs[pipe_id] .enable_dz = false; - if (ATOMISP_SOC_CAMERA(asd)) - stream_env->pipe_configs[pipe_id].enable_dz = true; if (asd->params.video_dis_en) { stream_env->pipe_extra_configs[pipe_id] @@ -612,10 +603,7 @@ static void __apply_additional_pipe_config( break; case IA_CSS_PIPE_ID_YUVPP: case IA_CSS_PIPE_ID_COPY: - if (ATOMISP_SOC_CAMERA(asd)) - stream_env->pipe_configs[pipe_id].enable_dz = true; - else - stream_env->pipe_configs[pipe_id].enable_dz = false; + stream_env->pipe_configs[pipe_id].enable_dz = false; break; default: break; @@ -658,13 +646,10 @@ static bool is_pipe_valid_to_current_run_mode(struct atomisp_sub_device *asd, return false; case ATOMISP_RUN_MODE_PREVIEW: - if (!asd->continuous_mode->val) { - if (pipe_id == IA_CSS_PIPE_ID_PREVIEW) - return true; + if (pipe_id == IA_CSS_PIPE_ID_PREVIEW) + return true; - return false; - } - fallthrough; + return false; case ATOMISP_RUN_MODE_CONTINUOUS_CAPTURE: if (pipe_id == IA_CSS_PIPE_ID_CAPTURE || pipe_id == IA_CSS_PIPE_ID_PREVIEW) @@ -672,14 +657,10 @@ static bool is_pipe_valid_to_current_run_mode(struct atomisp_sub_device *asd, return false; case ATOMISP_RUN_MODE_VIDEO: - if (!asd->continuous_mode->val) { - if (pipe_id == IA_CSS_PIPE_ID_VIDEO || - pipe_id == IA_CSS_PIPE_ID_YUVPP) - return true; - else - return false; - } - fallthrough; + if (pipe_id == IA_CSS_PIPE_ID_VIDEO || pipe_id == IA_CSS_PIPE_ID_YUVPP) + return true; + + return false; case ATOMISP_RUN_MODE_SDV: if (pipe_id == IA_CSS_PIPE_ID_CAPTURE || pipe_id == IA_CSS_PIPE_ID_VIDEO) @@ -813,9 +794,6 @@ static inline int __set_css_print_env(struct atomisp_device *isp, int opt) if (opt == 0) isp->css_env.isp_css_env.print_env.debug_print = NULL; else if (opt == 1) - isp->css_env.isp_css_env.print_env.debug_print = - atomisp_css2_dbg_ftrace_print; - else if (opt == 2) isp->css_env.isp_css_env.print_env.debug_print = atomisp_vprintk; else ret = -EINVAL; @@ -1745,25 +1723,6 @@ void atomisp_css_input_set_two_pixels_per_clock( .update_pipe[i] = true; } -void atomisp_css_enable_raw_binning(struct atomisp_sub_device *asd, - bool enable) -{ - struct atomisp_stream_env *stream_env = - &asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]; - unsigned int pipe; - - if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) - pipe = IA_CSS_PIPE_ID_VIDEO; - else - pipe = IA_CSS_PIPE_ID_PREVIEW; - - stream_env->pipe_extra_configs[pipe].enable_raw_binning = enable; - stream_env->update_pipe[pipe] = true; - if (enable) - stream_env->pipe_configs[pipe].output_info[0].padded_width = - stream_env->stream_config.input_config.effective_res.width; -} - void atomisp_css_enable_dz(struct atomisp_sub_device *asd, bool enable) { int i; @@ -1894,17 +1853,6 @@ void atomisp_css_enable_continuous(struct atomisp_sub_device *asd, &asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]; int i; - /* - * To SOC camera, there is only one YUVPP pipe in any case - * including ZSL/SDV/continuous viewfinder, so always set - * stream_config.continuous to 0. - */ - if (ATOMISP_USE_YUVPP(asd)) { - stream_env->stream_config.continuous = 0; - stream_env->stream_config.online = 1; - return; - } - if (stream_env->stream_config.continuous != !!enable) { stream_env->stream_config.continuous = !!enable; stream_env->stream_config.pack_raw_pixels = true; @@ -2122,51 +2070,6 @@ static void __configure_output(struct atomisp_sub_device *asd, pipe_id, width, height, format); } -static void __configure_video_preview_output(struct atomisp_sub_device *asd, - unsigned int stream_index, - unsigned int width, unsigned int height, - unsigned int min_width, - enum ia_css_frame_format format, - enum ia_css_pipe_id pipe_id) -{ - struct atomisp_device *isp = asd->isp; - struct atomisp_stream_env *stream_env = - &asd->stream_env[stream_index]; - struct ia_css_frame_info *css_output_info; - struct ia_css_stream_config *stream_config = &stream_env->stream_config; - - stream_env->pipe_configs[pipe_id].mode = - __pipe_id_to_pipe_mode(asd, pipe_id); - stream_env->update_pipe[pipe_id] = true; - - /* - * second_output will be as video main output in SDV mode - * with SOC camera. output will be as video main output in - * normal video mode. - */ - if (asd->continuous_mode->val) - css_output_info = &stream_env->pipe_configs[pipe_id]. - output_info[ATOMISP_CSS_OUTPUT_SECOND_INDEX]; - else - css_output_info = &stream_env->pipe_configs[pipe_id]. - output_info[ATOMISP_CSS_OUTPUT_DEFAULT_INDEX]; - - css_output_info->res.width = width; - css_output_info->res.height = height; - css_output_info->format = format; - css_output_info->padded_width = min_width; - - /* isp binary 2.2 specific setting*/ - if (width > stream_config->input_config.effective_res.width || - height > stream_config->input_config.effective_res.height) { - stream_config->input_config.effective_res.width = width; - stream_config->input_config.effective_res.height = height; - } - - dev_dbg(isp->dev, "configuring pipe[%d] output info w=%d.h=%d.f=%d.\n", - pipe_id, width, height, format); -} - /* * For CSS2.1, capture pipe uses capture_pp_in_res to configure yuv * downscaling input resolution. @@ -2470,42 +2373,6 @@ static void __configure_vf_output(struct atomisp_sub_device *asd, pipe_id, width, height, format); } -static void __configure_video_vf_output(struct atomisp_sub_device *asd, - unsigned int width, unsigned int height, - unsigned int min_width, - enum ia_css_frame_format format, - enum ia_css_pipe_id pipe_id) -{ - struct atomisp_device *isp = asd->isp; - struct atomisp_stream_env *stream_env = - &asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]; - struct ia_css_frame_info *css_output_info; - - stream_env->pipe_configs[pipe_id].mode = - __pipe_id_to_pipe_mode(asd, pipe_id); - stream_env->update_pipe[pipe_id] = true; - - /* - * second_vf_output will be as video viewfinder in SDV mode - * with SOC camera. vf_output will be as video viewfinder in - * normal video mode. - */ - if (asd->continuous_mode->val) - css_output_info = &stream_env->pipe_configs[pipe_id]. - vf_output_info[ATOMISP_CSS_OUTPUT_SECOND_INDEX]; - else - css_output_info = &stream_env->pipe_configs[pipe_id]. - vf_output_info[ATOMISP_CSS_OUTPUT_DEFAULT_INDEX]; - - css_output_info->res.width = width; - css_output_info->res.height = height; - css_output_info->format = format; - css_output_info->padded_width = min_width; - dev_dbg(isp->dev, - "configuring pipe[%d] vf output info w=%d.h=%d.f=%d.\n", - pipe_id, width, height, format); -} - static int __get_frame_info(struct atomisp_sub_device *asd, unsigned int stream_index, struct ia_css_frame_info *info, @@ -2565,16 +2432,9 @@ static unsigned int atomisp_get_pipe_index(struct atomisp_sub_device *asd, uint16_t source_pad) { struct atomisp_device *isp = asd->isp; - /* - * to SOC camera, use yuvpp pipe. - */ - if (ATOMISP_USE_YUVPP(asd)) - return IA_CSS_PIPE_ID_YUVPP; switch (source_pad) { case ATOMISP_SUBDEV_PAD_SOURCE_VIDEO: - if (asd->yuvpp_mode) - return IA_CSS_PIPE_ID_YUVPP; if (asd->copy_mode) return IA_CSS_PIPE_ID_COPY; if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO @@ -2593,8 +2453,6 @@ static unsigned int atomisp_get_pipe_index(struct atomisp_sub_device *asd, } fallthrough; case ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW: - if (asd->yuvpp_mode) - return IA_CSS_PIPE_ID_YUVPP; if (asd->copy_mode) return IA_CSS_PIPE_ID_COPY; if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) @@ -2617,13 +2475,9 @@ int atomisp_get_css_frame_info(struct atomisp_sub_device *asd, int stream_index; struct atomisp_device *isp = asd->isp; - if (ATOMISP_SOC_CAMERA(asd)) { - stream_index = ATOMISP_INPUT_STREAM_GENERAL; - } else { - stream_index = (pipe_index == IA_CSS_PIPE_ID_YUVPP) ? + stream_index = (pipe_index == IA_CSS_PIPE_ID_YUVPP) ? ATOMISP_INPUT_STREAM_VIDEO : ATOMISP_INPUT_STREAM_GENERAL; - } if (0 != ia_css_pipe_get_info(asd->stream_env[stream_index] .pipes[pipe_index], &info)) { @@ -2636,12 +2490,7 @@ int atomisp_get_css_frame_info(struct atomisp_sub_device *asd, *frame_info = info.output_info[0]; break; case ATOMISP_SUBDEV_PAD_SOURCE_VIDEO: - if (ATOMISP_USE_YUVPP(asd) && asd->continuous_mode->val) - *frame_info = info. - output_info[ATOMISP_CSS_OUTPUT_SECOND_INDEX]; - else - *frame_info = info. - output_info[ATOMISP_CSS_OUTPUT_DEFAULT_INDEX]; + *frame_info = info.output_info[ATOMISP_CSS_OUTPUT_DEFAULT_INDEX]; break; case ATOMISP_SUBDEV_PAD_SOURCE_VF: if (stream_index == ATOMISP_INPUT_STREAM_POSTVIEW) @@ -2653,15 +2502,7 @@ int atomisp_get_css_frame_info(struct atomisp_sub_device *asd, if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO && (pipe_index == IA_CSS_PIPE_ID_VIDEO || pipe_index == IA_CSS_PIPE_ID_YUVPP)) - if (ATOMISP_USE_YUVPP(asd) && asd->continuous_mode->val) - *frame_info = info. - vf_output_info[ATOMISP_CSS_OUTPUT_SECOND_INDEX]; - else - *frame_info = info. - vf_output_info[ATOMISP_CSS_OUTPUT_DEFAULT_INDEX]; - else if (ATOMISP_USE_YUVPP(asd) && asd->continuous_mode->val) - *frame_info = - info.output_info[ATOMISP_CSS_OUTPUT_SECOND_INDEX]; + *frame_info = info.vf_output_info[ATOMISP_CSS_OUTPUT_DEFAULT_INDEX]; else *frame_info = info.output_info[ATOMISP_CSS_OUTPUT_DEFAULT_INDEX]; @@ -2727,16 +2568,8 @@ int atomisp_css_preview_configure_output(struct atomisp_sub_device *asd, unsigned int min_width, enum ia_css_frame_format format) { - /* - * to SOC camera, use yuvpp pipe. - */ - if (ATOMISP_USE_YUVPP(asd)) - __configure_video_preview_output(asd, ATOMISP_INPUT_STREAM_GENERAL, width, - height, - min_width, format, IA_CSS_PIPE_ID_YUVPP); - else - __configure_output(asd, ATOMISP_INPUT_STREAM_GENERAL, width, height, - min_width, format, IA_CSS_PIPE_ID_PREVIEW); + __configure_output(asd, ATOMISP_INPUT_STREAM_GENERAL, width, height, + min_width, format, IA_CSS_PIPE_ID_PREVIEW); return 0; } @@ -2745,18 +2578,8 @@ int atomisp_css_capture_configure_output(struct atomisp_sub_device *asd, unsigned int min_width, enum ia_css_frame_format format) { - enum ia_css_pipe_id pipe_id; - - /* - * to SOC camera, use yuvpp pipe. - */ - if (ATOMISP_USE_YUVPP(asd)) - pipe_id = IA_CSS_PIPE_ID_YUVPP; - else - pipe_id = IA_CSS_PIPE_ID_CAPTURE; - __configure_output(asd, ATOMISP_INPUT_STREAM_GENERAL, width, height, - min_width, format, pipe_id); + min_width, format, IA_CSS_PIPE_ID_CAPTURE); return 0; } @@ -2765,16 +2588,8 @@ int atomisp_css_video_configure_output(struct atomisp_sub_device *asd, unsigned int min_width, enum ia_css_frame_format format) { - /* - * to SOC camera, use yuvpp pipe. - */ - if (ATOMISP_USE_YUVPP(asd)) - __configure_video_preview_output(asd, ATOMISP_INPUT_STREAM_GENERAL, width, - height, - min_width, format, IA_CSS_PIPE_ID_YUVPP); - else - __configure_output(asd, ATOMISP_INPUT_STREAM_GENERAL, width, height, - min_width, format, IA_CSS_PIPE_ID_VIDEO); + __configure_output(asd, ATOMISP_INPUT_STREAM_GENERAL, width, height, + min_width, format, IA_CSS_PIPE_ID_VIDEO); return 0; } @@ -2784,15 +2599,8 @@ int atomisp_css_video_configure_viewfinder( unsigned int min_width, enum ia_css_frame_format format) { - /* - * to SOC camera, video will use yuvpp pipe. - */ - if (ATOMISP_USE_YUVPP(asd)) - __configure_video_vf_output(asd, width, height, min_width, format, - IA_CSS_PIPE_ID_YUVPP); - else - __configure_vf_output(asd, width, height, min_width, format, - IA_CSS_PIPE_ID_VIDEO); + __configure_vf_output(asd, width, height, min_width, format, + IA_CSS_PIPE_ID_VIDEO); return 0; } @@ -2802,18 +2610,7 @@ int atomisp_css_capture_configure_viewfinder( unsigned int min_width, enum ia_css_frame_format format) { - enum ia_css_pipe_id pipe_id; - - /* - * to SOC camera, video will use yuvpp pipe. - */ - if (ATOMISP_USE_YUVPP(asd)) - pipe_id = IA_CSS_PIPE_ID_YUVPP; - else - pipe_id = IA_CSS_PIPE_ID_CAPTURE; - - __configure_vf_output(asd, width, height, min_width, format, - pipe_id); + __configure_vf_output(asd, width, height, min_width, format, IA_CSS_PIPE_ID_CAPTURE); return 0; } @@ -2821,45 +2618,16 @@ int atomisp_css_video_get_viewfinder_frame_info( struct atomisp_sub_device *asd, struct ia_css_frame_info *info) { - enum ia_css_pipe_id pipe_id; - enum frame_info_type frame_type = ATOMISP_CSS_VF_FRAME; - - if (ATOMISP_USE_YUVPP(asd)) { - pipe_id = IA_CSS_PIPE_ID_YUVPP; - if (asd->continuous_mode->val) - frame_type = ATOMISP_CSS_SECOND_VF_FRAME; - } else { - pipe_id = IA_CSS_PIPE_ID_VIDEO; - } - return __get_frame_info(asd, ATOMISP_INPUT_STREAM_GENERAL, info, - frame_type, pipe_id); + ATOMISP_CSS_VF_FRAME, IA_CSS_PIPE_ID_VIDEO); } int atomisp_css_capture_get_viewfinder_frame_info( struct atomisp_sub_device *asd, struct ia_css_frame_info *info) { - enum ia_css_pipe_id pipe_id; - - if (ATOMISP_USE_YUVPP(asd)) - pipe_id = IA_CSS_PIPE_ID_YUVPP; - else - pipe_id = IA_CSS_PIPE_ID_CAPTURE; - return __get_frame_info(asd, ATOMISP_INPUT_STREAM_GENERAL, info, - ATOMISP_CSS_VF_FRAME, pipe_id); -} - -int atomisp_css_capture_get_output_raw_frame_info( - struct atomisp_sub_device *asd, - struct ia_css_frame_info *info) -{ - if (ATOMISP_USE_YUVPP(asd)) - return 0; - - return __get_frame_info(asd, ATOMISP_INPUT_STREAM_GENERAL, info, - ATOMISP_CSS_RAW_FRAME, IA_CSS_PIPE_ID_CAPTURE); + ATOMISP_CSS_VF_FRAME, IA_CSS_PIPE_ID_CAPTURE); } int atomisp_css_copy_get_output_frame_info( @@ -2875,53 +2643,24 @@ int atomisp_css_preview_get_output_frame_info( struct atomisp_sub_device *asd, struct ia_css_frame_info *info) { - enum ia_css_pipe_id pipe_id; - enum frame_info_type frame_type = ATOMISP_CSS_OUTPUT_FRAME; - - if (ATOMISP_USE_YUVPP(asd)) { - pipe_id = IA_CSS_PIPE_ID_YUVPP; - if (asd->continuous_mode->val) - frame_type = ATOMISP_CSS_SECOND_OUTPUT_FRAME; - } else { - pipe_id = IA_CSS_PIPE_ID_PREVIEW; - } - return __get_frame_info(asd, ATOMISP_INPUT_STREAM_GENERAL, info, - frame_type, pipe_id); + ATOMISP_CSS_OUTPUT_FRAME, IA_CSS_PIPE_ID_PREVIEW); } int atomisp_css_capture_get_output_frame_info( struct atomisp_sub_device *asd, struct ia_css_frame_info *info) { - enum ia_css_pipe_id pipe_id; - - if (ATOMISP_USE_YUVPP(asd)) - pipe_id = IA_CSS_PIPE_ID_YUVPP; - else - pipe_id = IA_CSS_PIPE_ID_CAPTURE; - return __get_frame_info(asd, ATOMISP_INPUT_STREAM_GENERAL, info, - ATOMISP_CSS_OUTPUT_FRAME, pipe_id); + ATOMISP_CSS_OUTPUT_FRAME, IA_CSS_PIPE_ID_CAPTURE); } int atomisp_css_video_get_output_frame_info( struct atomisp_sub_device *asd, struct ia_css_frame_info *info) { - enum ia_css_pipe_id pipe_id; - enum frame_info_type frame_type = ATOMISP_CSS_OUTPUT_FRAME; - - if (ATOMISP_USE_YUVPP(asd)) { - pipe_id = IA_CSS_PIPE_ID_YUVPP; - if (asd->continuous_mode->val) - frame_type = ATOMISP_CSS_SECOND_OUTPUT_FRAME; - } else { - pipe_id = IA_CSS_PIPE_ID_VIDEO; - } - return __get_frame_info(asd, ATOMISP_INPUT_STREAM_GENERAL, info, - frame_type, pipe_id); + ATOMISP_CSS_OUTPUT_FRAME, IA_CSS_PIPE_ID_VIDEO); } int atomisp_css_preview_configure_pp_input( @@ -2930,15 +2669,12 @@ int atomisp_css_preview_configure_pp_input( { struct atomisp_stream_env *stream_env = &asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]; - __configure_preview_pp_input(asd, width, height, - ATOMISP_USE_YUVPP(asd) ? - IA_CSS_PIPE_ID_YUVPP : IA_CSS_PIPE_ID_PREVIEW); + __configure_preview_pp_input(asd, width, height, IA_CSS_PIPE_ID_PREVIEW); if (width > stream_env->pipe_configs[IA_CSS_PIPE_ID_CAPTURE]. capt_pp_in_res.width) - __configure_capture_pp_input(asd, width, height, - ATOMISP_USE_YUVPP(asd) ? - IA_CSS_PIPE_ID_YUVPP : IA_CSS_PIPE_ID_CAPTURE); + __configure_capture_pp_input(asd, width, height, IA_CSS_PIPE_ID_CAPTURE); + return 0; } @@ -2946,9 +2682,7 @@ int atomisp_css_capture_configure_pp_input( struct atomisp_sub_device *asd, unsigned int width, unsigned int height) { - __configure_capture_pp_input(asd, width, height, - ATOMISP_USE_YUVPP(asd) ? - IA_CSS_PIPE_ID_YUVPP : IA_CSS_PIPE_ID_CAPTURE); + __configure_capture_pp_input(asd, width, height, IA_CSS_PIPE_ID_CAPTURE); return 0; } @@ -2959,15 +2693,12 @@ int atomisp_css_video_configure_pp_input( struct atomisp_stream_env *stream_env = &asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]; - __configure_video_pp_input(asd, width, height, - ATOMISP_USE_YUVPP(asd) ? - IA_CSS_PIPE_ID_YUVPP : IA_CSS_PIPE_ID_VIDEO); + __configure_video_pp_input(asd, width, height, IA_CSS_PIPE_ID_VIDEO); if (width > stream_env->pipe_configs[IA_CSS_PIPE_ID_CAPTURE]. capt_pp_in_res.width) - __configure_capture_pp_input(asd, width, height, - ATOMISP_USE_YUVPP(asd) ? - IA_CSS_PIPE_ID_YUVPP : IA_CSS_PIPE_ID_CAPTURE); + __configure_capture_pp_input(asd, width, height, IA_CSS_PIPE_ID_CAPTURE); + return 0; } @@ -3662,41 +3393,33 @@ void atomisp_css_morph_table_free(struct ia_css_morph_table *table) ia_css_morph_table_free(table); } -static struct atomisp_sub_device *__get_atomisp_subdev( - struct ia_css_pipe *css_pipe, - struct atomisp_device *isp, - enum atomisp_input_stream_id *stream_id) +static bool atomisp_css_isr_get_stream_id(struct ia_css_pipe *css_pipe, + struct atomisp_device *isp, + enum atomisp_input_stream_id *stream_id) { - int i, j, k; - struct atomisp_sub_device *asd; struct atomisp_stream_env *stream_env; + int i, j; - for (i = 0; i < isp->num_of_streams; i++) { - asd = &isp->asd[i]; - if (asd->streaming == ATOMISP_DEVICE_STREAMING_DISABLED) - continue; - for (j = 0; j < ATOMISP_INPUT_STREAM_NUM; j++) { - stream_env = &asd->stream_env[j]; - for (k = 0; k < IA_CSS_PIPE_ID_NUM; k++) { - if (stream_env->pipes[k] && - stream_env->pipes[k] == css_pipe) { - *stream_id = j; - return asd; - } + if (isp->asd.streaming == ATOMISP_DEVICE_STREAMING_DISABLED) + return false; + + for (i = 0; i < ATOMISP_INPUT_STREAM_NUM; i++) { + stream_env = &isp->asd.stream_env[i]; + for (j = 0; j < IA_CSS_PIPE_ID_NUM; j++) { + if (stream_env->pipes[j] && stream_env->pipes[j] == css_pipe) { + *stream_id = i; + return true; } } } - return NULL; + return false; } -int atomisp_css_isr_thread(struct atomisp_device *isp, - bool *frame_done_found, - bool *css_pipe_done) +int atomisp_css_isr_thread(struct atomisp_device *isp) { enum atomisp_input_stream_id stream_id = 0; struct atomisp_css_event current_event; - struct atomisp_sub_device *asd; lockdep_assert_held(&isp->mutex); @@ -3722,9 +3445,7 @@ int atomisp_css_isr_thread(struct atomisp_device *isp, continue; } - asd = __get_atomisp_subdev(current_event.event.pipe, - isp, &stream_id); - if (!asd) { + if (!atomisp_css_isr_get_stream_id(current_event.event.pipe, isp, &stream_id)) { if (current_event.event.type == IA_CSS_EVENT_TYPE_TIMER) dev_dbg(isp->dev, "event: Timer event."); @@ -3735,56 +3456,53 @@ int atomisp_css_isr_thread(struct atomisp_device *isp, continue; } - atomisp_css_temp_pipe_to_pipe_id(asd, ¤t_event); + atomisp_css_temp_pipe_to_pipe_id(&isp->asd, ¤t_event); switch (current_event.event.type) { case IA_CSS_EVENT_TYPE_OUTPUT_FRAME_DONE: dev_dbg(isp->dev, "event: Output frame done"); - frame_done_found[asd->index] = true; - atomisp_buf_done(asd, 0, IA_CSS_BUFFER_TYPE_OUTPUT_FRAME, + atomisp_buf_done(&isp->asd, 0, IA_CSS_BUFFER_TYPE_OUTPUT_FRAME, current_event.pipe, true, stream_id); break; case IA_CSS_EVENT_TYPE_SECOND_OUTPUT_FRAME_DONE: dev_dbg(isp->dev, "event: Second output frame done"); - frame_done_found[asd->index] = true; - atomisp_buf_done(asd, 0, IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME, + atomisp_buf_done(&isp->asd, 0, IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME, current_event.pipe, true, stream_id); break; case IA_CSS_EVENT_TYPE_3A_STATISTICS_DONE: dev_dbg(isp->dev, "event: 3A stats frame done"); - atomisp_buf_done(asd, 0, + atomisp_buf_done(&isp->asd, 0, IA_CSS_BUFFER_TYPE_3A_STATISTICS, current_event.pipe, false, stream_id); break; case IA_CSS_EVENT_TYPE_METADATA_DONE: dev_dbg(isp->dev, "event: metadata frame done"); - atomisp_buf_done(asd, 0, + atomisp_buf_done(&isp->asd, 0, IA_CSS_BUFFER_TYPE_METADATA, current_event.pipe, false, stream_id); break; case IA_CSS_EVENT_TYPE_VF_OUTPUT_FRAME_DONE: dev_dbg(isp->dev, "event: VF output frame done"); - atomisp_buf_done(asd, 0, + atomisp_buf_done(&isp->asd, 0, IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME, current_event.pipe, true, stream_id); break; case IA_CSS_EVENT_TYPE_SECOND_VF_OUTPUT_FRAME_DONE: dev_dbg(isp->dev, "event: second VF output frame done"); - atomisp_buf_done(asd, 0, + atomisp_buf_done(&isp->asd, 0, IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME, current_event.pipe, true, stream_id); break; case IA_CSS_EVENT_TYPE_DIS_STATISTICS_DONE: dev_dbg(isp->dev, "event: dis stats frame done"); - atomisp_buf_done(asd, 0, + atomisp_buf_done(&isp->asd, 0, IA_CSS_BUFFER_TYPE_DIS_STATISTICS, current_event.pipe, false, stream_id); break; case IA_CSS_EVENT_TYPE_PIPELINE_DONE: dev_dbg(isp->dev, "event: pipeline done"); - css_pipe_done[asd->index] = true; break; case IA_CSS_EVENT_TYPE_ACC_STAGE_COMPLETE: dev_warn(isp->dev, "unexpected event: acc stage done"); @@ -3801,23 +3519,17 @@ int atomisp_css_isr_thread(struct atomisp_device *isp, bool atomisp_css_valid_sof(struct atomisp_device *isp) { - unsigned int i, j; - - /* Loop for each css stream */ - for (i = 0; i < isp->num_of_streams; i++) { - struct atomisp_sub_device *asd = &isp->asd[i]; - /* Loop for each css vc stream */ - for (j = 0; j < ATOMISP_INPUT_STREAM_NUM; j++) { - if (!asd->stream_env[j].stream) - continue; - - dev_dbg(isp->dev, - "stream #%d: mode: %d\n", j, - asd->stream_env[j].stream_config.mode); - if (asd->stream_env[j].stream_config.mode == - IA_CSS_INPUT_MODE_BUFFERED_SENSOR) - return false; - } + unsigned int i; + + /* Loop for each css vc stream */ + for (i = 0; i < ATOMISP_INPUT_STREAM_NUM; i++) { + if (!isp->asd.stream_env[i].stream) + continue; + + dev_dbg(isp->dev, "stream #%d: mode: %d\n", + i, isp->asd.stream_env[i].stream_config.mode); + if (isp->asd.stream_env[i].stream_config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR) + return false; } return true; diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c index ce01479bdd68..fa362c8a37e8 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_fops.c +++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c @@ -112,8 +112,7 @@ static int atomisp_q_one_metadata_buffer(struct atomisp_sub_device *asd, enum ia_css_pipe_id css_pipe_id) { struct atomisp_metadata_buf *metadata_buf; - enum atomisp_metadata_type md_type = - atomisp_get_metadata_type(asd, css_pipe_id); + enum atomisp_metadata_type md_type = ATOMISP_MAIN_METADATA; struct list_head *metadata_list; if (asd->metadata_bufs_in_css[stream_id][css_pipe_id] >= @@ -347,41 +346,6 @@ static int atomisp_get_css_buf_type(struct atomisp_sub_device *asd, enum ia_css_pipe_id pipe_id, uint16_t source_pad) { - if (ATOMISP_USE_YUVPP(asd)) { - /* when run ZSL case */ - if (asd->continuous_mode->val && - asd->run_mode->val == ATOMISP_RUN_MODE_PREVIEW) { - if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE) - return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME; - else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW) - return IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME; - else - return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME; - } - - /*when run SDV case*/ - if (asd->continuous_mode->val && - asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) { - if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE) - return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME; - else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW) - return IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME; - else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VIDEO) - return IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME; - else - return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME; - } - - /*other case: default setting*/ - if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE || - source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VIDEO || - (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW && - asd->run_mode->val != ATOMISP_RUN_MODE_VIDEO)) - return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME; - else - return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME; - } - if (pipe_id == IA_CSS_PIPE_ID_COPY || source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE || source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VIDEO || @@ -414,22 +378,10 @@ int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd) preview_pipe = &asd->video_out_capture; css_preview_pipe_id = IA_CSS_PIPE_ID_CAPTURE; } else if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) { - if (asd->continuous_mode->val) { - capture_pipe = &asd->video_out_capture; - vf_pipe = &asd->video_out_vf; - css_capture_pipe_id = IA_CSS_PIPE_ID_CAPTURE; - } video_pipe = &asd->video_out_video_capture; preview_pipe = &asd->video_out_preview; css_video_pipe_id = IA_CSS_PIPE_ID_VIDEO; css_preview_pipe_id = IA_CSS_PIPE_ID_VIDEO; - } else if (asd->continuous_mode->val) { - capture_pipe = &asd->video_out_capture; - vf_pipe = &asd->video_out_vf; - preview_pipe = &asd->video_out_preview; - - css_preview_pipe_id = IA_CSS_PIPE_ID_PREVIEW; - css_capture_pipe_id = IA_CSS_PIPE_ID_CAPTURE; } else if (asd->run_mode->val == ATOMISP_RUN_MODE_PREVIEW) { preview_pipe = &asd->video_out_preview; css_preview_pipe_id = IA_CSS_PIPE_ID_PREVIEW; @@ -447,27 +399,12 @@ int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd) css_video_pipe_id = IA_CSS_PIPE_ID_COPY; } - if (asd->yuvpp_mode) { - capture_pipe = &asd->video_out_capture; - video_pipe = &asd->video_out_video_capture; - preview_pipe = &asd->video_out_preview; - css_capture_pipe_id = IA_CSS_PIPE_ID_COPY; - css_video_pipe_id = IA_CSS_PIPE_ID_YUVPP; - css_preview_pipe_id = IA_CSS_PIPE_ID_YUVPP; - } - if (capture_pipe) { buf_type = atomisp_get_css_buf_type( asd, css_capture_pipe_id, atomisp_subdev_source_pad(&capture_pipe->vdev)); input_stream_id = ATOMISP_INPUT_STREAM_GENERAL; - /* - * use yuvpp pipe for SOC camera. - */ - if (ATOMISP_USE_YUVPP(asd)) - css_capture_pipe_id = IA_CSS_PIPE_ID_YUVPP; - atomisp_q_video_buffers_to_css(asd, capture_pipe, input_stream_id, buf_type, css_capture_pipe_id); @@ -482,11 +419,6 @@ int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd) else input_stream_id = ATOMISP_INPUT_STREAM_GENERAL; - /* - * use yuvpp pipe for SOC camera. - */ - if (ATOMISP_USE_YUVPP(asd)) - css_capture_pipe_id = IA_CSS_PIPE_ID_YUVPP; atomisp_q_video_buffers_to_css(asd, vf_pipe, input_stream_id, buf_type, css_capture_pipe_id); @@ -496,22 +428,14 @@ int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd) buf_type = atomisp_get_css_buf_type( asd, css_preview_pipe_id, atomisp_subdev_source_pad(&preview_pipe->vdev)); - if (ATOMISP_SOC_CAMERA(asd) && css_preview_pipe_id == IA_CSS_PIPE_ID_YUVPP) - input_stream_id = ATOMISP_INPUT_STREAM_GENERAL; - /* else for ext isp use case */ - else if (css_preview_pipe_id == IA_CSS_PIPE_ID_YUVPP) + + if (css_preview_pipe_id == IA_CSS_PIPE_ID_YUVPP) input_stream_id = ATOMISP_INPUT_STREAM_VIDEO; else if (asd->stream_env[ATOMISP_INPUT_STREAM_PREVIEW].stream) input_stream_id = ATOMISP_INPUT_STREAM_PREVIEW; else input_stream_id = ATOMISP_INPUT_STREAM_GENERAL; - /* - * use yuvpp pipe for SOC camera. - */ - if (ATOMISP_USE_YUVPP(asd)) - css_preview_pipe_id = IA_CSS_PIPE_ID_YUVPP; - atomisp_q_video_buffers_to_css(asd, preview_pipe, input_stream_id, buf_type, css_preview_pipe_id); @@ -526,12 +450,6 @@ int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd) else input_stream_id = ATOMISP_INPUT_STREAM_GENERAL; - /* - * use yuvpp pipe for SOC camera. - */ - if (ATOMISP_USE_YUVPP(asd)) - css_video_pipe_id = IA_CSS_PIPE_ID_YUVPP; - atomisp_q_video_buffers_to_css(asd, video_pipe, input_stream_id, buf_type, css_video_pipe_id); @@ -545,7 +463,6 @@ static void atomisp_buf_queue(struct vb2_buffer *vb) struct atomisp_video_pipe *pipe = vb_to_pipe(vb); struct ia_css_frame *frame = vb_to_frame(vb); struct atomisp_sub_device *asd = pipe->asd; - u16 source_pad = atomisp_subdev_source_pad(&pipe->vdev); unsigned long irqflags; int ret; @@ -593,21 +510,6 @@ static void atomisp_buf_queue(struct vb2_buffer *vb) atomisp_qbuffers_to_css(asd); } - /* - * Workaround: Due to the design of HALv3, - * sometimes in ZSL or SDV mode HAL needs to - * capture multiple images within one streaming cycle. - * But the capture number cannot be determined by HAL. - * So HAL only sets the capture number to be 1 and queue multiple - * buffers. Atomisp driver needs to check this case and re-trigger - * CSS to do capture when new buffer is queued. - */ - if (asd->continuous_mode->val && source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE && - !asd->enable_raw_buffer_lock->val && asd->params.offline_parm.num_captures == 1) { - asd->pending_capture_request++; - dev_dbg(asd->isp->dev, "Add one pending capture request.\n"); - } - out_unlock: mutex_unlock(&asd->isp->mutex); } @@ -662,21 +564,15 @@ static void atomisp_subdev_init_struct(struct atomisp_sub_device *asd) asd->params.fpn_en = false; asd->params.xnr_en = false; asd->params.false_color = 0; - asd->params.online_process = 1; asd->params.yuv_ds_en = 0; /* s3a grid not enabled for any pipe */ asd->params.s3a_enabled_pipe = IA_CSS_PIPE_ID_NUM; - asd->params.offline_parm.num_captures = 1; - asd->params.offline_parm.skip_frames = 0; - asd->params.offline_parm.offset = 0; - asd->delayed_init = ATOMISP_DELAYED_INIT_NOT_QUEUED; /* Add for channel */ asd->input_curr = 0; asd->mipi_frame_size = 0; asd->copy_mode = false; - asd->yuvpp_mode = false; asd->stream_prepared = false; asd->high_speed_mode = false; @@ -698,12 +594,7 @@ static unsigned int atomisp_subdev_users(struct atomisp_sub_device *asd) unsigned int atomisp_dev_users(struct atomisp_device *isp) { - unsigned int i, sum; - - for (i = 0, sum = 0; i < isp->num_of_streams; i++) - sum += atomisp_subdev_users(&isp->asd[i]); - - return sum; + return atomisp_subdev_users(&isp->asd); } static int atomisp_open(struct file *file) @@ -815,7 +706,7 @@ static int atomisp_release(struct file *file) * The sink pad setting can only be cleared when all device nodes * get released. */ - if (asd->fmt_auto->val) { + { struct v4l2_mbus_framefmt isp_sink_fmt = { 0 }; atomisp_subdev_set_ffmt(&asd->subdev, fh.state, diff --git a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c index 7fc7dfa56172..c718a74ea70a 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c +++ b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c @@ -304,7 +304,17 @@ static struct gmin_cfg_var surface3_vars[] = { {}, }; +static struct gmin_cfg_var lenovo_ideapad_miix_310_vars[] = { + /* _DSM contains the wrong CsiPort! */ + { "OVTI2680:01_CsiPort", "0" }, + {} +}; + static const struct dmi_system_id gmin_vars[] = { + /* + * These DMI IDs were present when the atomisp driver was merged into + * drivers/staging and it is unclear if they are really necessary. + */ { .ident = "BYT-T FFD8", .matches = { @@ -341,6 +351,7 @@ static const struct dmi_system_id gmin_vars[] = { }, .driver_data = i8880_vars, }, + /* Later added DMI ids, these are confirmed to really be necessary! */ { .ident = "Surface 3", .matches = { @@ -348,6 +359,14 @@ static const struct dmi_system_id gmin_vars[] = { }, .driver_data = surface3_vars, }, + { + .ident = "Lenovo Ideapad Miix 310", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "MIIX 310-10"), + }, + .driver_data = lenovo_ideapad_miix_310_vars, + }, {} }; @@ -1353,37 +1372,22 @@ static int gmin_get_config_var(struct device *maindev, const char *var, char *out, size_t *out_len) { + struct acpi_device *adev = ACPI_COMPANION(maindev); efi_char16_t var16[CFG_VAR_NAME_MAX]; const struct dmi_system_id *id; - struct device *dev = maindev; char var8[CFG_VAR_NAME_MAX]; efi_status_t status; int i, ret; - /* For sensors, try first to use the _DSM table */ - if (!is_gmin) { - ret = gmin_get_config_dsm_var(maindev, var, out, out_len); - if (!ret) - return 0; - } - - /* Fall-back to other approaches */ - - if (!is_gmin && ACPI_COMPANION(dev)) - dev = &ACPI_COMPANION(dev)->dev; - - if (!is_gmin) - ret = snprintf(var8, sizeof(var8), "%s_%s", dev_name(dev), var); + if (!is_gmin && adev) + ret = snprintf(var8, sizeof(var8), "%s_%s", acpi_dev_name(adev), var); else ret = snprintf(var8, sizeof(var8), "gmin_%s", var); if (ret < 0 || ret >= sizeof(var8) - 1) return -EINVAL; - /* First check a hard-coded list of board-specific variables. - * Some device firmwares lack the ability to set EFI variables at - * runtime. - */ + /* DMI based quirks override both the _DSM table and EFI variables */ id = dmi_first_match(gmin_vars); if (id) { ret = gmin_get_hardcoded_var(maindev, id->driver_data, var8, @@ -1392,6 +1396,13 @@ static int gmin_get_config_var(struct device *maindev, return 0; } + /* For sensors, try first to use the _DSM table */ + if (!is_gmin) { + ret = gmin_get_config_dsm_var(maindev, var, out, out_len); + if (!ret) + return 0; + } + /* Our variable names are ASCII by construction, but EFI names * are wide chars. Convert and zero-pad. */ @@ -1447,3 +1458,243 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0f38, isp_pm_cap_fixup); MODULE_DESCRIPTION("Ancillary routines for binding ACPI devices"); MODULE_LICENSE("GPL"); + +/* + * The below helper functions don't really belong here and should eventually be + * moved to some place under drivers/media/v4l2-core. + */ +#include <linux/platform_data/x86/soc.h> + +/* + * 79234640-9e10-4fea-a5c1-b5aa8b19756f + * This _DSM GUID returns information about the GPIO lines mapped to a sensor. + * Function number 1 returns a count of the GPIO lines that are mapped. + * Subsequent functions return 32 bit ints encoding information about the GPIO. + */ +static const guid_t intel_sensor_gpio_info_guid = + GUID_INIT(0x79234640, 0x9e10, 0x4fea, + 0xa5, 0xc1, 0xb5, 0xaa, 0x8b, 0x19, 0x75, 0x6f); + +/* + * 822ace8f-2814-4174-a56b-5f029fe079ee + * This _DSM GUID returns a string from the sensor device, which acts as a + * module identifier. + */ +static const guid_t intel_sensor_module_guid = + GUID_INIT(0x822ace8f, 0x2814, 0x4174, + 0xa5, 0x6b, 0x5f, 0x02, 0x9f, 0xe0, 0x79, 0xee); + +#define INTEL_DSM_TYPE_SHIFT 0 +#define INTEL_DSM_TYPE_MASK GENMASK(7, 0) +#define INTEL_DSM_PIN_SHIFT 8 +#define INTEL_DSM_PIN_MASK GENMASK(15, 8) +#define INTEL_DSM_SENSOR_ON_VAL_SHIFT 24 +#define INTEL_DSM_SENSOR_ON_VAL_MASK GENMASK(31, 24) + +#define INTEL_DSM_TYPE(x) \ + (((x) & INTEL_DSM_TYPE_MASK) >> INTEL_DSM_TYPE_SHIFT) +#define INTEL_DSM_PIN(x) \ + (((x) & INTEL_DSM_PIN_MASK) >> INTEL_DSM_PIN_SHIFT) +#define INTEL_DSM_SENSOR_ON_VAL(x) \ + (((x) & INTEL_DSM_SENSOR_ON_VAL_MASK) >> INTEL_DSM_SENSOR_ON_VAL_SHIFT) + +#define V4L2_SENSOR_MAX_ACPI_GPIOS 2u + +struct v4l2_acpi_gpio_map { + struct acpi_gpio_params params[V4L2_SENSOR_MAX_ACPI_GPIOS]; + struct acpi_gpio_mapping mapping[V4L2_SENSOR_MAX_ACPI_GPIOS + 1]; +}; + +struct v4l2_acpi_gpio_parsing_data { + struct device *dev; + u32 settings[V4L2_SENSOR_MAX_ACPI_GPIOS]; + unsigned int settings_count; + unsigned int res_count; + unsigned int map_count; + struct v4l2_acpi_gpio_map *map; +}; + +/* Note this always returns 1 to continue looping so that res_count is accurate */ +static int v4l2_acpi_handle_gpio_res(struct acpi_resource *ares, void *_data) +{ + struct v4l2_acpi_gpio_parsing_data *data = _data; + struct acpi_resource_gpio *agpio; + const char *name; + bool active_low; + unsigned int i; + u32 settings; + u8 pin; + + if (!acpi_gpio_get_io_resource(ares, &agpio)) + return 1; /* Not a GPIO, continue the loop */ + + data->res_count++; + + pin = agpio->pin_table[0]; + for (i = 0; i < data->settings_count; i++) { + if (INTEL_DSM_PIN(data->settings[i]) == pin) { + settings = data->settings[i]; + break; + } + } + + if (i == data->settings_count) { + dev_warn(data->dev, "Could not find DSM GPIO settings for pin %d\n", pin); + return 1; + } + + switch (INTEL_DSM_TYPE(settings)) { + case 0: + name = "reset-gpios"; + break; + case 1: + name = "powerdown-gpios"; + break; + default: + dev_warn(data->dev, "Unknown GPIO type 0x%02lx for pin %d\n", + INTEL_DSM_TYPE(settings), pin); + return 1; + } + + /* + * Both reset and power-down need to be logical false when the sensor + * is on (sensor should not be in reset and not be powered-down). So + * when the sensor-on-value (which is the physical pin value) is high, + * then the signal is active-low. + */ + active_low = INTEL_DSM_SENSOR_ON_VAL(settings) ? true : false; + + i = data->map_count; + if (i == V4L2_SENSOR_MAX_ACPI_GPIOS) + return 1; + + /* res_count is already incremented */ + data->map->params[i].crs_entry_index = data->res_count - 1; + data->map->params[i].active_low = active_low; + data->map->mapping[i].name = name; + data->map->mapping[i].data = &data->map->params[i]; + data->map->mapping[i].size = 1; + data->map_count++; + + dev_info(data->dev, "%s crs %d %s pin %d active-%s\n", name, + data->res_count - 1, agpio->resource_source.string_ptr, + pin, active_low ? "low" : "high"); + + return 1; +} + +/* + * Helper function to create an ACPI GPIO lookup table for sensor reset and + * powerdown signals on Intel Bay Trail (BYT) and Cherry Trail (CHT) devices, + * including setting the correct polarity for the GPIO. + * + * This uses the "79234640-9e10-4fea-a5c1-b5aa8b19756f" DSM method directly + * on the sensor device's ACPI node. This is different from later Intel + * hardware which has a separate INT3472 with this info. Since there is + * no separate firmware-node to which we can bind to register the GPIO lookups + * this unfortunately means that all sensor drivers which may be used on + * BYT or CHT hw need to call this function. This also means that this function + * may only fail when it is actually called on BYT/CHT hw. In all other cases + * it must always succeed. + * + * Note this code uses the same DSM GUID as the INT3472 discrete.c code + * and there is some overlap, but there are enough differences that it is + * difficult to share the code. + */ +int v4l2_get_acpi_sensor_info(struct device *dev, char **module_id_str) +{ + struct acpi_device *adev = ACPI_COMPANION(dev); + struct v4l2_acpi_gpio_parsing_data data = { }; + LIST_HEAD(resource_list); + union acpi_object *obj; + unsigned int i, j; + int ret; + + if (module_id_str) + *module_id_str = NULL; + + if (!adev) + return 0; + + obj = acpi_evaluate_dsm_typed(adev->handle, &intel_sensor_module_guid, + 0x00, 0x01, NULL, ACPI_TYPE_STRING); + if (obj) { + dev_info(dev, "Sensor module id: '%s'\n", obj->string.pointer); + if (module_id_str) + *module_id_str = kstrdup(obj->string.pointer, GFP_KERNEL); + + ACPI_FREE(obj); + } + + if (!soc_intel_is_byt() && !soc_intel_is_cht()) + return 0; + + /* + * First get the GPIO-settings count and then get count GPIO-settings + * values. Note the order of these may differ from the order in which + * the GPIOs are listed on the ACPI resources! So we first store them all + * and then enumerate the ACPI resources and match them up by pin number. + */ + obj = acpi_evaluate_dsm_typed(adev->handle, + &intel_sensor_gpio_info_guid, 0x00, 1, + NULL, ACPI_TYPE_INTEGER); + if (!obj) + return dev_err_probe(dev, -EIO, "No _DSM entry for GPIO pin count\n"); + + data.settings_count = obj->integer.value; + ACPI_FREE(obj); + + if (data.settings_count > V4L2_SENSOR_MAX_ACPI_GPIOS) + return dev_err_probe(dev, -EIO, "Too many GPIOs %u > %u\n", + data.settings_count, V4L2_SENSOR_MAX_ACPI_GPIOS); + + for (i = 0; i < data.settings_count; i++) { + /* + * i + 2 because the index of this _DSM function is 1-based + * and the first function is just a count. + */ + obj = acpi_evaluate_dsm_typed(adev->handle, + &intel_sensor_gpio_info_guid, + 0x00, i + 2, + NULL, ACPI_TYPE_INTEGER); + if (!obj) + return dev_err_probe(dev, -EIO, "No _DSM entry for GPIO pin %u\n", i); + + data.settings[i] = obj->integer.value; + ACPI_FREE(obj); + } + + /* Since we match up by pin-number the pin-numbers must be unique */ + for (i = 0; i < data.settings_count; i++) { + for (j = i + 1; j < data.settings_count; j++) { + if (INTEL_DSM_PIN(data.settings[i]) != + INTEL_DSM_PIN(data.settings[j])) + continue; + + return dev_err_probe(dev, -EIO, "Duplicate pin number %lu\n", + INTEL_DSM_PIN(data.settings[i])); + } + } + + /* Use devm_kzalloc() for the mappings + params to auto-free them */ + data.map = devm_kzalloc(dev, sizeof(*data.map), GFP_KERNEL); + if (!data.map) + return -ENOMEM; + + /* Now parse the ACPI resources and build the lookup table */ + data.dev = dev; + ret = acpi_dev_get_resources(adev, &resource_list, + v4l2_acpi_handle_gpio_res, &data); + if (ret < 0) + return ret; + + acpi_dev_free_resource_list(&resource_list); + + if (data.map_count != data.settings_count || + data.res_count != data.settings_count) + dev_warn(dev, "ACPI GPIO resources vs DSM GPIO-info count mismatch (dsm: %d res: %d map %d\n", + data.settings_count, data.res_count, data.map_count); + + return devm_acpi_dev_add_driver_gpios(dev, data.map->mapping); +} +EXPORT_SYMBOL_GPL(v4l2_get_acpi_sensor_info); diff --git a/drivers/staging/media/atomisp/pci/atomisp_internal.h b/drivers/staging/media/atomisp/pci/atomisp_internal.h index fa38d91420cf..1fac99f4e2b0 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_internal.h +++ b/drivers/staging/media/atomisp/pci/atomisp_internal.h @@ -48,8 +48,6 @@ (((isp)->media_dev.hw_revision & ATOMISP_HW_REVISION_MASK) == \ ((rev) << ATOMISP_HW_REVISION_SHIFT)) -#define MAX_STREAM_NUM 2 - #define ATOMISP_PCI_DEVICE_SOC_MASK 0xfff8 /* MRFLD with 0x1178: ISP freq can burst to 457MHz */ #define ATOMISP_PCI_DEVICE_SOC_MRFLD 0x1178 @@ -76,9 +74,6 @@ #define ATOM_RESOLUTION_SUBQCIF_WIDTH 128 #define ATOM_RESOLUTION_SUBQCIF_HEIGHT 96 -#define ATOM_ISP_MAX_WIDTH_TMP 1280 -#define ATOM_ISP_MAX_HEIGHT_TMP 720 - #define ATOM_ISP_I2C_BUS_1 4 #define ATOM_ISP_I2C_BUS_2 5 @@ -101,10 +96,6 @@ #define ATOMISP_METADATA_QUEUE_DEPTH_FOR_HAL 8 #define ATOMISP_S3A_BUF_QUEUE_DEPTH_FOR_HAL 8 -#define ATOMISP_DELAYED_INIT_NOT_QUEUED 0 -#define ATOMISP_DELAYED_INIT_QUEUED 1 -#define ATOMISP_DELAYED_INIT_DONE 2 - /* * Define how fast CPU should be able to serve ISP interrupts. * The bigger the value, the higher risk that the ISP is not @@ -121,23 +112,6 @@ #define ATOMISP_CSS_OUTPUT_SECOND_INDEX 1 #define ATOMISP_CSS_OUTPUT_DEFAULT_INDEX 0 -/* - * ATOMISP_SOC_CAMERA - * This is to differentiate between ext-isp and soc camera in - * Moorefield/Baytrail platform. - */ -#define ATOMISP_SOC_CAMERA(asd) \ - (asd->isp->inputs[asd->input_curr].type == SOC_CAMERA) - -#define ATOMISP_USE_YUVPP(asd) \ - (ATOMISP_SOC_CAMERA(asd) && ATOMISP_CSS_SUPPORT_YUVPP && \ - !asd->copy_mode) - -#define ATOMISP_DEPTH_SENSOR_STREAMON_COUNT 2 - -#define ATOMISP_DEPTH_DEFAULT_MASTER_SENSOR 0 -#define ATOMISP_DEPTH_DEFAULT_SLAVE_SENSOR 1 - /* ISP2401 */ #define ATOMISP_ION_DEVICE_FD_OFFSET 16 #define ATOMISP_ION_SHARED_FD_MASK (0xFFFF) @@ -205,6 +179,7 @@ struct atomisp_device { struct device *dev; struct v4l2_device v4l2_dev; struct media_device media_dev; + struct atomisp_sub_device asd; struct atomisp_platform_data *pdata; void *mmu_l1_base; void __iomem *base; @@ -214,18 +189,6 @@ struct atomisp_device { struct pm_qos_request pm_qos; s32 max_isr_latency; - /* - * ISP modules - * Multiple streams are represents by multiple - * atomisp_sub_device instances - */ - struct atomisp_sub_device *asd; - /* - * this will be assigned dyanamically. - * For Merr/BTY(ISP2400), 2 streams are supported. - */ - unsigned int num_of_streams; - struct atomisp_mipi_csi2_device csi2_port[ATOMISP_CAMERA_NR_PORTS]; struct atomisp_tpg_device tpg; @@ -246,7 +209,7 @@ struct atomisp_device { bool isp_fatal_error; struct work_struct assert_recovery_work; - spinlock_t lock; /* Protects asd[i].streaming */ + spinlock_t lock; /* Protects asd.streaming */ bool need_gfx_throttle; diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c index d1314bdbf7d5..384f31fc66c5 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c +++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c @@ -626,13 +626,7 @@ atomisp_subdev_streaming_count(struct atomisp_sub_device *asd) unsigned int atomisp_streaming_count(struct atomisp_device *isp) { - unsigned int i, sum; - - for (i = 0, sum = 0; i < isp->num_of_streams; i++) - sum += isp->asd[i].streaming == - ATOMISP_DEVICE_STREAMING_ENABLED; - - return sum; + return isp->asd.streaming == ATOMISP_DEVICE_STREAMING_ENABLED; } /* @@ -677,18 +671,6 @@ static int atomisp_s_input(struct file *file, void *fh, unsigned int input) return -EINVAL; } - /* - * check whether the request camera: - * 1: already in use - * 2: if in use, whether it is used by other streams - */ - if (isp->inputs[input].asd && isp->inputs[input].asd != asd) { - dev_err(isp->dev, - "%s, camera is already used by stream: %d\n", __func__, - isp->inputs[input].asd->index); - return -EBUSY; - } - camera = isp->inputs[input].camera; if (!camera) { dev_err(isp->dev, "%s, no camera\n", __func__); @@ -1112,24 +1094,13 @@ static int atomisp_dqbuf_wrapper(struct file *file, void *fh, struct v4l2_buffer buf->reserved2 = pipe->frame_config_id[buf->index]; dev_dbg(isp->dev, - "dqbuf buffer %d (%s) for asd%d with exp_id %d, isp_config_id %d\n", - buf->index, vdev->name, asd->index, buf->reserved >> 16, - buf->reserved2); + "dqbuf buffer %d (%s) with exp_id %d, isp_config_id %d\n", + buf->index, vdev->name, buf->reserved >> 16, buf->reserved2); return 0; } enum ia_css_pipe_id atomisp_get_css_pipe_id(struct atomisp_sub_device *asd) { - if (ATOMISP_USE_YUVPP(asd)) - return IA_CSS_PIPE_ID_YUVPP; - - if (asd->continuous_mode->val) { - if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) - return IA_CSS_PIPE_ID_VIDEO; - else - return IA_CSS_PIPE_ID_PREVIEW; - } - /* * Disable vf_pp and run CSS in video mode. This allows using ISP * scaling but it has one frame delay due to CSS internal buffering. @@ -1164,60 +1135,12 @@ static unsigned int atomisp_sensor_start_stream(struct atomisp_sub_device *asd) if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO || (asd->run_mode->val == ATOMISP_RUN_MODE_STILL_CAPTURE && - !atomisp_is_mbuscode_raw( - asd->fmt[ - asd->capture_pad].fmt.code) && - !asd->continuous_mode->val)) + !atomisp_is_mbuscode_raw(asd->fmt[asd->capture_pad].fmt.code))) return 2; else return 1; } -int atomisp_stream_on_master_slave_sensor(struct atomisp_device *isp, - bool isp_timeout) -{ - unsigned int master, slave, delay_slave = 0; - int ret; - - master = ATOMISP_DEPTH_DEFAULT_MASTER_SENSOR; - slave = ATOMISP_DEPTH_DEFAULT_SLAVE_SENSOR; - dev_warn(isp->dev, - "depth mode use default master=%s.slave=%s.\n", - isp->inputs[master].camera->name, - isp->inputs[slave].camera->name); - - ret = v4l2_subdev_call(isp->inputs[master].camera, core, - ioctl, ATOMISP_IOC_G_DEPTH_SYNC_COMP, - &delay_slave); - if (ret) - dev_warn(isp->dev, - "get depth sensor %s compensation delay failed.\n", - isp->inputs[master].camera->name); - - ret = v4l2_subdev_call(isp->inputs[master].camera, - video, s_stream, 1); - if (ret) { - dev_err(isp->dev, "depth mode master sensor %s stream-on failed.\n", - isp->inputs[master].camera->name); - return -EINVAL; - } - - if (delay_slave != 0) - udelay(delay_slave); - - ret = v4l2_subdev_call(isp->inputs[slave].camera, - video, s_stream, 1); - if (ret) { - dev_err(isp->dev, "depth mode slave sensor %s stream-on failed.\n", - isp->inputs[slave].camera->name); - v4l2_subdev_call(isp->inputs[master].camera, video, s_stream, 0); - - return -EINVAL; - } - - return 0; -} - /* Input system HW workaround */ /* Input system address translation corrupts burst during */ /* invalidate. SW workaround for this is to set burst length */ @@ -1250,8 +1173,7 @@ int atomisp_start_streaming(struct vb2_queue *vq, unsigned int count) mutex_lock(&isp->mutex); - dev_dbg(isp->dev, "Start stream on pad %d for asd%d\n", - atomisp_subdev_source_pad(vdev), asd->index); + dev_dbg(isp->dev, "Start stream on pad %d\n", atomisp_subdev_source_pad(vdev)); ret = atomisp_pipe_check(pipe, false); if (ret) @@ -1266,57 +1188,7 @@ int atomisp_start_streaming(struct vb2_queue *vq, unsigned int count) */ sensor_start_stream = atomisp_sensor_start_stream(asd); - /* Reset pending capture request count. */ - asd->pending_capture_request = 0; - if (atomisp_subdev_streaming_count(asd) > sensor_start_stream) { - /* trigger still capture */ - if (asd->continuous_mode->val && - atomisp_subdev_source_pad(vdev) - == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE) { - if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) - dev_dbg(isp->dev, "SDV last video raw buffer id: %u\n", - asd->latest_preview_exp_id); - else - dev_dbg(isp->dev, "ZSL last preview raw buffer id: %u\n", - asd->latest_preview_exp_id); - - if (asd->delayed_init == ATOMISP_DELAYED_INIT_QUEUED) { - flush_work(&asd->delayed_init_work); - mutex_unlock(&isp->mutex); - ret = wait_for_completion_interruptible(&asd->init_done); - mutex_lock(&isp->mutex); - if (ret) { - ret = -ERESTARTSYS; - goto out_unlock; - } - } - - /* handle per_frame_setting parameter and buffers */ - atomisp_handle_parameter_and_buffer(pipe); - - /* - * only ZSL/SDV capture request will be here, raise - * the ISP freq to the highest possible to minimize - * the S2S latency. - */ - atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_MAX, false); - /* - * When asd->enable_raw_buffer_lock->val is true, - * An extra IOCTL is needed to call - * atomisp_css_exp_id_capture and trigger real capture - */ - if (!asd->enable_raw_buffer_lock->val) { - ret = atomisp_css_offline_capture_configure(asd, - asd->params.offline_parm.num_captures, - asd->params.offline_parm.skip_frames, - asd->params.offline_parm.offset); - if (ret) { - ret = -EINVAL; - goto out_unlock; - } - } - } atomisp_qbuffers_to_css(asd); ret = 0; goto out_unlock; @@ -1396,19 +1268,6 @@ start_sensor: dev_dbg(isp->dev, "DFS auto mode failed!\n"); } - if (asd->depth_mode->val && atomisp_streaming_count(isp) == - ATOMISP_DEPTH_SENSOR_STREAMON_COUNT) { - ret = atomisp_stream_on_master_slave_sensor(isp, false); - if (ret) { - dev_err(isp->dev, "master slave sensor stream on failed!\n"); - goto out_unlock; - } - goto start_delay_wq; - } else if (asd->depth_mode->val && (atomisp_streaming_count(isp) < - ATOMISP_DEPTH_SENSOR_STREAMON_COUNT)) { - goto start_delay_wq; - } - /* Enable the CSI interface on ANN B0/K0 */ if (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 << ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)) { @@ -1427,19 +1286,6 @@ start_sensor: goto out_unlock; } -start_delay_wq: - if (asd->continuous_mode->val) { - atomisp_subdev_get_ffmt(&asd->subdev, NULL, - V4L2_SUBDEV_FORMAT_ACTIVE, - ATOMISP_SUBDEV_PAD_SINK); - - reinit_completion(&asd->init_done); - asd->delayed_init = ATOMISP_DELAYED_INIT_QUEUED; - queue_work(asd->delayed_init_workq, &asd->delayed_init_work); - } else { - asd->delayed_init = ATOMISP_DELAYED_INIT_NOT_QUEUED; - } - out_unlock: mutex_unlock(&isp->mutex); return ret; @@ -1452,16 +1298,15 @@ void atomisp_stop_streaming(struct vb2_queue *vq) struct video_device *vdev = &pipe->vdev; struct atomisp_device *isp = asd->isp; struct pci_dev *pdev = to_pci_dev(isp->dev); - bool recreate_streams[MAX_STREAM_NUM] = {0}; enum ia_css_pipe_id css_pipe_id; + bool recreate_stream = false; bool first_streamoff = false; unsigned long flags; - int i, ret; + int ret; mutex_lock(&isp->mutex); - dev_dbg(isp->dev, "Stop stream on pad %d for asd%d\n", - atomisp_subdev_source_pad(vdev), asd->index); + dev_dbg(isp->dev, "Stop stream on pad %d\n", atomisp_subdev_source_pad(vdev)); /* * There is no guarantee that the buffers queued to / owned by the ISP @@ -1479,24 +1324,6 @@ void atomisp_stop_streaming(struct vb2_queue *vq) if (ret == 0) dev_warn(isp->dev, "Warning timeout waiting for CSS to return buffers\n"); - /* - * do only videobuf_streamoff for capture & vf pipes in - * case of continuous capture - */ - if (asd->continuous_mode->val && - atomisp_subdev_source_pad(vdev) != ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW && - atomisp_subdev_source_pad(vdev) != ATOMISP_SUBDEV_PAD_SOURCE_VIDEO) { - if (atomisp_subdev_source_pad(vdev) == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE) { - /* stop continuous still capture if needed */ - if (asd->params.offline_parm.num_captures == -1) - atomisp_css_offline_capture_configure(asd, - 0, 0, 0); - atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_AUTO, false); - } - - goto out_unlock; - } - if (asd->streaming == ATOMISP_DEVICE_STREAMING_ENABLED) first_streamoff = true; @@ -1513,11 +1340,6 @@ void atomisp_stop_streaming(struct vb2_queue *vq) atomisp_clear_css_buffer_counters(asd); atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, false); - if (asd->delayed_init == ATOMISP_DELAYED_INIT_QUEUED) { - cancel_work_sync(&asd->delayed_init_work); - asd->delayed_init = ATOMISP_DELAYED_INIT_NOT_QUEUED; - } - css_pipe_id = atomisp_get_css_pipe_id(asd); atomisp_css_stop(asd, css_pipe_id, false); @@ -1566,11 +1388,9 @@ stopsensor: * * So force stream destroy here. */ - for (i = 0; i < isp->num_of_streams; i++) { - if (isp->asd[i].stream_prepared) { - atomisp_destroy_pipes_stream_force(&isp->asd[i]); - recreate_streams[i] = true; - } + if (isp->asd.stream_prepared) { + atomisp_destroy_pipes_stream_force(&isp->asd); + recreate_stream = true; } /* disable PUNIT/ISP acknowlede/handshake - SRSE=3 */ @@ -1578,19 +1398,18 @@ stopsensor: isp->saved_regs.i_control | MRFLD_PCI_I_CONTROL_SRSE_RESET_MASK); dev_err(isp->dev, "atomisp_reset"); atomisp_reset(isp); - for (i = 0; i < isp->num_of_streams; i++) { - if (recreate_streams[i]) { - int ret2; - - ret2 = atomisp_create_pipes_stream(&isp->asd[i]); - if (ret2) { - dev_err(isp->dev, "%s error re-creating streams: %d\n", - __func__, ret2); - if (!ret) - ret = ret2; - } + + if (recreate_stream) { + int ret2; + + ret2 = atomisp_create_pipes_stream(&isp->asd); + if (ret2) { + dev_err(isp->dev, "%s error re-creating streams: %d\n", __func__, ret2); + if (!ret) + ret = ret2; } } + isp->isp_timeout = false; out_unlock: mutex_unlock(&isp->mutex); @@ -2304,9 +2123,6 @@ static long atomisp_vidioc_default(struct file *file, void *fh, err = atomisp_set_parameters(vdev, arg); break; - case ATOMISP_IOC_S_CONT_CAPTURE_CONFIG: - err = atomisp_offline_capture_configure(asd, arg); - break; case ATOMISP_IOC_G_METADATA: err = atomisp_get_metadata(asd, 0, arg); break; diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.h b/drivers/staging/media/atomisp/pci/atomisp_ioctl.h index 59e071f035f9..db6da77df06b 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.h +++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.h @@ -53,10 +53,4 @@ unsigned int atomisp_streaming_count(struct atomisp_device *isp); long atomisp_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg); -int atomisp_stream_on_master_slave_sensor(struct atomisp_device *isp, - bool isp_timeout); - -int atomisp_start_streaming(struct vb2_queue *vq, unsigned int count); -void atomisp_stop_streaming(struct vb2_queue *vq); - #endif /* __ATOMISP_IOCTL_H__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.c b/drivers/staging/media/atomisp/pci/atomisp_subdev.c index 9cfb85c61db6..a0acfdb87177 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_subdev.c +++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.c @@ -189,7 +189,6 @@ static int isp_subdev_subscribe_event(struct v4l2_subdev *sd, sub->type != V4L2_EVENT_ATOMISP_METADATA_READY && sub->type != V4L2_EVENT_ATOMISP_PAUSE_BUFFER && sub->type != V4L2_EVENT_ATOMISP_CSS_RESET && - sub->type != V4L2_EVENT_ATOMISP_RAW_BUFFERS_ALLOC_DONE && sub->type != V4L2_EVENT_ATOMISP_ACC_COMPLETE) return -EINVAL; @@ -410,11 +409,6 @@ int atomisp_subdev_set_selection(struct v4l2_subdev *sd, padding_h = 12; } - if (isp->inputs[isp_sd->input_curr].type == SOC_CAMERA) { - padding_w = 0; - padding_h = 0; - } - if (atomisp_subdev_format_conversion(isp_sd, isp_sd->capture_pad) && crop[pad]->width && crop[pad]->height) { @@ -422,13 +416,8 @@ int atomisp_subdev_set_selection(struct v4l2_subdev *sd, crop[pad]->height -= padding_h; } - /* if subdev type is SOC camera,we do not need to set DVS */ - if (isp->inputs[isp_sd->input_curr].type == SOC_CAMERA) - isp_sd->params.video_dis_en = 0; - if (isp_sd->params.video_dis_en && - isp_sd->run_mode->val == ATOMISP_RUN_MODE_VIDEO && - !isp_sd->continuous_mode->val) { + isp_sd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) { /* This resolution contains 20 % of DVS slack * (of the desired captured image before * scaling, or 1 / 6 of what we get from the @@ -459,8 +448,7 @@ int atomisp_subdev_set_selection(struct v4l2_subdev *sd, break; if (isp_sd->params.video_dis_en && - isp_sd->run_mode->val == ATOMISP_RUN_MODE_VIDEO && - !isp_sd->continuous_mode->val) { + isp_sd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) { dvs_w = rounddown(crop[pad]->width / 5, ATOM_ISP_STEP_WIDTH); dvs_h = rounddown(crop[pad]->height / 5, @@ -727,11 +715,7 @@ static int __atomisp_update_run_mode(struct atomisp_sub_device *asd) struct v4l2_ctrl *c; s32 mode; - if (ctrl->val != ATOMISP_RUN_MODE_VIDEO && - asd->continuous_mode->val) - mode = ATOMISP_RUN_MODE_PREVIEW; - else - mode = ctrl->val; + mode = ctrl->val; c = v4l2_ctrl_find( isp->inputs[asd->input_curr].camera->ctrl_handler, @@ -758,23 +742,9 @@ static int s_ctrl(struct v4l2_ctrl *ctrl) { struct atomisp_sub_device *asd = container_of( ctrl->handler, struct atomisp_sub_device, ctrl_handler); - unsigned int streaming; - unsigned long flags; - switch (ctrl->id) { case V4L2_CID_RUN_MODE: return __atomisp_update_run_mode(asd); - case V4L2_CID_DEPTH_MODE: - /* Use spinlock instead of mutex to avoid possible locking issues */ - spin_lock_irqsave(&asd->isp->lock, flags); - streaming = asd->streaming; - spin_unlock_irqrestore(&asd->isp->lock, flags); - if (streaming != ATOMISP_DEVICE_STREAMING_DISABLED) { - dev_err(asd->isp->dev, - "ISP is streaming, it is not supported to change the depth mode\n"); - return -EINVAL; - } - break; } return 0; @@ -784,17 +754,6 @@ static const struct v4l2_ctrl_ops ctrl_ops = { .s_ctrl = &s_ctrl, }; -static const struct v4l2_ctrl_config ctrl_fmt_auto = { - .ops = &ctrl_ops, - .id = V4L2_CID_FMT_AUTO, - .name = "Automatic format guessing", - .type = V4L2_CTRL_TYPE_BOOLEAN, - .min = 0, - .max = 1, - .step = 1, - .def = 1, -}; - static const char *const ctrl_run_mode_menu[] = { NULL, "Video", @@ -831,24 +790,6 @@ static const struct v4l2_ctrl_config ctrl_vfpp = { }; /* - * Control for ISP continuous mode - * - * When enabled, capture processing is possible without - * stopping the preview pipeline. When disabled, ISP needs - * to be restarted between preview and capture. - */ -static const struct v4l2_ctrl_config ctrl_continuous_mode = { - .ops = &ctrl_ops, - .id = V4L2_CID_ATOMISP_CONTINUOUS_MODE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Continuous mode", - .min = 0, - .max = 1, - .step = 1, - .def = 0, -}; - -/* * Control for continuous mode raw buffer size * * The size of the RAW ringbuffer sets limit on how much @@ -930,24 +871,6 @@ static const struct v4l2_ctrl_config ctrl_disable_dz = { .def = 0, }; -/* - * Control for ISP depth mode - * - * When enabled, that means ISP will deal with dual streams and sensors will be - * in slave/master mode. - * slave sensor will have no output until master sensor is streamed on. - */ -static const struct v4l2_ctrl_config ctrl_depth_mode = { - .ops = &ctrl_ops, - .id = V4L2_CID_DEPTH_MODE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Depth mode", - .min = 0, - .max = 1, - .step = 1, - .def = 0, -}; - static int atomisp_init_subdev_pipe(struct atomisp_sub_device *asd, struct atomisp_video_pipe *pipe, enum v4l2_buf_type buf_type) { @@ -995,7 +918,7 @@ static int isp_subdev_init_entities(struct atomisp_sub_device *asd) int ret; v4l2_subdev_init(sd, &isp_subdev_v4l2_ops); - sprintf(sd->name, "ATOMISP_SUBDEV_%d", asd->index); + sprintf(sd->name, "ATOMISP_SUBDEV"); v4l2_set_subdevdata(sd, asd); sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE; @@ -1066,14 +989,10 @@ static int isp_subdev_init_entities(struct atomisp_sub_device *asd) if (ret) return ret; - asd->fmt_auto = v4l2_ctrl_new_custom(&asd->ctrl_handler, - &ctrl_fmt_auto, NULL); asd->run_mode = v4l2_ctrl_new_custom(&asd->ctrl_handler, &ctrl_run_mode, NULL); asd->vfpp = v4l2_ctrl_new_custom(&asd->ctrl_handler, &ctrl_vfpp, NULL); - asd->continuous_mode = v4l2_ctrl_new_custom(&asd->ctrl_handler, - &ctrl_continuous_mode, NULL); asd->continuous_viewfinder = v4l2_ctrl_new_custom(&asd->ctrl_handler, &ctrl_continuous_viewfinder, NULL); @@ -1086,10 +1005,6 @@ static int isp_subdev_init_entities(struct atomisp_sub_device *asd) v4l2_ctrl_new_custom(&asd->ctrl_handler, &ctrl_enable_raw_buffer_lock, NULL); - asd->depth_mode = - v4l2_ctrl_new_custom(&asd->ctrl_handler, - &ctrl_depth_mode, - NULL); asd->disable_dz = v4l2_ctrl_new_custom(&asd->ctrl_handler, &ctrl_disable_dz, @@ -1103,21 +1018,16 @@ static int isp_subdev_init_entities(struct atomisp_sub_device *asd) int atomisp_create_pads_links(struct atomisp_device *isp) { - struct atomisp_sub_device *asd; - int i, j, ret = 0; + int i, ret; - isp->num_of_streams = 2; for (i = 0; i < ATOMISP_CAMERA_NR_PORTS; i++) { - for (j = 0; j < isp->num_of_streams; j++) { - ret = - media_create_pad_link(&isp->csi2_port[i].subdev. - entity, CSI2_PAD_SOURCE, - &isp->asd[j].subdev.entity, - ATOMISP_SUBDEV_PAD_SINK, 0); - if (ret < 0) - return ret; - } + ret = media_create_pad_link(&isp->csi2_port[i].subdev.entity, + CSI2_PAD_SOURCE, &isp->asd.subdev.entity, + ATOMISP_SUBDEV_PAD_SINK, 0); + if (ret < 0) + return ret; } + for (i = 0; i < isp->input_cnt; i++) { /* Don't create links for the test-pattern-generator */ if (isp->inputs[i].type == TEST_PATTERN) @@ -1132,33 +1042,28 @@ int atomisp_create_pads_links(struct atomisp_device *isp) if (ret < 0) return ret; } - for (i = 0; i < isp->num_of_streams; i++) { - asd = &isp->asd[i]; - ret = media_create_pad_link(&asd->subdev.entity, - ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW, - &asd->video_out_preview.vdev.entity, - 0, 0); - if (ret < 0) - return ret; - ret = media_create_pad_link(&asd->subdev.entity, - ATOMISP_SUBDEV_PAD_SOURCE_VF, - &asd->video_out_vf.vdev.entity, 0, - 0); - if (ret < 0) - return ret; - ret = media_create_pad_link(&asd->subdev.entity, - ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE, - &asd->video_out_capture.vdev.entity, - 0, 0); - if (ret < 0) - return ret; - ret = media_create_pad_link(&asd->subdev.entity, - ATOMISP_SUBDEV_PAD_SOURCE_VIDEO, - &asd->video_out_video_capture.vdev. - entity, 0, 0); - if (ret < 0) - return ret; - } + + ret = media_create_pad_link(&isp->asd.subdev.entity, + ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW, + &isp->asd.video_out_preview.vdev.entity, 0, 0); + if (ret < 0) + return ret; + ret = media_create_pad_link(&isp->asd.subdev.entity, + ATOMISP_SUBDEV_PAD_SOURCE_VF, + &isp->asd.video_out_vf.vdev.entity, 0, 0); + if (ret < 0) + return ret; + ret = media_create_pad_link(&isp->asd.subdev.entity, + ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE, + &isp->asd.video_out_capture.vdev.entity, 0, 0); + if (ret < 0) + return ret; + ret = media_create_pad_link(&isp->asd.subdev.entity, + ATOMISP_SUBDEV_PAD_SOURCE_VIDEO, + &isp->asd.video_out_video_capture.vdev.entity, 0, 0); + if (ret < 0) + return ret; + return 0; } @@ -1254,29 +1159,13 @@ error: */ int atomisp_subdev_init(struct atomisp_device *isp) { - struct atomisp_sub_device *asd; - int i, ret = 0; + int ret; - /* - * CSS2.0 running ISP2400 support - * multiple streams - */ - isp->num_of_streams = 2; - isp->asd = devm_kzalloc(isp->dev, sizeof(struct atomisp_sub_device) * - isp->num_of_streams, GFP_KERNEL); - if (!isp->asd) - return -ENOMEM; - for (i = 0; i < isp->num_of_streams; i++) { - asd = &isp->asd[i]; - asd->isp = isp; - isp_subdev_init_params(asd); - asd->index = i; - ret = isp_subdev_init_entities(asd); - if (ret < 0) { - atomisp_subdev_cleanup_entities(asd); - break; - } - } + isp->asd.isp = isp; + isp_subdev_init_params(&isp->asd); + ret = isp_subdev_init_entities(&isp->asd); + if (ret < 0) + atomisp_subdev_cleanup_entities(&isp->asd); return ret; } diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.h b/drivers/staging/media/atomisp/pci/atomisp_subdev.h index daa6077a83bd..fee663bc415a 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_subdev.h +++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.h @@ -183,9 +183,6 @@ struct atomisp_css_params { }; struct atomisp_subdev_params { - /* FIXME: Determines whether raw capture buffer are being passed to - * user space. Unimplemented for now. */ - int online_process; int yuv_ds_en; unsigned int color_effect; bool gdc_cac_en; @@ -237,8 +234,6 @@ struct atomisp_subdev_params { enum atomisp_flash_state flash_state; enum atomisp_frame_status last_frame_status; - /* continuous capture */ - struct atomisp_cont_capture_conf offline_parm; /* Flag to check if driver needs to update params to css */ bool css_update_params_needed; }; @@ -264,11 +259,8 @@ struct atomisp_sub_device { /* struct isp_subdev_params params; */ struct atomisp_device *isp; struct v4l2_ctrl_handler ctrl_handler; - struct v4l2_ctrl *fmt_auto; struct v4l2_ctrl *run_mode; - struct v4l2_ctrl *depth_mode; struct v4l2_ctrl *vfpp; - struct v4l2_ctrl *continuous_mode; struct v4l2_ctrl *continuous_raw_buffer_size; struct v4l2_ctrl *continuous_viewfinder; struct v4l2_ctrl *enable_raw_buffer_lock; @@ -307,7 +299,6 @@ struct atomisp_sub_device { spinlock_t dis_stats_lock; struct ia_css_frame *vf_frame; /* TODO: needed? */ - struct ia_css_frame *raw_output_frame; enum atomisp_frame_status frame_status[VIDEO_MAX_FRAME]; /* This field specifies which camera (v4l2 input) is selected. */ @@ -324,23 +315,11 @@ struct atomisp_sub_device { unsigned int streaming; bool stream_prepared; /* whether css stream is created */ - /* subdev index: will be used to show which subdev is holding the - * resource, like which camera is used by which subdev - */ - unsigned int index; - - /* delayed memory allocation for css */ - struct completion init_done; - struct workqueue_struct *delayed_init_workq; - unsigned int delayed_init; - struct work_struct delayed_init_work; - unsigned int latest_preview_exp_id; /* CSS ZSL/SDV raw buffer id */ unsigned int mipi_frame_size; bool copy_mode; /* CSI2+ use copy mode */ - bool yuvpp_mode; /* CSI2+ yuvpp pipe */ int raw_buffer_bitmap[ATOMISP_MAX_EXP_ID / 32 + 1]; /* Record each Raw Buffer lock status */ @@ -352,7 +331,6 @@ struct atomisp_sub_device { struct atomisp_resolution sensor_array_res; bool high_speed_mode; /* Indicate whether now is a high speed mode */ - int pending_capture_request; /* Indicates the number of pending capture requests. */ unsigned int preview_exp_id; unsigned int postview_exp_id; diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index ba628f7cf385..3f315dabbeeb 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -64,10 +64,10 @@ module_param(dbg_level, int, 0644); MODULE_PARM_DESC(dbg_level, "debug message level (default:0)"); /* log function switch */ -int dbg_func = 2; +int dbg_func = 1; module_param(dbg_func, int, 0644); MODULE_PARM_DESC(dbg_func, - "log function switch non/trace_printk/printk (default:printk)"); + "log function switch non/printk (default:printk)"); int mipicsi_flag; module_param(mipicsi_flag, int, 0644); @@ -753,8 +753,6 @@ static int atomisp_suspend(struct device *dev) { struct atomisp_device *isp = (struct atomisp_device *) dev_get_drvdata(dev); - /* FIXME: only has one isp_subdev at present */ - struct atomisp_sub_device *asd = &isp->asd[0]; unsigned long flags; /* @@ -765,7 +763,7 @@ static int atomisp_suspend(struct device *dev) return -EBUSY; spin_lock_irqsave(&isp->lock, flags); - if (asd->streaming != ATOMISP_DEVICE_STREAMING_DISABLED) { + if (isp->asd.streaming != ATOMISP_DEVICE_STREAMING_DISABLED) { spin_unlock_irqrestore(&isp->lock, flags); dev_err(isp->dev, "atomisp cannot suspend at this time.\n"); return -EINVAL; @@ -842,8 +840,7 @@ int atomisp_csi_lane_config(struct atomisp_device *isp) for (i = 0; i < isp->input_cnt; i++) { struct camera_mipi_info *mipi_info; - if (isp->inputs[i].type != RAW_CAMERA && - isp->inputs[i].type != SOC_CAMERA) + if (isp->inputs[i].type != RAW_CAMERA) continue; mipi_info = atomisp_to_sensor_mipi_info(isp->inputs[i].camera); @@ -923,8 +920,7 @@ static int atomisp_subdev_probe(struct atomisp_device *isp) int camera_count = 0; for (subdevs = pdata->subdevs; subdevs->type; ++subdevs) { - if (subdevs->type == RAW_CAMERA || - subdevs->type == SOC_CAMERA) + if (subdevs->type == RAW_CAMERA) camera_count++; } if (camera_count) @@ -945,9 +941,6 @@ static int atomisp_subdev_probe(struct atomisp_device *isp) case RAW_CAMERA: dev_dbg(isp->dev, "raw_index: %d\n", raw_index); raw_index = isp->input_cnt; - fallthrough; - case SOC_CAMERA: - dev_dbg(isp->dev, "SOC_INDEX: %d\n", isp->input_cnt); if (isp->input_cnt >= ATOM_ISP_MAX_INPUTS) { dev_warn(isp->dev, "too many atomisp inputs, ignored\n"); @@ -974,7 +967,6 @@ static int atomisp_subdev_probe(struct atomisp_device *isp) isp->motor = subdevs->subdev; break; case LED_FLASH: - case XENON_FLASH: if (isp->flash) { dev_warn(isp->dev, "too many atomisp flash devices\n"); continue; @@ -1010,8 +1002,7 @@ static void atomisp_unregister_entities(struct atomisp_device *isp) unsigned int i; struct v4l2_subdev *sd, *next; - for (i = 0; i < isp->num_of_streams; i++) - atomisp_subdev_unregister_entities(&isp->asd[i]); + atomisp_subdev_unregister_entities(&isp->asd); atomisp_tpg_unregister_entities(&isp->tpg); for (i = 0; i < ATOMISP_CAMERA_NR_PORTS; i++) atomisp_mipi_csi2_unregister_entities(&isp->csi2_port[i]); @@ -1070,38 +1061,10 @@ static int atomisp_register_entities(struct atomisp_device *isp) goto tpg_register_failed; } - for (i = 0; i < isp->num_of_streams; i++) { - struct atomisp_sub_device *asd = &isp->asd[i]; - - ret = atomisp_subdev_register_subdev(asd, &isp->v4l2_dev); - if (ret < 0) { - dev_err(isp->dev, "atomisp_subdev_register_subdev fail\n"); - for (; i > 0; i--) - atomisp_subdev_unregister_entities( - &isp->asd[i - 1]); - goto subdev_register_failed; - } - } - - for (i = 0; i < isp->num_of_streams; i++) { - struct atomisp_sub_device *asd = &isp->asd[i]; - - init_completion(&asd->init_done); - - asd->delayed_init_workq = - alloc_workqueue(isp->v4l2_dev.name, WQ_CPU_INTENSIVE, - 1); - if (!asd->delayed_init_workq) { - dev_err(isp->dev, - "Failed to initialize delayed init workq\n"); - ret = -ENOMEM; - - for (; i > 0; i--) - destroy_workqueue(isp->asd[i - 1]. - delayed_init_workq); - goto wq_alloc_failed; - } - INIT_WORK(&asd->delayed_init_work, atomisp_delayed_init_work); + ret = atomisp_subdev_register_subdev(&isp->asd, &isp->v4l2_dev); + if (ret < 0) { + dev_err(isp->dev, "atomisp_subdev_register_subdev fail\n"); + goto subdev_register_failed; } for (i = 0; i < isp->input_cnt; i++) { @@ -1126,13 +1089,7 @@ static int atomisp_register_entities(struct atomisp_device *isp) return 0; link_failed: - for (i = 0; i < isp->num_of_streams; i++) - destroy_workqueue(isp->asd[i]. - delayed_init_workq); -wq_alloc_failed: - for (i = 0; i < isp->num_of_streams; i++) - atomisp_subdev_unregister_entities( - &isp->asd[i]); + atomisp_subdev_unregister_entities(&isp->asd); subdev_register_failed: atomisp_tpg_unregister_entities(&isp->tpg); tpg_register_failed: @@ -1148,13 +1105,11 @@ v4l2_device_failed: static int atomisp_register_device_nodes(struct atomisp_device *isp) { - int i, err; + int err; - for (i = 0; i < isp->num_of_streams; i++) { - err = atomisp_subdev_register_video_nodes(&isp->asd[i], &isp->v4l2_dev); - if (err) - return err; - } + err = atomisp_subdev_register_video_nodes(&isp->asd, &isp->v4l2_dev); + if (err) + return err; err = atomisp_create_pads_links(isp); if (err) diff --git a/drivers/staging/media/av7110/av7110.c b/drivers/staging/media/av7110/av7110.c index df81a9b744c2..a5a431c14ea7 100644 --- a/drivers/staging/media/av7110/av7110.c +++ b/drivers/staging/media/av7110/av7110.c @@ -1106,9 +1106,11 @@ static int dvb_get_stc(struct dmx_demux *demux, unsigned int num, struct av7110 *av7110; /* pointer casting paranoia... */ - BUG_ON(!demux); + if (WARN_ON(!demux)) + return -EIO; dvbdemux = demux->priv; - BUG_ON(!dvbdemux); + if (WARN_ON(!dvbdemux)) + return -EIO; av7110 = dvbdemux->priv; dprintk(4, "%p\n", av7110); diff --git a/drivers/staging/media/av7110/av7110_av.c b/drivers/staging/media/av7110/av7110_av.c index 0bf513c26b6b..a5c5bebad306 100644 --- a/drivers/staging/media/av7110/av7110_av.c +++ b/drivers/staging/media/av7110/av7110_av.c @@ -823,10 +823,10 @@ static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, s av7110_ipack_flush(ipack); if (buf[3] & ADAPT_FIELD) { + if (buf[4] > len - 1 - 4) + return 0; len -= buf[4] + 1; buf += buf[4] + 1; - if (!len) - return 0; } av7110_ipack_instant_repack(buf + 4, len - 4, ipack); diff --git a/drivers/staging/media/av7110/av7110_hw.c b/drivers/staging/media/av7110/av7110_hw.c index 93ca31e38ddd..a0be37717259 100644 --- a/drivers/staging/media/av7110/av7110_hw.c +++ b/drivers/staging/media/av7110/av7110_hw.c @@ -1007,7 +1007,8 @@ static int OSDSetBlock(struct av7110 *av7110, int x0, int y0, if (av7110->bmp_state == BMP_LOADING) { /* possible if syscall is repeated by -ERESTARTSYS and if firmware cannot abort */ - BUG_ON (FW_VERSION(av7110->arm_app) >= 0x261e); + if (WARN_ON(FW_VERSION(av7110->arm_app) >= 0x261e)) + return -EIO; rc = WaitUntilBmpLoaded(av7110); if (rc) return rc; diff --git a/drivers/staging/media/av7110/av7110_v4l.c b/drivers/staging/media/av7110/av7110_v4l.c index c89f536f699c..ed2c605808e8 100644 --- a/drivers/staging/media/av7110/av7110_v4l.c +++ b/drivers/staging/media/av7110/av7110_v4l.c @@ -213,25 +213,14 @@ static const struct v4l2_audio msp3400_v4l2_audio = { .capability = V4L2_AUDCAP_STEREO }; -static int av7110_dvb_c_switch(struct saa7146_fh *fh) +static int av7110_dvb_c_switch(struct saa7146_dev *dev) { - struct saa7146_dev *dev = fh->dev; - struct saa7146_vv *vv = dev->vv_data; struct av7110 *av7110 = (struct av7110*)dev->ext_priv; u16 adswitch; - int source, sync, err; + int source, sync; dprintk(4, "%p\n", av7110); - if ((vv->video_status & STATUS_OVERLAY) != 0) { - vv->ov_suspend = vv->video_fh; - err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */ - if (err != 0) { - dprintk(2, "suspending video failed\n"); - vv->ov_suspend = NULL; - } - } - if (0 != av7110->current_input) { dprintk(1, "switching to analog TV:\n"); adswitch = 1; @@ -300,17 +289,12 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh) saa7146_set_hps_source_and_sync(dev, source, sync); - if (vv->ov_suspend != NULL) { - saa7146_start_preview(vv->ov_suspend); - vv->ov_suspend = NULL; - } - return 0; } static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_dev *dev = video_drvdata(file); struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; u16 stereo_det; s8 stereo; @@ -354,7 +338,7 @@ static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t) static int vidioc_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *t) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_dev *dev = video_drvdata(file); struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; u16 fm_matrix, src; dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index); @@ -398,7 +382,7 @@ static int vidioc_s_tuner(struct file *file, void *fh, const struct v4l2_tuner * static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_dev *dev = video_drvdata(file); struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x\n", f->frequency); @@ -414,7 +398,7 @@ static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency static int vidioc_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *f) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_dev *dev = video_drvdata(file); struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x\n", f->frequency); @@ -444,7 +428,7 @@ static int vidioc_s_frequency(struct file *file, void *fh, const struct v4l2_fre static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_dev *dev = video_drvdata(file); struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index); @@ -464,7 +448,7 @@ static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) static int vidioc_g_input(struct file *file, void *fh, unsigned int *input) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_dev *dev = video_drvdata(file); struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; *input = av7110->current_input; @@ -474,7 +458,7 @@ static int vidioc_g_input(struct file *file, void *fh, unsigned int *input) static int vidioc_s_input(struct file *file, void *fh, unsigned int input) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_dev *dev = video_drvdata(file); struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; dprintk(2, "VIDIOC_S_INPUT: %d\n", input); @@ -486,7 +470,29 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input) return -EINVAL; av7110->current_input = input; - return av7110_dvb_c_switch(fh); + return av7110_dvb_c_switch(dev); +} + +static int vidioc_enum_output(struct file *file, void *fh, struct v4l2_output *o) +{ + if (o->index) + return -EINVAL; + strscpy(o->name, "Video Output", sizeof(o->name)); + o->type = V4L2_OUTPUT_TYPE_ANALOG; + o->std = V4L2_STD_NTSC_M | V4L2_STD_PAL_BG; + o->capabilities = V4L2_OUT_CAP_STD; + return 0; +} + +static int vidioc_g_output(struct file *file, void *fh, unsigned int *output) +{ + *output = 0; + return 0; +} + +static int vidioc_s_output(struct file *file, void *fh, unsigned int output) +{ + return output ? -EINVAL : 0; } static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a) @@ -500,7 +506,7 @@ static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a) static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_dev *dev = video_drvdata(file); struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index); @@ -514,7 +520,7 @@ static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a) static int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *a) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_dev *dev = video_drvdata(file); struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index); @@ -526,7 +532,7 @@ static int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio * static int vidioc_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_dev *dev = video_drvdata(file); struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n"); @@ -542,7 +548,7 @@ static int vidioc_g_sliced_vbi_cap(struct file *file, void *fh, static int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *f) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_dev *dev = video_drvdata(file); struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; dprintk(2, "VIDIOC_G_FMT:\n"); @@ -552,59 +558,58 @@ static int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *fh, if (av7110->wssMode) { f->fmt.sliced.service_set = V4L2_SLICED_WSS_625; f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625; - f->fmt.sliced.io_size = sizeof(struct v4l2_sliced_vbi_data); } + f->fmt.sliced.io_size = sizeof(struct v4l2_sliced_vbi_data); + return 0; +} + +static int vidioc_try_fmt_sliced_vbi_out(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct saa7146_dev *dev = video_drvdata(file); + struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; + bool want_wss = (f->fmt.sliced.service_set & V4L2_SLICED_WSS_625) || + (!f->fmt.sliced.service_set && + f->fmt.sliced.service_lines[0][23] == V4L2_SLICED_WSS_625); + + dprintk(2, "VIDIOC_G_FMT:\n"); + if (FW_VERSION(av7110->arm_app) < 0x2623) + return -EINVAL; + memset(&f->fmt.sliced, 0, sizeof(f->fmt.sliced)); + if (want_wss) { + f->fmt.sliced.service_set = V4L2_SLICED_WSS_625; + f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625; + } + f->fmt.sliced.io_size = sizeof(struct v4l2_sliced_vbi_data); return 0; } static int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *f) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_dev *dev = video_drvdata(file); struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; dprintk(2, "VIDIOC_S_FMT\n"); - if (FW_VERSION(av7110->arm_app) < 0x2623) + if (vidioc_try_fmt_sliced_vbi_out(file, fh, f)) return -EINVAL; - if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 && - f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) { - memset(&f->fmt.sliced, 0, sizeof(f->fmt.sliced)); + if (f->fmt.sliced.service_set & V4L2_SLICED_WSS_625) { + /* WSS controlled by userspace */ + av7110->wssMode = 1; + av7110->wssData = 0; + } else { /* WSS controlled by firmware */ av7110->wssMode = 0; av7110->wssData = 0; return av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0); - } else { - memset(&f->fmt.sliced, 0, sizeof(f->fmt.sliced)); - f->fmt.sliced.service_set = V4L2_SLICED_WSS_625; - f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625; - f->fmt.sliced.io_size = sizeof(struct v4l2_sliced_vbi_data); - /* WSS controlled by userspace */ - av7110->wssMode = 1; - av7110->wssData = 0; } return 0; } -static int av7110_vbi_reset(struct file *file) -{ - struct saa7146_fh *fh = file->private_data; - struct saa7146_dev *dev = fh->dev; - struct av7110 *av7110 = (struct av7110*) dev->ext_priv; - - dprintk(2, "%s\n", __func__); - av7110->wssMode = 0; - av7110->wssData = 0; - if (FW_VERSION(av7110->arm_app) < 0x2623) - return 0; - else - return av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0); -} - static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size_t count, loff_t *ppos) { - struct saa7146_fh *fh = file->private_data; - struct saa7146_dev *dev = fh->dev; + struct saa7146_dev *dev = video_drvdata(file); struct av7110 *av7110 = (struct av7110*) dev->ext_priv; struct v4l2_sliced_vbi_data d; int rc; @@ -819,13 +824,16 @@ int av7110_init_v4l(struct av7110 *av7110) vv_data->vid_ops.vidioc_s_audio = vidioc_s_audio; vv_data->vid_ops.vidioc_g_fmt_vbi_cap = NULL; - vv_data->vbi_ops.vidioc_g_tuner = vidioc_g_tuner; - vv_data->vbi_ops.vidioc_s_tuner = vidioc_s_tuner; - vv_data->vbi_ops.vidioc_g_frequency = vidioc_g_frequency; - vv_data->vbi_ops.vidioc_s_frequency = vidioc_s_frequency; + vv_data->vbi_ops.vidioc_enum_output = vidioc_enum_output; + vv_data->vbi_ops.vidioc_g_output = vidioc_g_output; + vv_data->vbi_ops.vidioc_s_output = vidioc_s_output; + vv_data->vbi_ops.vidioc_g_parm = NULL; vv_data->vbi_ops.vidioc_g_fmt_vbi_cap = NULL; + vv_data->vbi_ops.vidioc_try_fmt_vbi_cap = NULL; + vv_data->vbi_ops.vidioc_s_fmt_vbi_cap = NULL; vv_data->vbi_ops.vidioc_g_sliced_vbi_cap = vidioc_g_sliced_vbi_cap; vv_data->vbi_ops.vidioc_g_fmt_sliced_vbi_out = vidioc_g_fmt_sliced_vbi_out; + vv_data->vbi_ops.vidioc_try_fmt_sliced_vbi_out = vidioc_try_fmt_sliced_vbi_out; vv_data->vbi_ops.vidioc_s_fmt_sliced_vbi_out = vidioc_s_fmt_sliced_vbi_out; if (FW_VERSION(av7110->arm_app) < 0x2623) @@ -866,7 +874,7 @@ static struct saa7146_standard standard[] = { .h_offset = 0x48, .h_pixels = 708, .v_max_out = 576, .h_max_out = 768, }, { - .name = "NTSC", .id = V4L2_STD_NTSC, + .name = "NTSC", .id = V4L2_STD_NTSC_M, .v_offset = 0x10, .v_field = 244, .h_offset = 0x40, .h_pixels = 708, .v_max_out = 480, .h_max_out = 640, @@ -880,7 +888,7 @@ static struct saa7146_standard analog_standard[] = { .h_offset = 0x08, .h_pixels = 708, .v_max_out = 576, .h_max_out = 768, }, { - .name = "NTSC", .id = V4L2_STD_NTSC, + .name = "NTSC", .id = V4L2_STD_NTSC_M, .v_offset = 0x10, .v_field = 244, .h_offset = 0x40, .h_pixels = 708, .v_max_out = 480, .h_max_out = 640, @@ -894,7 +902,7 @@ static struct saa7146_standard dvb_standard[] = { .h_offset = 0x48, .h_pixels = 708, .v_max_out = 576, .h_max_out = 768, }, { - .name = "NTSC", .id = V4L2_STD_NTSC, + .name = "NTSC", .id = V4L2_STD_NTSC_M, .v_offset = 0x10, .v_field = 244, .h_offset = 0x40, .h_pixels = 708, .v_max_out = 480, .h_max_out = 640, @@ -930,8 +938,6 @@ static struct saa7146_ext_vv av7110_vv_data_st = { .num_stds = ARRAY_SIZE(standard), .std_callback = &std_callback, - .vbi_fops.open = av7110_vbi_reset, - .vbi_fops.release = av7110_vbi_reset, .vbi_fops.write = av7110_vbi_write, }; @@ -945,8 +951,6 @@ static struct saa7146_ext_vv av7110_vv_data_c = { .num_stds = ARRAY_SIZE(standard), .std_callback = &std_callback, - .vbi_fops.open = av7110_vbi_reset, - .vbi_fops.release = av7110_vbi_reset, .vbi_fops.write = av7110_vbi_write, }; diff --git a/drivers/staging/media/deprecated/atmel/atmel-isc-base.c b/drivers/staging/media/deprecated/atmel/atmel-isc-base.c index 99e61bbfc9bc..61c5afa58142 100644 --- a/drivers/staging/media/deprecated/atmel/atmel-isc-base.c +++ b/drivers/staging/media/deprecated/atmel/atmel-isc-base.c @@ -824,8 +824,10 @@ static int isc_try_configure_pipeline(struct isc_device *isc) static void isc_try_fse(struct isc_device *isc, struct v4l2_subdev_state *sd_state) { + struct v4l2_subdev_frame_size_enum fse = { + .which = V4L2_SUBDEV_FORMAT_TRY, + }; int ret; - struct v4l2_subdev_frame_size_enum fse = {}; /* * If we do not know yet which format the subdev is using, we cannot @@ -835,7 +837,6 @@ static void isc_try_fse(struct isc_device *isc, return; fse.code = isc->try_config.sd_format->mbus_code; - fse.which = V4L2_SUBDEV_FORMAT_TRY; ret = v4l2_subdev_call(isc->current_subdev->sd, pad, enum_frame_size, sd_state, &fse); @@ -860,8 +861,8 @@ static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f, struct v4l2_pix_format *pixfmt = &f->fmt.pix; struct v4l2_subdev_pad_config pad_cfg = {}; struct v4l2_subdev_state pad_state = { - .pads = &pad_cfg - }; + .pads = &pad_cfg, + }; struct v4l2_subdev_format format = { .which = V4L2_SUBDEV_FORMAT_TRY, }; diff --git a/drivers/staging/media/deprecated/atmel/atmel-sama5d2-isc.c b/drivers/staging/media/deprecated/atmel/atmel-sama5d2-isc.c index ba0614f981a2..cc86ebcc76af 100644 --- a/drivers/staging/media/deprecated/atmel/atmel-sama5d2-isc.c +++ b/drivers/staging/media/deprecated/atmel/atmel-sama5d2-isc.c @@ -389,7 +389,6 @@ static int atmel_isc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct isc_device *isc; - struct resource *res; void __iomem *io_base; struct isc_subdev_entity *subdev_entity; int irq; @@ -403,8 +402,7 @@ static int atmel_isc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, isc); isc->dev = dev; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - io_base = devm_ioremap_resource(dev, res); + io_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(io_base)) return PTR_ERR(io_base); @@ -580,7 +578,7 @@ unprepare_hclk: return ret; } -static int atmel_isc_remove(struct platform_device *pdev) +static void atmel_isc_remove(struct platform_device *pdev) { struct isc_device *isc = platform_get_drvdata(pdev); @@ -594,8 +592,6 @@ static int atmel_isc_remove(struct platform_device *pdev) clk_disable_unprepare(isc->hclock); atmel_isc_clk_cleanup(isc); - - return 0; } static int __maybe_unused isc_runtime_suspend(struct device *dev) @@ -638,7 +634,7 @@ MODULE_DEVICE_TABLE(of, atmel_isc_of_match); static struct platform_driver atmel_isc_driver = { .probe = atmel_isc_probe, - .remove = atmel_isc_remove, + .remove_new = atmel_isc_remove, .driver = { .name = "atmel-sama5d2-isc", .pm = &atmel_isc_dev_pm_ops, diff --git a/drivers/staging/media/deprecated/atmel/atmel-sama7g5-isc.c b/drivers/staging/media/deprecated/atmel/atmel-sama7g5-isc.c index 01ababdfcbd9..68ef3374d25e 100644 --- a/drivers/staging/media/deprecated/atmel/atmel-sama7g5-isc.c +++ b/drivers/staging/media/deprecated/atmel/atmel-sama7g5-isc.c @@ -378,7 +378,6 @@ static int microchip_xisc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct isc_device *isc; - struct resource *res; void __iomem *io_base; struct isc_subdev_entity *subdev_entity; int irq; @@ -392,8 +391,7 @@ static int microchip_xisc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, isc); isc->dev = dev; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - io_base = devm_ioremap_resource(dev, res); + io_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(io_base)) return PTR_ERR(io_base); @@ -549,7 +547,7 @@ unprepare_hclk: return ret; } -static int microchip_xisc_remove(struct platform_device *pdev) +static void microchip_xisc_remove(struct platform_device *pdev) { struct isc_device *isc = platform_get_drvdata(pdev); @@ -562,8 +560,6 @@ static int microchip_xisc_remove(struct platform_device *pdev) clk_disable_unprepare(isc->hclock); atmel_isc_clk_cleanup(isc); - - return 0; } static int __maybe_unused xisc_runtime_suspend(struct device *dev) @@ -601,7 +597,7 @@ MODULE_DEVICE_TABLE(of, microchip_xisc_of_match); static struct platform_driver microchip_xisc_driver = { .probe = microchip_xisc_probe, - .remove = microchip_xisc_remove, + .remove_new = microchip_xisc_remove, .driver = { .name = "microchip-sama7g5-xisc", .pm = µchip_xisc_dev_pm_ops, diff --git a/drivers/staging/media/imx/imx-media-capture.c b/drivers/staging/media/imx/imx-media-capture.c index 93ba09236010..4364df27c6d2 100644 --- a/drivers/staging/media/imx/imx-media-capture.c +++ b/drivers/staging/media/imx/imx-media-capture.c @@ -353,12 +353,13 @@ static int capture_legacy_enum_fmt_vid_cap(struct file *file, void *fh, { struct capture_priv *priv = video_drvdata(file); const struct imx_media_pixfmt *cc_src; - struct v4l2_subdev_format fmt_src; + struct v4l2_subdev_format fmt_src = { + .pad = priv->src_sd_pad, + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; u32 fourcc; int ret; - fmt_src.pad = priv->src_sd_pad; - fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE; ret = v4l2_subdev_call(priv->src_sd, pad, get_fmt, NULL, &fmt_src); if (ret) { dev_err(priv->dev, "failed to get src_sd format\n"); @@ -426,11 +427,12 @@ static int capture_legacy_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) { struct capture_priv *priv = video_drvdata(file); - struct v4l2_subdev_format fmt_src; + struct v4l2_subdev_format fmt_src = { + .pad = priv->src_sd_pad, + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; int ret; - fmt_src.pad = priv->src_sd_pad; - fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE; ret = v4l2_subdev_call(priv->src_sd, pad, get_fmt, NULL, &fmt_src); if (ret) return ret; @@ -445,7 +447,10 @@ static int capture_legacy_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) { struct capture_priv *priv = video_drvdata(file); - struct v4l2_subdev_format fmt_src; + struct v4l2_subdev_format fmt_src = { + .pad = priv->src_sd_pad, + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; const struct imx_media_pixfmt *cc; int ret; @@ -454,8 +459,6 @@ static int capture_legacy_s_fmt_vid_cap(struct file *file, void *fh, return -EBUSY; } - fmt_src.pad = priv->src_sd_pad; - fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE; ret = v4l2_subdev_call(priv->src_sd, pad, get_fmt, NULL, &fmt_src); if (ret) return ret; @@ -501,14 +504,14 @@ static int capture_legacy_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a) { struct capture_priv *priv = video_drvdata(file); - struct v4l2_subdev_frame_interval fi; + struct v4l2_subdev_frame_interval fi = { + .pad = priv->src_sd_pad, + }; int ret; if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - memset(&fi, 0, sizeof(fi)); - fi.pad = priv->src_sd_pad; ret = v4l2_subdev_call(priv->src_sd, video, g_frame_interval, &fi); if (ret < 0) return ret; @@ -523,14 +526,14 @@ static int capture_legacy_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) { struct capture_priv *priv = video_drvdata(file); - struct v4l2_subdev_frame_interval fi; + struct v4l2_subdev_frame_interval fi = { + .pad = priv->src_sd_pad, + }; int ret; if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - memset(&fi, 0, sizeof(fi)); - fi.pad = priv->src_sd_pad; fi.interval = a->parm.capture.timeperframe; ret = v4l2_subdev_call(priv->src_sd, video, s_frame_interval, &fi); if (ret < 0) @@ -670,13 +673,14 @@ static void capture_buf_queue(struct vb2_buffer *vb) static int capture_validate_fmt(struct capture_priv *priv) { - struct v4l2_subdev_format fmt_src; + struct v4l2_subdev_format fmt_src = { + .pad = priv->src_sd_pad, + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; const struct imx_media_pixfmt *cc; int ret; /* Retrieve the media bus format on the source subdev. */ - fmt_src.pad = priv->src_sd_pad; - fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE; ret = v4l2_subdev_call(priv->src_sd, pad, get_fmt, NULL, &fmt_src); if (ret) return ret; diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index 44d87fe30d52..097171bb930d 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -2041,7 +2041,7 @@ free: return ret; } -static int imx_csi_remove(struct platform_device *pdev) +static void imx_csi_remove(struct platform_device *pdev) { struct v4l2_subdev *sd = platform_get_drvdata(pdev); struct csi_priv *priv = sd_to_dev(sd); @@ -2052,8 +2052,6 @@ static int imx_csi_remove(struct platform_device *pdev) v4l2_async_nf_cleanup(&priv->notifier); v4l2_async_unregister_subdev(sd); media_entity_cleanup(&sd->entity); - - return 0; } static const struct platform_device_id imx_csi_ids[] = { @@ -2064,7 +2062,7 @@ MODULE_DEVICE_TABLE(platform, imx_csi_ids); static struct platform_driver imx_csi_driver = { .probe = imx_csi_probe, - .remove = imx_csi_remove, + .remove_new = imx_csi_remove, .id_table = imx_csi_ids, .driver = { .name = "imx-ipuv3-csi", diff --git a/drivers/staging/media/imx/imx-media-dev-common.c b/drivers/staging/media/imx/imx-media-dev-common.c index e6d6ed3b1161..991820a8500f 100644 --- a/drivers/staging/media/imx/imx-media-dev-common.c +++ b/drivers/staging/media/imx/imx-media-dev-common.c @@ -19,18 +19,6 @@ static inline struct imx_media_dev *notifier2dev(struct v4l2_async_notifier *n) return container_of(n, struct imx_media_dev, notifier); } -/* async subdev bound notifier */ -static int imx_media_subdev_bound(struct v4l2_async_notifier *notifier, - struct v4l2_subdev *sd, - struct v4l2_async_subdev *asd) -{ - struct imx_media_dev *imxmd = notifier2dev(notifier); - - dev_dbg(imxmd->md.dev, "subdev %s bound\n", sd->name); - - return 0; -} - /* * Create the missing media links from the CSI-2 receiver. * Called after all async subdevs have bound. @@ -51,7 +39,6 @@ static void imx_media_create_csi2_links(struct imx_media_dev *imxmd) list_for_each_entry(sd, &imxmd->v4l2_dev.subdevs, list) { /* skip if not a CSI or a CSI mux */ if (!(sd->grp_id & IMX_MEDIA_GRP_ID_IPU_CSI) && - !(sd->grp_id & IMX_MEDIA_GRP_ID_CSI) && !(sd->grp_id & IMX_MEDIA_GRP_ID_CSI_MUX)) continue; @@ -337,7 +324,6 @@ static void imx_media_notify(struct v4l2_subdev *sd, unsigned int notification, } static const struct v4l2_async_notifier_operations imx_media_notifier_ops = { - .bound = imx_media_subdev_bound, .complete = imx_media_probe_complete, }; diff --git a/drivers/staging/media/imx/imx-media-dev.c b/drivers/staging/media/imx/imx-media-dev.c index f85462214e22..c80113905069 100644 --- a/drivers/staging/media/imx/imx-media-dev.c +++ b/drivers/staging/media/imx/imx-media-dev.c @@ -101,7 +101,7 @@ cleanup: return ret; } -static int imx_media_remove(struct platform_device *pdev) +static void imx_media_remove(struct platform_device *pdev) { struct imx_media_dev *imxmd = (struct imx_media_dev *)platform_get_drvdata(pdev); @@ -119,8 +119,6 @@ static int imx_media_remove(struct platform_device *pdev) media_device_unregister(&imxmd->md); v4l2_device_unregister(&imxmd->v4l2_dev); media_device_cleanup(&imxmd->md); - - return 0; } static const struct of_device_id imx_media_dt_ids[] = { @@ -131,7 +129,7 @@ MODULE_DEVICE_TABLE(of, imx_media_dt_ids); static struct platform_driver imx_media_pdrv = { .probe = imx_media_probe, - .remove = imx_media_remove, + .remove_new = imx_media_remove, .driver = { .name = "imx-media", .of_match_table = imx_media_dt_ids, diff --git a/drivers/staging/media/imx/imx-media-of.c b/drivers/staging/media/imx/imx-media-of.c index 59f1eb7b62bc..92a99010c150 100644 --- a/drivers/staging/media/imx/imx-media-of.c +++ b/drivers/staging/media/imx/imx-media-of.c @@ -16,8 +16,8 @@ #include <video/imx-ipu-v3.h> #include "imx-media.h" -int imx_media_of_add_csi(struct imx_media_dev *imxmd, - struct device_node *csi_np) +static int imx_media_of_add_csi(struct imx_media_dev *imxmd, + struct device_node *csi_np) { struct v4l2_async_subdev *asd; int ret = 0; @@ -41,7 +41,6 @@ int imx_media_of_add_csi(struct imx_media_dev *imxmd, return ret; } -EXPORT_SYMBOL_GPL(imx_media_of_add_csi); int imx_media_add_of_subdevs(struct imx_media_dev *imxmd, struct device_node *np) diff --git a/drivers/staging/media/imx/imx-media-utils.c b/drivers/staging/media/imx/imx-media-utils.c index 411e907b68eb..2d712eda2c5d 100644 --- a/drivers/staging/media/imx/imx-media-utils.c +++ b/drivers/staging/media/imx/imx-media-utils.c @@ -432,15 +432,15 @@ int imx_media_init_cfg(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state) { struct v4l2_mbus_framefmt *mf_try; - struct v4l2_subdev_format format; unsigned int pad; int ret; for (pad = 0; pad < sd->entity.num_pads; pad++) { - memset(&format, 0, sizeof(format)); + struct v4l2_subdev_format format = { + .pad = pad, + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; - format.pad = pad; - format.which = V4L2_SUBDEV_FORMAT_ACTIVE; ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &format); if (ret) continue; @@ -626,36 +626,6 @@ void imx_media_grp_id_to_sd_name(char *sd_name, int sz, u32 grp_id, int ipu_id) } EXPORT_SYMBOL_GPL(imx_media_grp_id_to_sd_name); -struct v4l2_subdev * -imx_media_find_subdev_by_fwnode(struct imx_media_dev *imxmd, - struct fwnode_handle *fwnode) -{ - struct v4l2_subdev *sd; - - list_for_each_entry(sd, &imxmd->v4l2_dev.subdevs, list) { - if (sd->fwnode == fwnode) - return sd; - } - - return NULL; -} -EXPORT_SYMBOL_GPL(imx_media_find_subdev_by_fwnode); - -struct v4l2_subdev * -imx_media_find_subdev_by_devname(struct imx_media_dev *imxmd, - const char *devname) -{ - struct v4l2_subdev *sd; - - list_for_each_entry(sd, &imxmd->v4l2_dev.subdevs, list) { - if (!strcmp(devname, dev_name(sd->dev))) - return sd; - } - - return NULL; -} -EXPORT_SYMBOL_GPL(imx_media_find_subdev_by_devname); - /* * Adds a video device to the master video device list. This is called * when a video device is registered. @@ -757,25 +727,6 @@ find_pipeline_entity(struct media_entity *start, u32 grp_id, } /* - * Find the upstream mipi-csi2 virtual channel reached from the given - * start entity in the current pipeline. - * Must be called with mdev->graph_mutex held. - */ -int imx_media_pipeline_csi2_channel(struct media_entity *start_entity) -{ - struct media_pad *pad; - int ret = -EPIPE; - - pad = imx_media_pipeline_pad(start_entity, IMX_MEDIA_GRP_ID_CSI2, - 0, true); - if (pad) - ret = pad->index - 1; - - return ret; -} -EXPORT_SYMBOL_GPL(imx_media_pipeline_csi2_channel); - -/* * Find a subdev reached upstream from the given start entity in * the current pipeline. * Must be called with mdev->graph_mutex held. @@ -795,25 +746,6 @@ imx_media_pipeline_subdev(struct media_entity *start_entity, u32 grp_id, EXPORT_SYMBOL_GPL(imx_media_pipeline_subdev); /* - * Find a subdev reached upstream from the given start entity in - * the current pipeline. - * Must be called with mdev->graph_mutex held. - */ -struct video_device * -imx_media_pipeline_video_device(struct media_entity *start_entity, - enum v4l2_buf_type buftype, bool upstream) -{ - struct media_entity *me; - - me = find_pipeline_entity(start_entity, 0, buftype, upstream); - if (!me) - return ERR_PTR(-ENODEV); - - return media_entity_to_video_device(me); -} -EXPORT_SYMBOL_GPL(imx_media_pipeline_video_device); - -/* * Turn current pipeline streaming on/off starting from entity. */ int imx_media_pipeline_set_stream(struct imx_media_dev *imxmd, diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h index 6f9a46573edd..2640cd34dce2 100644 --- a/drivers/staging/media/imx/imx-media.h +++ b/drivers/staging/media/imx/imx-media.h @@ -201,24 +201,14 @@ int imx_media_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix, const struct imx_media_pixfmt *cc); void imx_media_grp_id_to_sd_name(char *sd_name, int sz, u32 grp_id, int ipu_id); -struct v4l2_subdev * -imx_media_find_subdev_by_fwnode(struct imx_media_dev *imxmd, - struct fwnode_handle *fwnode); -struct v4l2_subdev * -imx_media_find_subdev_by_devname(struct imx_media_dev *imxmd, - const char *devname); void imx_media_add_video_device(struct imx_media_dev *imxmd, struct imx_media_video_dev *vdev); -int imx_media_pipeline_csi2_channel(struct media_entity *start_entity); struct media_pad * imx_media_pipeline_pad(struct media_entity *start_entity, u32 grp_id, enum v4l2_buf_type buftype, bool upstream); struct v4l2_subdev * imx_media_pipeline_subdev(struct media_entity *start_entity, u32 grp_id, bool upstream); -struct video_device * -imx_media_pipeline_video_device(struct media_entity *start_entity, - enum v4l2_buf_type buftype, bool upstream); struct imx_media_dma_buf { void *virt; @@ -261,8 +251,6 @@ void imx_media_unregister_ipu_internal_subdevs(struct imx_media_dev *imxmd); /* imx-media-of.c */ int imx_media_add_of_subdevs(struct imx_media_dev *dev, struct device_node *np); -int imx_media_of_add_csi(struct imx_media_dev *imxmd, - struct device_node *csi_np); /* imx-media-vdic.c */ struct v4l2_subdev *imx_media_vdic_register(struct v4l2_device *v4l2_dev, @@ -298,7 +286,6 @@ void imx_media_csc_scaler_device_unregister(struct imx_media_video_dev *vdev); /* subdev group ids */ #define IMX_MEDIA_GRP_ID_CSI2 BIT(8) -#define IMX_MEDIA_GRP_ID_CSI BIT(9) #define IMX_MEDIA_GRP_ID_IPU_CSI_BIT 10 #define IMX_MEDIA_GRP_ID_IPU_CSI (0x3 << IMX_MEDIA_GRP_ID_IPU_CSI_BIT) #define IMX_MEDIA_GRP_ID_IPU_CSI0 BIT(IMX_MEDIA_GRP_ID_IPU_CSI_BIT) diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c index c4cb558a85c6..c07994ea6e96 100644 --- a/drivers/staging/media/imx/imx6-mipi-csi2.c +++ b/drivers/staging/media/imx/imx6-mipi-csi2.c @@ -765,7 +765,7 @@ rmmutex: return ret; } -static int csi2_remove(struct platform_device *pdev) +static void csi2_remove(struct platform_device *pdev) { struct v4l2_subdev *sd = platform_get_drvdata(pdev); struct csi2_dev *csi2 = sd_to_dev(sd); @@ -777,8 +777,6 @@ static int csi2_remove(struct platform_device *pdev) clk_disable_unprepare(csi2->pllref_clk); mutex_destroy(&csi2->lock); media_entity_cleanup(&sd->entity); - - return 0; } static const struct of_device_id csi2_dt_ids[] = { @@ -793,7 +791,7 @@ static struct platform_driver csi2_driver = { .of_match_table = csi2_dt_ids, }, .probe = csi2_probe, - .remove = csi2_remove, + .remove_new = csi2_remove, }; module_platform_driver(csi2_driver); diff --git a/drivers/staging/media/imx/imx8mq-mipi-csi2.c b/drivers/staging/media/imx/imx8mq-mipi-csi2.c index 83194328d010..32700cb8bc4d 100644 --- a/drivers/staging/media/imx/imx8mq-mipi-csi2.c +++ b/drivers/staging/media/imx/imx8mq-mipi-csi2.c @@ -119,11 +119,8 @@ struct csi_state { struct v4l2_mbus_config_mipi_csi2 bus; - struct mutex lock; /* Protect csi2_fmt, format_mbus, state, hs_settle */ - const struct csi2_pix_format *csi2_fmt; - struct v4l2_mbus_framefmt format_mbus[MIPI_CSI2_PADS_NUM]; + struct mutex lock; /* Protect state */ u32 state; - u32 hs_settle; struct regmap *phy_gpr; u8 phy_gpr_reg; @@ -248,23 +245,6 @@ static int imx8mq_mipi_csi_sw_reset(struct csi_state *state) return 0; } -static void imx8mq_mipi_csi_system_enable(struct csi_state *state, int on) -{ - if (!on) { - imx8mq_mipi_csi_write(state, CSI2RX_CFG_DISABLE_DATA_LANES, 0xf); - return; - } - - regmap_update_bits(state->phy_gpr, - state->phy_gpr_reg, - 0x3fff, - GPR_CSI2_1_RX_ENABLE | - GPR_CSI2_1_VID_INTFC_ENB | - GPR_CSI2_1_HSEL | - GPR_CSI2_1_CONT_CLK_MODE | - GPR_CSI2_1_S_PRG_RXHS_SETTLE(state->hs_settle)); -} - static void imx8mq_mipi_csi_set_params(struct csi_state *state) { int lanes = state->bus.num_data_lanes; @@ -304,16 +284,24 @@ static int imx8mq_mipi_csi_clk_get(struct csi_state *state) return devm_clk_bulk_get(state->dev, CSI2_NUM_CLKS, state->clks); } -static int imx8mq_mipi_csi_calc_hs_settle(struct csi_state *state) +static int imx8mq_mipi_csi_calc_hs_settle(struct csi_state *state, + struct v4l2_subdev_state *sd_state, + u32 *hs_settle) { s64 link_freq; u32 lane_rate; unsigned long esc_clk_rate; u32 min_ths_settle, max_ths_settle, ths_settle_ns, esc_clk_period_ns; + const struct v4l2_mbus_framefmt *fmt; + const struct csi2_pix_format *csi2_fmt; /* Calculate the line rate from the pixel rate. */ + + fmt = v4l2_subdev_get_pad_format(&state->sd, sd_state, MIPI_CSI2_PAD_SINK); + csi2_fmt = find_csi2_format(fmt->code); + link_freq = v4l2_get_link_freq(state->src_sd->ctrl_handler, - state->csi2_fmt->width, + csi2_fmt->width, state->bus.num_data_lanes * 2); if (link_freq < 0) { dev_err(state->dev, "Unable to obtain link frequency: %d\n", @@ -354,35 +342,44 @@ static int imx8mq_mipi_csi_calc_hs_settle(struct csi_state *state) max_ths_settle = 140 + 10 * 1000000 / (lane_rate / 1000); ths_settle_ns = (min_ths_settle + max_ths_settle) / 2; - state->hs_settle = ths_settle_ns / esc_clk_period_ns - 1; + *hs_settle = ths_settle_ns / esc_clk_period_ns - 1; dev_dbg(state->dev, "lane rate %u Ths_settle %u hs_settle %u\n", - lane_rate, ths_settle_ns, state->hs_settle); + lane_rate, ths_settle_ns, *hs_settle); return 0; } -static int imx8mq_mipi_csi_start_stream(struct csi_state *state) +static int imx8mq_mipi_csi_start_stream(struct csi_state *state, + struct v4l2_subdev_state *sd_state) { int ret; + u32 hs_settle; ret = imx8mq_mipi_csi_sw_reset(state); if (ret) return ret; imx8mq_mipi_csi_set_params(state); - ret = imx8mq_mipi_csi_calc_hs_settle(state); + ret = imx8mq_mipi_csi_calc_hs_settle(state, sd_state, &hs_settle); if (ret) return ret; - imx8mq_mipi_csi_system_enable(state, true); + regmap_update_bits(state->phy_gpr, + state->phy_gpr_reg, + 0x3fff, + GPR_CSI2_1_RX_ENABLE | + GPR_CSI2_1_VID_INTFC_ENB | + GPR_CSI2_1_HSEL | + GPR_CSI2_1_CONT_CLK_MODE | + GPR_CSI2_1_S_PRG_RXHS_SETTLE(hs_settle)); return 0; } static void imx8mq_mipi_csi_stop_stream(struct csi_state *state) { - imx8mq_mipi_csi_system_enable(state, false); + imx8mq_mipi_csi_write(state, CSI2RX_CFG_DISABLE_DATA_LANES, 0xf); } /* ----------------------------------------------------------------------------- @@ -397,6 +394,7 @@ static struct csi_state *mipi_sd_to_csi2_state(struct v4l2_subdev *sdev) static int imx8mq_mipi_csi_s_stream(struct v4l2_subdev *sd, int enable) { struct csi_state *state = mipi_sd_to_csi2_state(sd); + struct v4l2_subdev_state *sd_state; int ret = 0; if (enable) { @@ -413,7 +411,10 @@ static int imx8mq_mipi_csi_s_stream(struct v4l2_subdev *sd, int enable) goto unlock; } - ret = imx8mq_mipi_csi_start_stream(state); + sd_state = v4l2_subdev_lock_and_get_active_state(sd); + ret = imx8mq_mipi_csi_start_stream(state, sd_state); + v4l2_subdev_unlock_state(sd_state); + if (ret < 0) goto unlock; @@ -437,29 +438,14 @@ unlock: return ret; } -static struct v4l2_mbus_framefmt * -imx8mq_mipi_csi_get_format(struct csi_state *state, - struct v4l2_subdev_state *sd_state, - enum v4l2_subdev_format_whence which, - unsigned int pad) -{ - if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&state->sd, sd_state, pad); - - return &state->format_mbus[pad]; -} - static int imx8mq_mipi_csi_init_cfg(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state) { - struct csi_state *state = mipi_sd_to_csi2_state(sd); struct v4l2_mbus_framefmt *fmt_sink; struct v4l2_mbus_framefmt *fmt_source; - enum v4l2_subdev_format_whence which; - which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - fmt_sink = imx8mq_mipi_csi_get_format(state, sd_state, which, - MIPI_CSI2_PAD_SINK); + fmt_sink = v4l2_subdev_get_pad_format(sd, sd_state, MIPI_CSI2_PAD_SINK); + fmt_source = v4l2_subdev_get_pad_format(sd, sd_state, MIPI_CSI2_PAD_SOURCE); fmt_sink->code = MEDIA_BUS_FMT_SGBRG10_1X10; fmt_sink->width = MIPI_CSI2_DEF_PIX_WIDTH; @@ -473,38 +459,15 @@ static int imx8mq_mipi_csi_init_cfg(struct v4l2_subdev *sd, V4L2_MAP_QUANTIZATION_DEFAULT(false, fmt_sink->colorspace, fmt_sink->ycbcr_enc); - fmt_source = imx8mq_mipi_csi_get_format(state, sd_state, which, - MIPI_CSI2_PAD_SOURCE); *fmt_source = *fmt_sink; return 0; } -static int imx8mq_mipi_csi_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *sdformat) -{ - struct csi_state *state = mipi_sd_to_csi2_state(sd); - struct v4l2_mbus_framefmt *fmt; - - fmt = imx8mq_mipi_csi_get_format(state, sd_state, sdformat->which, - sdformat->pad); - - mutex_lock(&state->lock); - - sdformat->format = *fmt; - - mutex_unlock(&state->lock); - - return 0; -} - static int imx8mq_mipi_csi_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { - struct csi_state *state = mipi_sd_to_csi2_state(sd); - /* * We can't transcode in any way, the source format is identical * to the sink format. @@ -515,8 +478,7 @@ static int imx8mq_mipi_csi_enum_mbus_code(struct v4l2_subdev *sd, if (code->index > 0) return -EINVAL; - fmt = imx8mq_mipi_csi_get_format(state, sd_state, code->which, - code->pad); + fmt = v4l2_subdev_get_pad_format(sd, sd_state, code->pad); code->code = fmt->code; return 0; } @@ -536,8 +498,7 @@ static int imx8mq_mipi_csi_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { - struct csi_state *state = mipi_sd_to_csi2_state(sd); - struct csi2_pix_format const *csi2_fmt; + const struct csi2_pix_format *csi2_fmt; struct v4l2_mbus_framefmt *fmt; /* @@ -545,7 +506,7 @@ static int imx8mq_mipi_csi_set_fmt(struct v4l2_subdev *sd, * modified. */ if (sdformat->pad == MIPI_CSI2_PAD_SOURCE) - return imx8mq_mipi_csi_get_fmt(sd, sd_state, sdformat); + return v4l2_subdev_get_fmt(sd, sd_state, sdformat); if (sdformat->pad != MIPI_CSI2_PAD_SINK) return -EINVAL; @@ -554,10 +515,7 @@ static int imx8mq_mipi_csi_set_fmt(struct v4l2_subdev *sd, if (!csi2_fmt) csi2_fmt = &imx8mq_mipi_csi_formats[0]; - fmt = imx8mq_mipi_csi_get_format(state, sd_state, sdformat->which, - sdformat->pad); - - mutex_lock(&state->lock); + fmt = v4l2_subdev_get_pad_format(sd, sd_state, sdformat->pad); fmt->code = csi2_fmt->code; fmt->width = sdformat->format.width; @@ -566,16 +524,9 @@ static int imx8mq_mipi_csi_set_fmt(struct v4l2_subdev *sd, sdformat->format = *fmt; /* Propagate the format from sink to source. */ - fmt = imx8mq_mipi_csi_get_format(state, sd_state, sdformat->which, - MIPI_CSI2_PAD_SOURCE); + fmt = v4l2_subdev_get_pad_format(sd, sd_state, MIPI_CSI2_PAD_SOURCE); *fmt = sdformat->format; - /* Store the CSI2 format descriptor for active formats. */ - if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE) - state->csi2_fmt = csi2_fmt; - - mutex_unlock(&state->lock); - return 0; } @@ -586,7 +537,7 @@ static const struct v4l2_subdev_video_ops imx8mq_mipi_csi_video_ops = { static const struct v4l2_subdev_pad_ops imx8mq_mipi_csi_pad_ops = { .init_cfg = imx8mq_mipi_csi_init_cfg, .enum_mbus_code = imx8mq_mipi_csi_enum_mbus_code, - .get_fmt = imx8mq_mipi_csi_get_fmt, + .get_fmt = v4l2_subdev_get_fmt, .set_fmt = imx8mq_mipi_csi_set_fmt, }; @@ -714,6 +665,7 @@ static int imx8mq_mipi_csi_pm_resume(struct device *dev) { struct v4l2_subdev *sd = dev_get_drvdata(dev); struct csi_state *state = mipi_sd_to_csi2_state(sd); + struct v4l2_subdev_state *sd_state; int ret = 0; mutex_lock(&state->lock); @@ -723,7 +675,9 @@ static int imx8mq_mipi_csi_pm_resume(struct device *dev) ret = imx8mq_mipi_csi_clk_enable(state); } if (state->state & ST_STREAMING) { - ret = imx8mq_mipi_csi_start_stream(state); + sd_state = v4l2_subdev_lock_and_get_active_state(sd); + ret = imx8mq_mipi_csi_start_stream(state, sd_state); + v4l2_subdev_unlock_state(sd_state); if (ret) goto unlock; } @@ -803,6 +757,7 @@ static const struct dev_pm_ops imx8mq_mipi_csi_pm_ops = { static int imx8mq_mipi_csi_subdev_init(struct csi_state *state) { struct v4l2_subdev *sd = &state->sd; + int ret; v4l2_subdev_init(sd, &imx8mq_mipi_csi_subdev_ops); sd->owner = THIS_MODULE; @@ -816,15 +771,22 @@ static int imx8mq_mipi_csi_subdev_init(struct csi_state *state) sd->dev = state->dev; - state->csi2_fmt = &imx8mq_mipi_csi_formats[0]; - imx8mq_mipi_csi_init_cfg(sd, NULL); - state->pads[MIPI_CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT; state->pads[MIPI_CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE | MEDIA_PAD_FL_MUST_CONNECT; - return media_entity_pads_init(&sd->entity, MIPI_CSI2_PADS_NUM, - state->pads); + ret = media_entity_pads_init(&sd->entity, MIPI_CSI2_PADS_NUM, + state->pads); + if (ret) + return ret; + + ret = v4l2_subdev_init_finalize(sd); + if (ret) { + media_entity_cleanup(&sd->entity); + return ret; + } + + return 0; } static void imx8mq_mipi_csi_release_icc(struct platform_device *pdev) @@ -950,6 +912,7 @@ cleanup: imx8mq_mipi_csi_runtime_suspend(&pdev->dev); media_entity_cleanup(&state->sd.entity); + v4l2_subdev_cleanup(&state->sd); v4l2_async_nf_unregister(&state->notifier); v4l2_async_nf_cleanup(&state->notifier); v4l2_async_unregister_subdev(&state->sd); @@ -961,7 +924,7 @@ mutex: return ret; } -static int imx8mq_mipi_csi_remove(struct platform_device *pdev) +static void imx8mq_mipi_csi_remove(struct platform_device *pdev) { struct v4l2_subdev *sd = platform_get_drvdata(pdev); struct csi_state *state = mipi_sd_to_csi2_state(sd); @@ -973,11 +936,10 @@ static int imx8mq_mipi_csi_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); imx8mq_mipi_csi_runtime_suspend(&pdev->dev); media_entity_cleanup(&state->sd.entity); + v4l2_subdev_cleanup(&state->sd); mutex_destroy(&state->lock); pm_runtime_set_suspended(&pdev->dev); imx8mq_mipi_csi_release_icc(pdev); - - return 0; } static const struct of_device_id imx8mq_mipi_csi_of_match[] = { @@ -988,7 +950,7 @@ MODULE_DEVICE_TABLE(of, imx8mq_mipi_csi_of_match); static struct platform_driver imx8mq_mipi_csi_driver = { .probe = imx8mq_mipi_csi_probe, - .remove = imx8mq_mipi_csi_remove, + .remove_new = imx8mq_mipi_csi_remove, .driver = { .of_match_table = imx8mq_mipi_csi_of_match, .name = MIPI_CSI2_DRIVER_NAME, diff --git a/drivers/staging/media/meson/vdec/vdec.c b/drivers/staging/media/meson/vdec/vdec.c index 52f224d8def1..5ca4b1200831 100644 --- a/drivers/staging/media/meson/vdec/vdec.c +++ b/drivers/staging/media/meson/vdec/vdec.c @@ -1106,19 +1106,17 @@ err_vdev_release: return ret; } -static int vdec_remove(struct platform_device *pdev) +static void vdec_remove(struct platform_device *pdev) { struct amvdec_core *core = platform_get_drvdata(pdev); video_unregister_device(core->vdev_dec); v4l2_device_unregister(&core->v4l2_dev); - - return 0; } static struct platform_driver meson_vdec_driver = { .probe = vdec_probe, - .remove = vdec_remove, + .remove_new = vdec_remove, .driver = { .name = "meson-vdec", .of_match_table = vdec_dt_match, diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index fa2a36d829d3..0c4283bb48ad 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -1323,15 +1323,13 @@ error: return ret; } -static int iss_remove(struct platform_device *pdev) +static void iss_remove(struct platform_device *pdev) { struct iss_device *iss = platform_get_drvdata(pdev); iss_unregister_entities(iss); media_entity_enum_cleanup(&iss->crashed); iss_cleanup_modules(iss); - - return 0; } static const struct platform_device_id omap4iss_id_table[] = { @@ -1342,7 +1340,7 @@ MODULE_DEVICE_TABLE(platform, omap4iss_id_table); static struct platform_driver iss_driver = { .probe = iss_probe, - .remove = iss_remove, + .remove_new = iss_remove, .id_table = omap4iss_id_table, .driver = { .name = "omap4iss", diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index 05548eab7daa..22fa4d6cae10 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -237,7 +237,9 @@ static int __iss_video_get_format(struct iss_video *video, struct v4l2_mbus_framefmt *format) { - struct v4l2_subdev_format fmt; + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; struct v4l2_subdev *subdev; u32 pad; int ret; @@ -246,9 +248,7 @@ __iss_video_get_format(struct iss_video *video, if (!subdev) return -EINVAL; - memset(&fmt, 0, sizeof(fmt)); fmt.pad = pad; - fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; mutex_lock(&video->mutex); ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt); @@ -610,7 +610,9 @@ static int iss_video_try_format(struct file *file, void *fh, struct v4l2_format *format) { struct iss_video *video = video_drvdata(file); - struct v4l2_subdev_format fmt; + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; struct v4l2_subdev *subdev; u32 pad; int ret; @@ -625,7 +627,6 @@ iss_video_try_format(struct file *file, void *fh, struct v4l2_format *format) iss_video_pix_to_mbus(&format->fmt.pix, &fmt.format); fmt.pad = pad; - fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt); if (ret) return ret; @@ -638,7 +639,9 @@ static int iss_video_get_selection(struct file *file, void *fh, struct v4l2_selection *sel) { struct iss_video *video = video_drvdata(file); - struct v4l2_subdev_format format; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; struct v4l2_subdev *subdev; struct v4l2_subdev_selection sdsel = { .which = V4L2_SUBDEV_FORMAT_ACTIVE, @@ -679,7 +682,6 @@ iss_video_get_selection(struct file *file, void *fh, struct v4l2_selection *sel) return ret; format.pad = pad; - format.which = V4L2_SUBDEV_FORMAT_ACTIVE; ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &format); if (ret < 0) return ret == -ENOIOCTLCMD ? -ENOTTY : ret; diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c index 7bab7586918c..134e2b9fa7d9 100644 --- a/drivers/staging/media/rkvdec/rkvdec.c +++ b/drivers/staging/media/rkvdec/rkvdec.c @@ -1062,14 +1062,15 @@ err_disable_runtime_pm: return ret; } -static int rkvdec_remove(struct platform_device *pdev) +static void rkvdec_remove(struct platform_device *pdev) { struct rkvdec_dev *rkvdec = platform_get_drvdata(pdev); + cancel_delayed_work_sync(&rkvdec->watchdog_work); + rkvdec_v4l2_cleanup(rkvdec); pm_runtime_disable(&pdev->dev); pm_runtime_dont_use_autosuspend(&pdev->dev); - return 0; } #ifdef CONFIG_PM @@ -1099,7 +1100,7 @@ static const struct dev_pm_ops rkvdec_pm_ops = { static struct platform_driver rkvdec_driver = { .probe = rkvdec_probe, - .remove = rkvdec_remove, + .remove_new = rkvdec_remove, .driver = { .name = "rkvdec", .of_match_table = of_rkvdec_match, diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c index a43d5ff66716..8e248d4a0aec 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c @@ -543,10 +543,11 @@ err_v4l2: return ret; } -static int cedrus_remove(struct platform_device *pdev) +static void cedrus_remove(struct platform_device *pdev) { struct cedrus_dev *dev = platform_get_drvdata(pdev); + cancel_delayed_work_sync(&dev->watchdog_work); if (media_devnode_is_registered(dev->mdev.devnode)) { media_device_unregister(&dev->mdev); v4l2_m2m_unregister_media_controller(dev->m2m_dev); @@ -558,8 +559,6 @@ static int cedrus_remove(struct platform_device *pdev) v4l2_device_unregister(&dev->v4l2_dev); cedrus_hw_remove(dev); - - return 0; } static const struct cedrus_variant sun4i_a10_cedrus_variant = { @@ -706,7 +705,7 @@ static const struct dev_pm_ops cedrus_dev_pm_ops = { static struct platform_driver cedrus_driver = { .probe = cedrus_probe, - .remove = cedrus_remove, + .remove_new = cedrus_remove, .driver = { .name = CEDRUS_NAME, .of_match_table = of_match_ptr(cedrus_dt_match), diff --git a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp.c b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp.c index 7b7947509b69..0dc75adbd9d8 100644 --- a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp.c +++ b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp.c @@ -493,7 +493,7 @@ error_resources: return ret; } -static int sun6i_isp_remove(struct platform_device *platform_dev) +static void sun6i_isp_remove(struct platform_device *platform_dev) { struct sun6i_isp_device *isp_dev = platform_get_drvdata(platform_dev); @@ -503,8 +503,6 @@ static int sun6i_isp_remove(struct platform_device *platform_dev) sun6i_isp_v4l2_cleanup(isp_dev); sun6i_isp_tables_cleanup(isp_dev); sun6i_isp_resources_cleanup(isp_dev); - - return 0; } /* @@ -540,7 +538,7 @@ MODULE_DEVICE_TABLE(of, sun6i_isp_of_match); static struct platform_driver sun6i_isp_platform_driver = { .probe = sun6i_isp_probe, - .remove = sun6i_isp_remove, + .remove_new = sun6i_isp_remove, .driver = { .name = SUN6I_ISP_NAME, .of_match_table = of_match_ptr(sun6i_isp_of_match), diff --git a/drivers/staging/media/tegra-video/vi.c b/drivers/staging/media/tegra-video/vi.c index 26f7aedce718..2f1aff7e8717 100644 --- a/drivers/staging/media/tegra-video/vi.c +++ b/drivers/staging/media/tegra-video/vi.c @@ -493,7 +493,9 @@ static int __tegra_channel_try_format(struct tegra_vi_channel *chan, const struct tegra_video_format *fmtinfo; static struct lock_class_key key; struct v4l2_subdev *subdev; - struct v4l2_subdev_format fmt; + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_TRY, + }; struct v4l2_subdev_state *sd_state; struct v4l2_subdev_frame_size_enum fse = { .which = V4L2_SUBDEV_FORMAT_TRY, @@ -529,7 +531,6 @@ static int __tegra_channel_try_format(struct tegra_vi_channel *chan, } pix->field = V4L2_FIELD_NONE; - fmt.which = V4L2_SUBDEV_FORMAT_TRY; fmt.pad = 0; v4l2_fill_mbus_format(&fmt.format, pix, fmtinfo->code); @@ -590,7 +591,9 @@ static int tegra_channel_set_format(struct file *file, void *fh, { struct tegra_vi_channel *chan = video_drvdata(file); const struct tegra_video_format *fmtinfo; - struct v4l2_subdev_format fmt; + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; struct v4l2_subdev *subdev; struct v4l2_pix_format *pix = &format->fmt.pix; int ret; @@ -605,7 +608,6 @@ static int tegra_channel_set_format(struct file *file, void *fh, fmtinfo = tegra_get_format_by_fourcc(chan->vi, pix->pixelformat); - fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; fmt.pad = 0; v4l2_fill_mbus_format(&fmt.format, pix, fmtinfo->code); subdev = tegra_channel_get_remote_source_subdev(chan); |