From 161aadaec11cd0f610950da56f82bd1778be4156 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Sun, 22 Mar 2015 17:42:31 -0300 Subject: [media] v4l: of: Instead of zeroing bus_type and bus field separately, unify this Zero the entire struct starting from bus_type. As more fields are added, no changes will be needed in the function to reset their value explicitly. Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Acked-by: Sylwester Nawrocki Acked-by: Lad, Prabhakar Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-of.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/v4l2-of.c b/drivers/media/v4l2-core/v4l2-of.c index 83143d39dea7..3ac634891f75 100644 --- a/drivers/media/v4l2-core/v4l2-of.c +++ b/drivers/media/v4l2-core/v4l2-of.c @@ -149,8 +149,9 @@ int v4l2_of_parse_endpoint(const struct device_node *node, int rval; of_graph_parse_endpoint(node, &endpoint->base); - endpoint->bus_type = 0; - memset(&endpoint->bus, 0, sizeof(endpoint->bus)); + /* Zero fields from bus_type to until the end */ + memset(&endpoint->bus_type, 0, sizeof(*endpoint) - + offsetof(typeof(*endpoint), bus_type)); rval = v4l2_of_parse_csi_bus(node, endpoint); if (rval) -- cgit v1.2.3-59-g8ed1b From 698da18e082c8fdfa675bee6338e3f9864d5d7ee Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Sun, 22 Mar 2015 17:48:26 -0300 Subject: [media] v4l: of: Parse variable length properties --- link-frequencies The link-frequencies property is a variable length array of link frequencies in an endpoint. The array is needed by an increasing number of drivers, so it makes sense to add it to struct v4l2_of_endpoint. However, the length of the array is variable and the size of struct v4l2_of_endpoint is fixed since it is allocated by the caller. The options here are 1. to define a fixed maximum limit of link frequencies that has to be the global maximum of all boards. This is seen as problematic since the maximum could be largish, and everyone hitting the problem would need to submit a patch to fix it, or 2. parse the property in every driver. This doesn't sound appealing as two of the three implementations submitted to linux-media were wrong, and one of them was even merged before this was noticed, or 3. change the interface so that allocating and releasing memory according to the size of the array is possible. This is what the patch does. v4l2_of_alloc_parse_endpoint() is just like v4l2_of_parse_endpoint(), but it will allocate the memory resources needed to store struct v4l2_of_endpoint and the additional arrays pointed to by this struct. A corresponding release function v4l2_of_free_endpoint() is provided to release the memory allocated by v4l2_of_alloc_parse_endpoint(). In addition to this, the link-frequencies property is parsed as well, and the result is stored to struct v4l2_of_endpoint field link_frequencies. Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Acked-by: Sylwester Nawrocki Tested-by: Lad, Prabhakar Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-of.c | 87 +++++++++++++++++++++++++++++++++++++++ include/media/v4l2-of.h | 17 ++++++++ 2 files changed, 104 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/v4l2-of.c b/drivers/media/v4l2-core/v4l2-of.c index 3ac634891f75..c52fb9620e11 100644 --- a/drivers/media/v4l2-core/v4l2-of.c +++ b/drivers/media/v4l2-core/v4l2-of.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -141,6 +142,10 @@ static void v4l2_of_parse_parallel_bus(const struct device_node *node, * V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag. * The caller should hold a reference to @node. * + * NOTE: This function does not parse properties the size of which is + * variable without a low fixed limit. Please use + * v4l2_of_alloc_parse_endpoint() in new drivers instead. + * * Return: 0. */ int v4l2_of_parse_endpoint(const struct device_node *node, @@ -167,6 +172,88 @@ int v4l2_of_parse_endpoint(const struct device_node *node, } EXPORT_SYMBOL(v4l2_of_parse_endpoint); +/* + * v4l2_of_free_endpoint() - free the endpoint acquired by + * v4l2_of_alloc_parse_endpoint() + * @endpoint - the endpoint the resources of which are to be released + * + * It is safe to call this function with NULL argument or on an + * endpoint the parsing of which failed. + */ +void v4l2_of_free_endpoint(struct v4l2_of_endpoint *endpoint) +{ + if (IS_ERR_OR_NULL(endpoint)) + return; + + kfree(endpoint->link_frequencies); + kfree(endpoint); +} +EXPORT_SYMBOL(v4l2_of_free_endpoint); + +/** + * v4l2_of_alloc_parse_endpoint() - parse all endpoint node properties + * @node: pointer to endpoint device_node + * + * All properties are optional. If none are found, we don't set any flags. + * This means the port has a static configuration and no properties have + * to be specified explicitly. + * If any properties that identify the bus as parallel are found and + * slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if we recognise + * the bus as serial CSI-2 and clock-noncontinuous isn't set, we set the + * V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag. + * The caller should hold a reference to @node. + * + * v4l2_of_alloc_parse_endpoint() has two important differences to + * v4l2_of_parse_endpoint(): + * + * 1. It also parses variable size data and + * + * 2. The memory it has allocated to store the variable size data must + * be freed using v4l2_of_free_endpoint() when no longer needed. + * + * Return: Pointer to v4l2_of_endpoint if successful, on error a + * negative error code. + */ +struct v4l2_of_endpoint *v4l2_of_alloc_parse_endpoint( + const struct device_node *node) +{ + struct v4l2_of_endpoint *endpoint; + int len; + int rval; + + endpoint = kzalloc(sizeof(*endpoint), GFP_KERNEL); + if (!endpoint) + return ERR_PTR(-ENOMEM); + + rval = v4l2_of_parse_endpoint(node, endpoint); + if (rval < 0) + goto out_err; + + if (of_get_property(node, "link-frequencies", &len)) { + endpoint->link_frequencies = kmalloc(len, GFP_KERNEL); + if (!endpoint->link_frequencies) { + rval = -ENOMEM; + goto out_err; + } + + endpoint->nr_of_link_frequencies = + len / sizeof(*endpoint->link_frequencies); + + rval = of_property_read_u64_array( + node, "link-frequencies", endpoint->link_frequencies, + endpoint->nr_of_link_frequencies); + if (rval < 0) + goto out_err; + } + + return endpoint; + +out_err: + v4l2_of_free_endpoint(endpoint); + return ERR_PTR(rval); +} +EXPORT_SYMBOL(v4l2_of_alloc_parse_endpoint); + /** * v4l2_of_parse_link() - parse a link between two endpoints * @node: pointer to the endpoint at the local end of the link diff --git a/include/media/v4l2-of.h b/include/media/v4l2-of.h index 6c85c079544f..241e98aee40e 100644 --- a/include/media/v4l2-of.h +++ b/include/media/v4l2-of.h @@ -57,6 +57,8 @@ struct v4l2_of_bus_parallel { * @base: struct of_endpoint containing port, id, and local of_node * @bus_type: bus type * @bus: bus configuration data structure + * @link_frequencies: array of supported link frequencies + * @nr_of_link_frequencies: number of elements in link_frequenccies array */ struct v4l2_of_endpoint { struct of_endpoint base; @@ -66,6 +68,8 @@ struct v4l2_of_endpoint { struct v4l2_of_bus_parallel parallel; struct v4l2_of_bus_mipi_csi2 mipi_csi2; } bus; + u64 *link_frequencies; + unsigned int nr_of_link_frequencies; }; /** @@ -85,6 +89,9 @@ struct v4l2_of_link { #ifdef CONFIG_OF int v4l2_of_parse_endpoint(const struct device_node *node, struct v4l2_of_endpoint *endpoint); +struct v4l2_of_endpoint *v4l2_of_alloc_parse_endpoint( + const struct device_node *node); +void v4l2_of_free_endpoint(struct v4l2_of_endpoint *endpoint); int v4l2_of_parse_link(const struct device_node *node, struct v4l2_of_link *link); void v4l2_of_put_link(struct v4l2_of_link *link); @@ -96,6 +103,16 @@ static inline int v4l2_of_parse_endpoint(const struct device_node *node, return -ENOSYS; } +struct v4l2_of_endpoint *v4l2_of_alloc_parse_endpoint( + const struct device_node *node) +{ + return NULL; +} + +static void v4l2_of_free_endpoint(struct v4l2_of_endpoint *endpoint) +{ +} + static inline int v4l2_of_parse_link(const struct device_node *node, struct v4l2_of_link *link) { -- cgit v1.2.3-59-g8ed1b From cb0c9e1f6777287e81d9b48c264d980bf5014b48 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Sun, 22 Mar 2015 17:58:45 -0300 Subject: [media] smiapp: Use v4l2_of_alloc_parse_endpoint() Instead of parsing the link-frequencies property in the driver, let v4l2_of_alloc_parse_endpoint() do it. Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Reviewed-by: Sylwester Nawrocki Reviewed-by: Lad, Prabhakar Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 38 ++++++++++++++++------------------ 1 file changed, 18 insertions(+), 20 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 557f25def3a0..636ebd6fe5dc 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2975,9 +2975,9 @@ static int smiapp_resume(struct device *dev) static struct smiapp_platform_data *smiapp_get_pdata(struct device *dev) { struct smiapp_platform_data *pdata; - struct v4l2_of_endpoint bus_cfg; + struct v4l2_of_endpoint *bus_cfg; struct device_node *ep; - uint32_t asize; + int i; int rval; if (!dev->of_node) @@ -2987,13 +2987,15 @@ static struct smiapp_platform_data *smiapp_get_pdata(struct device *dev) if (!ep) return NULL; + bus_cfg = v4l2_of_alloc_parse_endpoint(ep); + if (IS_ERR(bus_cfg)) + goto out_err; + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) goto out_err; - v4l2_of_parse_endpoint(ep, &bus_cfg); - - switch (bus_cfg.bus_type) { + switch (bus_cfg->bus_type) { case V4L2_MBUS_CSI2: pdata->csi_signalling_mode = SMIAPP_CSI_SIGNALLING_MODE_CSI2; break; @@ -3002,7 +3004,7 @@ static struct smiapp_platform_data *smiapp_get_pdata(struct device *dev) goto out_err; } - pdata->lanes = bus_cfg.bus.mipi_csi2.num_data_lanes; + pdata->lanes = bus_cfg->bus.mipi_csi2.num_data_lanes; dev_dbg(dev, "lanes %u\n", pdata->lanes); /* xshutdown GPIO is optional */ @@ -3022,34 +3024,30 @@ static struct smiapp_platform_data *smiapp_get_pdata(struct device *dev) dev_dbg(dev, "reset %d, nvm %d, clk %d, csi %d\n", pdata->xshutdown, pdata->nvm_size, pdata->ext_clk, pdata->csi_signalling_mode); - rval = of_get_property(ep, "link-frequencies", &asize) ? 0 : -ENOENT; - if (rval) { - dev_warn(dev, "can't get link-frequencies array size\n"); + if (!bus_cfg->nr_of_link_frequencies) { + dev_warn(dev, "no link frequencies defined\n"); goto out_err; } - pdata->op_sys_clock = devm_kzalloc(dev, asize, GFP_KERNEL); + pdata->op_sys_clock = devm_kcalloc( + dev, bus_cfg->nr_of_link_frequencies + 1 /* guardian */, + sizeof(*pdata->op_sys_clock), GFP_KERNEL); if (!pdata->op_sys_clock) { rval = -ENOMEM; goto out_err; } - asize /= sizeof(*pdata->op_sys_clock); - rval = of_property_read_u64_array( - ep, "link-frequencies", pdata->op_sys_clock, asize); - if (rval) { - dev_warn(dev, "can't get link-frequencies\n"); - goto out_err; + for (i = 0; i < bus_cfg->nr_of_link_frequencies; i++) { + pdata->op_sys_clock[i] = bus_cfg->link_frequencies[i]; + dev_dbg(dev, "freq %d: %lld\n", i, pdata->op_sys_clock[i]); } - for (; asize > 0; asize--) - dev_dbg(dev, "freq %d: %lld\n", asize - 1, - pdata->op_sys_clock[asize - 1]); - + v4l2_of_free_endpoint(bus_cfg); of_node_put(ep); return pdata; out_err: + v4l2_of_free_endpoint(bus_cfg); of_node_put(ep); return NULL; } -- cgit v1.2.3-59-g8ed1b From 074c57a25fa2c83a264f3fdbb99a9fef0229884d Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Thu, 9 Apr 2015 04:42:38 -0300 Subject: [media] media: i2c/adp1653: Devicetree support for adp1653 Add device tree support for adp1653 flash LED driver. Signed-off-by: Pavel Machek Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adp1653.c | 100 +++++++++++++++++++++++++++++++++++++++----- include/media/adp1653.h | 8 ++-- 2 files changed, 95 insertions(+), 13 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/adp1653.c b/drivers/media/i2c/adp1653.c index 873fe1949e98..c70ababce954 100644 --- a/drivers/media/i2c/adp1653.c +++ b/drivers/media/i2c/adp1653.c @@ -8,6 +8,7 @@ * Contributors: * Sakari Ailus * Tuukka Toivonen + * Pavel Machek * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -34,6 +35,8 @@ #include #include #include +#include +#include #include #include @@ -308,16 +311,28 @@ __adp1653_set_power(struct adp1653_flash *flash, int on) { int ret; - ret = flash->platform_data->power(&flash->subdev, on); - if (ret < 0) - return ret; + if (flash->platform_data->power) { + ret = flash->platform_data->power(&flash->subdev, on); + if (ret < 0) + return ret; + } else { + gpiod_set_value(flash->platform_data->enable_gpio, on); + if (on) + /* Some delay is apparently required. */ + udelay(20); + } if (!on) return 0; ret = adp1653_init_device(flash); - if (ret < 0) + if (ret >= 0) + return ret; + + if (flash->platform_data->power) flash->platform_data->power(&flash->subdev, 0); + else + gpiod_set_value(flash->platform_data->enable_gpio, 0); return ret; } @@ -407,21 +422,85 @@ static int adp1653_resume(struct device *dev) #endif /* CONFIG_PM */ +static int adp1653_of_init(struct i2c_client *client, + struct adp1653_flash *flash, + struct device_node *node) +{ + struct adp1653_platform_data *pd; + struct device_node *child; + + pd = devm_kzalloc(&client->dev, sizeof(*pd), GFP_KERNEL); + if (!pd) + return -ENOMEM; + flash->platform_data = pd; + + child = of_get_child_by_name(node, "flash"); + if (!child) + return -EINVAL; + + if (of_property_read_u32(child, "flash-timeout-us", + &pd->max_flash_timeout)) + goto err; + + if (of_property_read_u32(child, "flash-max-microamp", + &pd->max_flash_intensity)) + goto err; + + pd->max_flash_intensity /= 1000; + + if (of_property_read_u32(child, "led-max-microamp", + &pd->max_torch_intensity)) + goto err; + + pd->max_torch_intensity /= 1000; + of_node_put(child); + + child = of_get_child_by_name(node, "indicator"); + if (!child) + return -EINVAL; + + if (of_property_read_u32(child, "led-max-microamp", + &pd->max_indicator_intensity)) + goto err; + + of_node_put(child); + + pd->enable_gpio = devm_gpiod_get(&client->dev, "enable"); + if (!pd->enable_gpio) { + dev_err(&client->dev, "Error getting GPIO\n"); + return -EINVAL; + } + + return 0; +err: + dev_err(&client->dev, "Required property not found\n"); + of_node_put(child); + return -EINVAL; +} + + static int adp1653_probe(struct i2c_client *client, const struct i2c_device_id *devid) { struct adp1653_flash *flash; int ret; - /* we couldn't work without platform data */ - if (client->dev.platform_data == NULL) - return -ENODEV; - flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL); if (flash == NULL) return -ENOMEM; - flash->platform_data = client->dev.platform_data; + if (client->dev.of_node) { + ret = adp1653_of_init(client, flash, client->dev.of_node); + if (ret) + return ret; + } else { + if (!client->dev.platform_data) { + dev_err(&client->dev, + "Neither DT not platform data provided\n"); + return EINVAL; + } + flash->platform_data = client->dev.platform_data; + } mutex_init(&flash->power_lock); @@ -442,6 +521,7 @@ static int adp1653_probe(struct i2c_client *client, return 0; free_and_quit: + dev_err(&client->dev, "adp1653: failed to register device\n"); v4l2_ctrl_handler_free(&flash->ctrls); return ret; } @@ -464,7 +544,7 @@ static const struct i2c_device_id adp1653_id_table[] = { }; MODULE_DEVICE_TABLE(i2c, adp1653_id_table); -static struct dev_pm_ops adp1653_pm_ops = { +static const struct dev_pm_ops adp1653_pm_ops = { .suspend = adp1653_suspend, .resume = adp1653_resume, }; diff --git a/include/media/adp1653.h b/include/media/adp1653.h index 1d9b48a3bd80..9779c8549eb4 100644 --- a/include/media/adp1653.h +++ b/include/media/adp1653.h @@ -100,9 +100,11 @@ struct adp1653_platform_data { int (*power)(struct v4l2_subdev *sd, int on); u32 max_flash_timeout; /* flash light timeout in us */ - u32 max_flash_intensity; /* led intensity, flash mode */ - u32 max_torch_intensity; /* led intensity, torch mode */ - u32 max_indicator_intensity; /* indicator led intensity */ + u32 max_flash_intensity; /* led intensity, flash mode, mA */ + u32 max_torch_intensity; /* led intensity, torch mode, mA */ + u32 max_indicator_intensity; /* indicator led intensity, uA */ + + struct gpio_desc *enable_gpio; /* for device-tree based boot */ }; #define to_adp1653_flash(sd) container_of(sd, struct adp1653_flash, subdev) -- cgit v1.2.3-59-g8ed1b From 1381fb3e01cb40e9ddbaf247af757847003d0e75 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 23 Apr 2015 10:52:54 -0300 Subject: [media] vivid: add 1080p capture at 2 fps and 5 fps to webcam emulation Use the VIVID_WEBCAM_SIZES constant where appropriate and add a 1920x1080 pixel frame size setting with frame rates of 2 fps and 5 fps. Signed-off-by: Philipp Zabel Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-vid-cap.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c index dab5990f45a0..09afc933ab80 100644 --- a/drivers/media/platform/vivid/vivid-vid-cap.c +++ b/drivers/media/platform/vivid/vivid-vid-cap.c @@ -66,7 +66,7 @@ static const struct vivid_fmt formats_ovl[] = { }; /* The number of discrete webcam framesizes */ -#define VIVID_WEBCAM_SIZES 3 +#define VIVID_WEBCAM_SIZES 4 /* The number of discrete webcam frameintervals */ #define VIVID_WEBCAM_IVALS (VIVID_WEBCAM_SIZES * 2) @@ -75,6 +75,7 @@ static const struct v4l2_frmsize_discrete webcam_sizes[VIVID_WEBCAM_SIZES] = { { 320, 180 }, { 640, 360 }, { 1280, 720 }, + { 1920, 1080 }, }; /* @@ -82,6 +83,8 @@ static const struct v4l2_frmsize_discrete webcam_sizes[VIVID_WEBCAM_SIZES] = { * elements in this array as there are in webcam_sizes. */ static const struct v4l2_fract webcam_intervals[VIVID_WEBCAM_IVALS] = { + { 1, 2 }, + { 1, 5 }, { 1, 10 }, { 1, 15 }, { 1, 25 }, @@ -720,8 +723,8 @@ int vivid_s_fmt_vid_cap(struct file *file, void *priv, webcam_sizes[i].height == mp->height) break; dev->webcam_size_idx = i; - if (dev->webcam_ival_idx >= 2 * (3 - i)) - dev->webcam_ival_idx = 2 * (3 - i) - 1; + if (dev->webcam_ival_idx >= 2 * (VIVID_WEBCAM_SIZES - i)) + dev->webcam_ival_idx = 2 * (VIVID_WEBCAM_SIZES - i) - 1; vivid_update_format_cap(dev, false); } else { struct v4l2_rect r = { 0, 0, mp->width, mp->height }; @@ -1768,7 +1771,7 @@ int vidioc_enum_frameintervals(struct file *file, void *priv, break; if (i == ARRAY_SIZE(webcam_sizes)) return -EINVAL; - if (fival->index >= 2 * (3 - i)) + if (fival->index >= 2 * (VIVID_WEBCAM_SIZES - i)) return -EINVAL; fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; fival->discrete = webcam_intervals[fival->index]; @@ -1798,7 +1801,7 @@ int vivid_vid_cap_s_parm(struct file *file, void *priv, struct v4l2_streamparm *parm) { struct vivid_dev *dev = video_drvdata(file); - unsigned ival_sz = 2 * (3 - dev->webcam_size_idx); + unsigned ival_sz = 2 * (VIVID_WEBCAM_SIZES - dev->webcam_size_idx); struct v4l2_fract tpf; unsigned i; -- cgit v1.2.3-59-g8ed1b From 84b76d749b18a7badf4135deb160d66e4b2e2d57 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 24 Apr 2015 11:16:22 -0300 Subject: [media] vivid-tpg: add tpg_log_status() Add a log_status function to the test pattern generator and use that in vivid. This simplifies debugging complex colorspace problems. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-core.c | 13 ++++++++++++- drivers/media/platform/vivid/vivid-tpg.c | 16 ++++++++++++++++ drivers/media/platform/vivid/vivid-tpg.h | 1 + 3 files changed, 29 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c index d33f16495dbc..d6caeeb5758d 100644 --- a/drivers/media/platform/vivid/vivid-core.c +++ b/drivers/media/platform/vivid/vivid-core.c @@ -392,6 +392,17 @@ static int vidioc_s_parm(struct file *file, void *fh, return vivid_vid_out_g_parm(file, fh, parm); } +static int vidioc_log_status(struct file *file, void *fh) +{ + struct vivid_dev *dev = video_drvdata(file); + struct video_device *vdev = video_devdata(file); + + v4l2_ctrl_log_status(file, fh); + if (vdev->vfl_dir == VFL_DIR_RX && vdev->vfl_type == VFL_TYPE_GRABBER) + tpg_log_status(&dev->tpg); + return 0; +} + static ssize_t vivid_radio_read(struct file *file, char __user *buf, size_t size, loff_t *offset) { @@ -610,7 +621,7 @@ static const struct v4l2_ioctl_ops vivid_ioctl_ops = { .vidioc_g_edid = vidioc_g_edid, .vidioc_s_edid = vidioc_s_edid, - .vidioc_log_status = v4l2_ctrl_log_status, + .vidioc_log_status = vidioc_log_status, .vidioc_subscribe_event = vidioc_subscribe_event, .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; diff --git a/drivers/media/platform/vivid/vivid-tpg.c b/drivers/media/platform/vivid/vivid-tpg.c index cb766eb154e7..69cd8fb6aac4 100644 --- a/drivers/media/platform/vivid/vivid-tpg.c +++ b/drivers/media/platform/vivid/vivid-tpg.c @@ -1670,6 +1670,22 @@ static int tpg_pattern_avg(const struct tpg_data *tpg, return -1; } +void tpg_log_status(struct tpg_data *tpg) +{ + pr_info("tpg source WxH: %ux%u (%s)\n", + tpg->src_width, tpg->src_height, + tpg->is_yuv ? "YCbCr" : "RGB"); + pr_info("tpg field: %u\n", tpg->field); + pr_info("tpg crop: %ux%u@%dx%d\n", tpg->crop.width, tpg->crop.height, + tpg->crop.left, tpg->crop.top); + pr_info("tpg compose: %ux%u@%dx%d\n", tpg->compose.width, tpg->compose.height, + tpg->compose.left, tpg->compose.top); + pr_info("tpg colorspace: %d\n", tpg->colorspace); + pr_info("tpg Y'CbCr encoding: %d/%d\n", tpg->ycbcr_enc, tpg->real_ycbcr_enc); + pr_info("tpg quantization: %d/%d\n", tpg->quantization, tpg->real_quantization); + pr_info("tpg RGB range: %d/%d\n", tpg->rgb_range, tpg->real_rgb_range); +} + /* * This struct contains common parameters used by both the drawing of the * test pattern and the drawing of the extras (borders, square, etc.) diff --git a/drivers/media/platform/vivid/vivid-tpg.h b/drivers/media/platform/vivid/vivid-tpg.h index a50cd2e2535b..ef8638f945be 100644 --- a/drivers/media/platform/vivid/vivid-tpg.h +++ b/drivers/media/platform/vivid/vivid-tpg.h @@ -192,6 +192,7 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w); void tpg_free(struct tpg_data *tpg); void tpg_reset_source(struct tpg_data *tpg, unsigned width, unsigned height, u32 field); +void tpg_log_status(struct tpg_data *tpg); void tpg_set_font(const u8 *f); void tpg_gen_text(const struct tpg_data *tpg, -- cgit v1.2.3-59-g8ed1b From c702f68af959375f8943fbbedcdec77925f8d513 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 24 Apr 2015 11:16:23 -0300 Subject: [media] vivid-tpg: add full range SMPTE 240M support In order to be consistent with the other Y'CbCr encodings add support for full range V4L2_YCBCR_ENC_SMPTE240M. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-tpg.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/vivid/vivid-tpg.c b/drivers/media/platform/vivid/vivid-tpg.c index 69cd8fb6aac4..59bdbae5f017 100644 --- a/drivers/media/platform/vivid/vivid-tpg.c +++ b/drivers/media/platform/vivid/vivid-tpg.c @@ -479,6 +479,11 @@ static void color_to_ycbcr(struct tpg_data *tpg, int r, int g, int b, { COEFF(-0.116, 224), COEFF(-0.384, 224), COEFF(0.5, 224) }, { COEFF(0.5, 224), COEFF(-0.445, 224), COEFF(-0.055, 224) }, }; + static const int smpte240m_full[3][3] = { + { COEFF(0.212, 255), COEFF(0.701, 255), COEFF(0.087, 255) }, + { COEFF(-0.116, 255), COEFF(-0.384, 255), COEFF(0.5, 255) }, + { COEFF(0.5, 255), COEFF(-0.445, 255), COEFF(-0.055, 255) }, + }; static const int bt2020[3][3] = { { COEFF(0.2627, 219), COEFF(0.6780, 219), COEFF(0.0593, 219) }, { COEFF(-0.1396, 224), COEFF(-0.3604, 224), COEFF(0.5, 224) }, @@ -513,7 +518,7 @@ static void color_to_ycbcr(struct tpg_data *tpg, int r, int g, int b, *cr = (((r - yc) * COEFF(1.0 / 0.9936, 224)) >> 16) + (128 << 4); break; case V4L2_YCBCR_ENC_SMPTE240M: - rgb2ycbcr(smpte240m, r, g, b, 16, y, cb, cr); + rgb2ycbcr(full ? smpte240m_full : smpte240m, r, g, b, y_offset, y, cb, cr); break; case V4L2_YCBCR_ENC_709: case V4L2_YCBCR_ENC_XV709: @@ -567,6 +572,11 @@ static void ycbcr_to_color(struct tpg_data *tpg, int y, int cb, int cr, { COEFF(1, 219), COEFF(-0.2253, 224), COEFF(-0.4767, 224) }, { COEFF(1, 219), COEFF(1.8270, 224), COEFF(0, 224) }, }; + static const int smpte240m_full[3][3] = { + { COEFF(1, 255), COEFF(0, 255), COEFF(1.5756, 255) }, + { COEFF(1, 255), COEFF(-0.2253, 255), COEFF(-0.4767, 255) }, + { COEFF(1, 255), COEFF(1.8270, 255), COEFF(0, 255) }, + }; static const int bt2020[3][3] = { { COEFF(1, 219), COEFF(0, 224), COEFF(1.4746, 224) }, { COEFF(1, 219), COEFF(-0.1646, 224), COEFF(-0.5714, 224) }, @@ -610,7 +620,7 @@ static void ycbcr_to_color(struct tpg_data *tpg, int y, int cb, int cr, *g = linear_to_rec709(lin_g >> 12); break; case V4L2_YCBCR_ENC_SMPTE240M: - ycbcr2rgb(smpte240m, y, cb, cr, 16, r, g, b); + ycbcr2rgb(full ? smpte240m_full : smpte240m, y, cb, cr, y_offset, r, g, b); break; case V4L2_YCBCR_ENC_709: case V4L2_YCBCR_ENC_XV709: -- cgit v1.2.3-59-g8ed1b From cf73b71706df28b9db6b80f6a35c3291c69de17e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 24 Apr 2015 11:16:24 -0300 Subject: [media] vivid-tpg: add full range BT.2020 support In order to be consistent with the other Y'CbCr encodings add support for full range V4L2_YCBCR_ENC_BT2020. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-tpg.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/vivid/vivid-tpg.c b/drivers/media/platform/vivid/vivid-tpg.c index 59bdbae5f017..a7ead155a7d8 100644 --- a/drivers/media/platform/vivid/vivid-tpg.c +++ b/drivers/media/platform/vivid/vivid-tpg.c @@ -489,6 +489,12 @@ static void color_to_ycbcr(struct tpg_data *tpg, int r, int g, int b, { COEFF(-0.1396, 224), COEFF(-0.3604, 224), COEFF(0.5, 224) }, { COEFF(0.5, 224), COEFF(-0.4598, 224), COEFF(-0.0402, 224) }, }; + static const int bt2020_full[3][3] = { + { COEFF(0.2627, 255), COEFF(0.6780, 255), COEFF(0.0593, 255) }, + { COEFF(-0.1396, 255), COEFF(-0.3604, 255), COEFF(0.5, 255) }, + { COEFF(0.5, 255), COEFF(-0.4698, 255), COEFF(-0.0402, 255) }, + }; + bool full = tpg->real_quantization == V4L2_QUANTIZATION_FULL_RANGE; unsigned y_offset = full ? 0 : 16; int lin_y, yc; @@ -500,7 +506,7 @@ static void color_to_ycbcr(struct tpg_data *tpg, int r, int g, int b, rgb2ycbcr(full ? bt601_full : bt601, r, g, b, y_offset, y, cb, cr); break; case V4L2_YCBCR_ENC_BT2020: - rgb2ycbcr(bt2020, r, g, b, 16, y, cb, cr); + rgb2ycbcr(full ? bt2020_full : bt2020, r, g, b, y_offset, y, cb, cr); break; case V4L2_YCBCR_ENC_BT2020_CONST_LUM: lin_y = (COEFF(0.2627, 255) * rec709_to_linear(r) + @@ -582,6 +588,11 @@ static void ycbcr_to_color(struct tpg_data *tpg, int y, int cb, int cr, { COEFF(1, 219), COEFF(-0.1646, 224), COEFF(-0.5714, 224) }, { COEFF(1, 219), COEFF(1.8814, 224), COEFF(0, 224) }, }; + static const int bt2020_full[3][3] = { + { COEFF(1, 255), COEFF(0, 255), COEFF(1.4746, 255) }, + { COEFF(1, 255), COEFF(-0.1646, 255), COEFF(-0.5714, 255) }, + { COEFF(1, 255), COEFF(1.8814, 255), COEFF(0, 255) }, + }; bool full = tpg->real_quantization == V4L2_QUANTIZATION_FULL_RANGE; unsigned y_offset = full ? 0 : 16; int lin_r, lin_g, lin_b, lin_y; @@ -593,7 +604,7 @@ static void ycbcr_to_color(struct tpg_data *tpg, int y, int cb, int cr, ycbcr2rgb(full ? bt601_full : bt601, y, cb, cr, y_offset, r, g, b); break; case V4L2_YCBCR_ENC_BT2020: - ycbcr2rgb(bt2020, y, cb, cr, 16, r, g, b); + ycbcr2rgb(full ? bt2020_full : bt2020, y, cb, cr, y_offset, r, g, b); break; case V4L2_YCBCR_ENC_BT2020_CONST_LUM: y -= 16 << 4; -- cgit v1.2.3-59-g8ed1b From bbfef49fcf61ccd708ce55805c2e25488ed4cf8e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 24 Apr 2015 11:16:25 -0300 Subject: [media] vivid-tpg: add full range BT.2020C support In order to be consistent with the other Y'CbCr encodings add support for full range V4L2_YCBCR_ENC_BT2020_CONST_LUM. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-tpg.c | 40 +++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 11 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/vivid/vivid-tpg.c b/drivers/media/platform/vivid/vivid-tpg.c index a7ead155a7d8..097d29995ec2 100644 --- a/drivers/media/platform/vivid/vivid-tpg.c +++ b/drivers/media/platform/vivid/vivid-tpg.c @@ -494,6 +494,14 @@ static void color_to_ycbcr(struct tpg_data *tpg, int r, int g, int b, { COEFF(-0.1396, 255), COEFF(-0.3604, 255), COEFF(0.5, 255) }, { COEFF(0.5, 255), COEFF(-0.4698, 255), COEFF(-0.0402, 255) }, }; + static const int bt2020c[4] = { + COEFF(1.0 / 1.9404, 224), COEFF(1.0 / 1.5816, 224), + COEFF(1.0 / 1.7184, 224), COEFF(1.0 / 0.9936, 224), + }; + static const int bt2020c_full[4] = { + COEFF(1.0 / 1.9404, 255), COEFF(1.0 / 1.5816, 255), + COEFF(1.0 / 1.7184, 255), COEFF(1.0 / 0.9936, 255), + }; bool full = tpg->real_quantization == V4L2_QUANTIZATION_FULL_RANGE; unsigned y_offset = full ? 0 : 16; @@ -513,15 +521,15 @@ static void color_to_ycbcr(struct tpg_data *tpg, int r, int g, int b, COEFF(0.6780, 255) * rec709_to_linear(g) + COEFF(0.0593, 255) * rec709_to_linear(b)) >> 16; yc = linear_to_rec709(lin_y); - *y = (yc * 219) / 255 + (16 << 4); + *y = full ? yc : (yc * 219) / 255 + (16 << 4); if (b <= yc) - *cb = (((b - yc) * COEFF(1.0 / 1.9404, 224)) >> 16) + (128 << 4); + *cb = (((b - yc) * (full ? bt2020c_full[0] : bt2020c[0])) >> 16) + (128 << 4); else - *cb = (((b - yc) * COEFF(1.0 / 1.5816, 224)) >> 16) + (128 << 4); + *cb = (((b - yc) * (full ? bt2020c_full[1] : bt2020c[1])) >> 16) + (128 << 4); if (r <= yc) - *cr = (((r - yc) * COEFF(1.0 / 1.7184, 224)) >> 16) + (128 << 4); + *cr = (((r - yc) * (full ? bt2020c_full[2] : bt2020c[2])) >> 16) + (128 << 4); else - *cr = (((r - yc) * COEFF(1.0 / 0.9936, 224)) >> 16) + (128 << 4); + *cr = (((r - yc) * (full ? bt2020c_full[3] : bt2020c[3])) >> 16) + (128 << 4); break; case V4L2_YCBCR_ENC_SMPTE240M: rgb2ycbcr(full ? smpte240m_full : smpte240m, r, g, b, y_offset, y, cb, cr); @@ -593,8 +601,18 @@ static void ycbcr_to_color(struct tpg_data *tpg, int y, int cb, int cr, { COEFF(1, 255), COEFF(-0.1646, 255), COEFF(-0.5714, 255) }, { COEFF(1, 255), COEFF(1.8814, 255), COEFF(0, 255) }, }; + static const int bt2020c[4] = { + COEFF(1.9404, 224), COEFF(1.5816, 224), + COEFF(1.7184, 224), COEFF(0.9936, 224), + }; + static const int bt2020c_full[4] = { + COEFF(1.9404, 255), COEFF(1.5816, 255), + COEFF(1.7184, 255), COEFF(0.9936, 255), + }; + bool full = tpg->real_quantization == V4L2_QUANTIZATION_FULL_RANGE; unsigned y_offset = full ? 0 : 16; + int y_fac = full ? COEFF(1.0, 255) : COEFF(1.0, 219); int lin_r, lin_g, lin_b, lin_y; switch (tpg->real_ycbcr_enc) { @@ -607,23 +625,23 @@ static void ycbcr_to_color(struct tpg_data *tpg, int y, int cb, int cr, ycbcr2rgb(full ? bt2020_full : bt2020, y, cb, cr, y_offset, r, g, b); break; case V4L2_YCBCR_ENC_BT2020_CONST_LUM: - y -= 16 << 4; + y -= full ? 0 : 16 << 4; cb -= 128 << 4; cr -= 128 << 4; if (cb <= 0) - *b = COEFF(1.0, 219) * y + COEFF(1.9404, 224) * cb; + *b = y_fac * y + (full ? bt2020c_full[0] : bt2020c[0]) * cb; else - *b = COEFF(1.0, 219) * y + COEFF(1.5816, 224) * cb; + *b = y_fac * y + (full ? bt2020c_full[1] : bt2020c[1]) * cb; *b = *b >> 12; if (cr <= 0) - *r = COEFF(1.0, 219) * y + COEFF(1.7184, 224) * cr; + *r = y_fac * y + (full ? bt2020c_full[2] : bt2020c[2]) * cr; else - *r = COEFF(1.0, 219) * y + COEFF(0.9936, 224) * cr; + *r = y_fac * y + (full ? bt2020c_full[3] : bt2020c[3]) * cr; *r = *r >> 12; lin_r = rec709_to_linear(*r); lin_b = rec709_to_linear(*b); - lin_y = rec709_to_linear((y * 255) / 219); + lin_y = rec709_to_linear((y * 255) / (full ? 255 : 219)); lin_g = COEFF(1.0 / 0.6780, 255) * lin_y - COEFF(0.2627 / 0.6780, 255) * lin_r - -- cgit v1.2.3-59-g8ed1b From f6b8af22e9aab21d72c881f5eebfb8eef805ac88 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 24 Apr 2015 11:16:26 -0300 Subject: [media] vivid-tpg: fix XV601/709 Y'CbCr encoding For these encodings the quantization range should be ignored, since there is only one possible Y'CbCr encoding. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-tpg.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/vivid/vivid-tpg.c b/drivers/media/platform/vivid/vivid-tpg.c index 097d29995ec2..4df755aa7e48 100644 --- a/drivers/media/platform/vivid/vivid-tpg.c +++ b/drivers/media/platform/vivid/vivid-tpg.c @@ -509,10 +509,19 @@ static void color_to_ycbcr(struct tpg_data *tpg, int r, int g, int b, switch (tpg->real_ycbcr_enc) { case V4L2_YCBCR_ENC_601: - case V4L2_YCBCR_ENC_XV601: case V4L2_YCBCR_ENC_SYCC: rgb2ycbcr(full ? bt601_full : bt601, r, g, b, y_offset, y, cb, cr); break; + case V4L2_YCBCR_ENC_XV601: + /* Ignore quantization range, there is only one possible + * Y'CbCr encoding. */ + rgb2ycbcr(bt601, r, g, b, 16, y, cb, cr); + break; + case V4L2_YCBCR_ENC_XV709: + /* Ignore quantization range, there is only one possible + * Y'CbCr encoding. */ + rgb2ycbcr(rec709, r, g, b, 16, y, cb, cr); + break; case V4L2_YCBCR_ENC_BT2020: rgb2ycbcr(full ? bt2020_full : bt2020, r, g, b, y_offset, y, cb, cr); break; @@ -535,7 +544,6 @@ static void color_to_ycbcr(struct tpg_data *tpg, int r, int g, int b, rgb2ycbcr(full ? smpte240m_full : smpte240m, r, g, b, y_offset, y, cb, cr); break; case V4L2_YCBCR_ENC_709: - case V4L2_YCBCR_ENC_XV709: default: rgb2ycbcr(full ? rec709_full : rec709, r, g, b, y_offset, y, cb, cr); break; @@ -617,10 +625,19 @@ static void ycbcr_to_color(struct tpg_data *tpg, int y, int cb, int cr, switch (tpg->real_ycbcr_enc) { case V4L2_YCBCR_ENC_601: - case V4L2_YCBCR_ENC_XV601: case V4L2_YCBCR_ENC_SYCC: ycbcr2rgb(full ? bt601_full : bt601, y, cb, cr, y_offset, r, g, b); break; + case V4L2_YCBCR_ENC_XV601: + /* Ignore quantization range, there is only one possible + * Y'CbCr encoding. */ + ycbcr2rgb(bt601, y, cb, cr, 16, r, g, b); + break; + case V4L2_YCBCR_ENC_XV709: + /* Ignore quantization range, there is only one possible + * Y'CbCr encoding. */ + ycbcr2rgb(rec709, y, cb, cr, 16, r, g, b); + break; case V4L2_YCBCR_ENC_BT2020: ycbcr2rgb(full ? bt2020_full : bt2020, y, cb, cr, y_offset, r, g, b); break; @@ -652,7 +669,6 @@ static void ycbcr_to_color(struct tpg_data *tpg, int y, int cb, int cr, ycbcr2rgb(full ? smpte240m_full : smpte240m, y, cb, cr, y_offset, r, g, b); break; case V4L2_YCBCR_ENC_709: - case V4L2_YCBCR_ENC_XV709: default: ycbcr2rgb(full ? rec709_full : rec709, y, cb, cr, y_offset, r, g, b); break; -- cgit v1.2.3-59-g8ed1b From 874c65f038b8c8d7ba9490b8cbc204209f008c81 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 27 Apr 2015 04:29:51 -0300 Subject: [media] s5c73m3/s5k5baf/s5k6aa: fix compiler warnings Fix these compiler warnings that appeared after switching to gcc-5.1.0: drivers/media/i2c/s5k5baf.c: In function 's5k5baf_set_power': drivers/media/i2c/s5k5baf.c:1057:10: warning: logical not is only applied to the left hand side of comparison [-Wlogical-not-parentheses] if (!on != state->power) ^ drivers/media/i2c/s5k6aa.c: In function 's5k6aa_set_power': drivers/media/i2c/s5k6aa.c:878:10: warning: logical not is only applied to the left hand side of comparison [-Wlogical-not-parentheses] if (!on == s5k6aa->power) { ^ drivers/media/i2c/s5c73m3/s5c73m3-core.c: In function 's5c73m3_oif_set_power': drivers/media/i2c/s5c73m3/s5c73m3-core.c:1456:17: warning: logical not is only applied to the left hand side of comparison [-Wlogical-not-parentheses] } else if (!on == state->power) { ^ Signed-off-by: Hans Verkuil Cc: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/s5c73m3/s5c73m3-core.c | 2 +- drivers/media/i2c/s5k5baf.c | 2 +- drivers/media/i2c/s5k6aa.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index 08b234bd2962..53c5ea89f0b9 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -1453,7 +1453,7 @@ static int s5c73m3_oif_set_power(struct v4l2_subdev *sd, int on) state->apply_fiv = 1; state->apply_fmt = 1; } - } else if (!on == state->power) { + } else if (state->power == !on) { ret = s5c73m3_set_af_softlanding(state); if (!ret) ret = __s5c73m3_power_off(state); diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index 297ef04e146a..bee73de347dc 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -1054,7 +1054,7 @@ static int s5k5baf_set_power(struct v4l2_subdev *sd, int on) mutex_lock(&state->lock); - if (!on != state->power) + if (state->power != !on) goto out; if (on) { diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c index de803a11efb4..d0ad6a25bdab 100644 --- a/drivers/media/i2c/s5k6aa.c +++ b/drivers/media/i2c/s5k6aa.c @@ -875,7 +875,7 @@ static int s5k6aa_set_power(struct v4l2_subdev *sd, int on) mutex_lock(&s5k6aa->lock); - if (!on == s5k6aa->power) { + if (s5k6aa->power == !on) { if (on) { ret = __s5k6aa_power_on(s5k6aa); if (!ret) -- cgit v1.2.3-59-g8ed1b From 7e0d4e92269e574e50a58041fac4cc75a149828c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 27 Apr 2015 04:29:52 -0300 Subject: [media] s3c-camif: fix compiler warnings Fix these compiler warnings that appeared after switching to gcc-5.1.0: drivers/media/platform/s3c-camif/camif-capture.c: In function 'sensor_set_power': drivers/media/platform/s3c-camif/camif-capture.c:118:10: warning: logical not is only applied to the left hand side of comparison [-Wlogical-not-parentheses] if (!on == camif->sensor.power_count) ^ drivers/media/platform/s3c-camif/camif-capture.c: In function 'sensor_set_streaming': drivers/media/platform/s3c-camif/camif-capture.c:134:10: warning: logical not is only applied to the left hand side of comparison [-Wlogical-not-parentheses] if (!on == camif->sensor.stream_count) ^ Signed-off-by: Hans Verkuil Cc: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s3c-camif/camif-capture.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c index f6a61b9ceff4..db4d7d23beb9 100644 --- a/drivers/media/platform/s3c-camif/camif-capture.c +++ b/drivers/media/platform/s3c-camif/camif-capture.c @@ -115,7 +115,7 @@ static int sensor_set_power(struct camif_dev *camif, int on) struct cam_sensor *sensor = &camif->sensor; int err = 0; - if (!on == camif->sensor.power_count) + if (camif->sensor.power_count == !on) err = v4l2_subdev_call(sensor->sd, core, s_power, on); if (!err) sensor->power_count += on ? 1 : -1; @@ -131,7 +131,7 @@ static int sensor_set_streaming(struct camif_dev *camif, int on) struct cam_sensor *sensor = &camif->sensor; int err = 0; - if (!on == camif->sensor.stream_count) + if (camif->sensor.stream_count == !on) err = v4l2_subdev_call(sensor->sd, video, s_stream, on); if (!err) sensor->stream_count += on ? 1 : -1; -- cgit v1.2.3-59-g8ed1b From 8b012fc9bd89a743bbefe2055ca6f091e190935e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 27 Apr 2015 04:29:53 -0300 Subject: [media] cx24123/mb86a20s/s921: fix compiler warnings In file included from drivers/media/common/b2c2/flexcop-fe-tuner.c:13:0: drivers/media/dvb-frontends/cx24123.h:54:2: warning: 'cx24123_get_tuner_i2c_adapter' defined but not used [-Wunused-function] cx24123_get_tuner_i2c_adapter(struct dvb_frontend *fe) ^ In file included from drivers/media/usb/em28xx/em28xx-dvb.c:46:0: drivers/media/dvb-frontends/s921.h:40:2: warning: 's921_get_tuner_i2c_adapter' defined but not used [-Wunused-function] s921_get_tuner_i2c_adapter(struct dvb_frontend *fe) ^ In file included from drivers/media/usb/em28xx/em28xx-dvb.c:55:0: drivers/media/dvb-frontends/mb86a20s.h:49:2: warning: 'mb86a20s_get_tuner_i2c_adapter' defined but not used [-Wunused-function] mb86a20s_get_tuner_i2c_adapter(struct dvb_frontend *fe) ^ In file included from drivers/media/usb/cx231xx/cx231xx-dvb.c:35:0: drivers/media/dvb-frontends/mb86a20s.h:49:2: warning: 'mb86a20s_get_tuner_i2c_adapter' defined but not used [-Wunused-function] mb86a20s_get_tuner_i2c_adapter(struct dvb_frontend *fe) ^ Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24123.h | 2 +- drivers/media/dvb-frontends/mb86a20s.h | 2 +- drivers/media/dvb-frontends/s921.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24123.h b/drivers/media/dvb-frontends/cx24123.h index 758aee5a072f..975f3c926fe8 100644 --- a/drivers/media/dvb-frontends/cx24123.h +++ b/drivers/media/dvb-frontends/cx24123.h @@ -50,7 +50,7 @@ static inline struct dvb_frontend *cx24123_attach( printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } -static struct i2c_adapter * +static inline struct i2c_adapter * cx24123_get_tuner_i2c_adapter(struct dvb_frontend *fe) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); diff --git a/drivers/media/dvb-frontends/mb86a20s.h b/drivers/media/dvb-frontends/mb86a20s.h index f749c8ac5f39..a113282d6956 100644 --- a/drivers/media/dvb-frontends/mb86a20s.h +++ b/drivers/media/dvb-frontends/mb86a20s.h @@ -45,7 +45,7 @@ static inline struct dvb_frontend *mb86a20s_attach( printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } -static struct i2c_adapter * +static inline struct i2c_adapter * mb86a20s_get_tuner_i2c_adapter(struct dvb_frontend *fe) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); diff --git a/drivers/media/dvb-frontends/s921.h b/drivers/media/dvb-frontends/s921.h index 7d3999a4e974..f5b722d8081b 100644 --- a/drivers/media/dvb-frontends/s921.h +++ b/drivers/media/dvb-frontends/s921.h @@ -36,7 +36,7 @@ static inline struct dvb_frontend *s921_attach( printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } -static struct i2c_adapter * +static inline struct i2c_adapter * s921_get_tuner_i2c_adapter(struct dvb_frontend *fe) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); -- cgit v1.2.3-59-g8ed1b From 21de82e374712f3ebfe102b3643e63d633dd350c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 09:28:45 -0300 Subject: [media] dib8000: fix compiler warning In file included from include/uapi/linux/posix_types.h:4:0, from include/uapi/linux/types.h:13, from include/linux/types.h:5, from include/uapi/linux/sysinfo.h:4, from include/uapi/linux/kernel.h:4, from include/linux/cache.h:4, from include/linux/time.h:4, from include/linux/input.h:11, from drivers/media/usb/dvb-usb/dvb-usb.h:13, from drivers/media/usb/dvb-usb/dib0700.h:13, from drivers/media/usb/dvb-usb/dib0700_devices.c:9: drivers/media/dvb-frontends/dib8000.h: In function 'dib8000_attach': include/linux/stddef.h:8:14: warning: return makes integer from pointer without a cast [-Wint-conversion] #define NULL ((void *)0) ^ drivers/media/dvb-frontends/dib8000.h:72:9: note: in expansion of macro 'NULL' return NULL; ^ Reported-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dib8000.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/dib8000.h b/drivers/media/dvb-frontends/dib8000.h index 780c37bdcb72..2b8b4b1656a2 100644 --- a/drivers/media/dvb-frontends/dib8000.h +++ b/drivers/media/dvb-frontends/dib8000.h @@ -66,7 +66,7 @@ struct dib8000_ops { #if IS_REACHABLE(CONFIG_DVB_DIB8000) void *dib8000_attach(struct dib8000_ops *ops); #else -static inline int dib8000_attach(struct dib8000_ops *ops) +static inline void *dib8000_attach(struct dib8000_ops *ops) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; -- cgit v1.2.3-59-g8ed1b From adf98ffe8055107e75e9e914c1733e97952a6f9a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 08:48:15 -0300 Subject: [media] am437x-vpfe: really update the vpfe_ccdc_update_raw_params data drivers/media/platform/am437x/am437x-vpfe.c: In function 'vpfe_ccdc_update_raw_params': drivers/media/platform/am437x/am437x-vpfe.c:430:38: warning: variable 'config_params' set but not used [-Wunused-but-set-variable] struct vpfe_ccdc_config_params_raw *config_params = ^ vpfe_ccdc_update_raw_params() is supposed to update the raw params at ccdc. However, it is just creating a local var and changing it. Compile-tested only. Cc: Benoit Parrot Signed-off-by: Mauro Carvalho Chehab Acked-by: Lad, Prabhakar Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/am437x/am437x-vpfe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c index a30cc2f7e4f1..9c037ac10e10 100644 --- a/drivers/media/platform/am437x/am437x-vpfe.c +++ b/drivers/media/platform/am437x/am437x-vpfe.c @@ -430,7 +430,7 @@ vpfe_ccdc_update_raw_params(struct vpfe_ccdc *ccdc, struct vpfe_ccdc_config_params_raw *config_params = &ccdc->ccdc_cfg.bayer.config_params; - config_params = raw_params; + *config_params = *raw_params; } /* -- cgit v1.2.3-59-g8ed1b From f396573e1c749c1e0b81a052dec900f2c26044cd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 08:55:46 -0300 Subject: [media] am437x: Fix a wrong identation drivers/media/platform/am437x/am437x-vpfe.c:513 vpfe_ccdc_set_params() warn: inconsistent indenting Cc: Benoit Parrot Signed-off-by: Mauro Carvalho Chehab Acked-by: Lad, Prabhakar Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/am437x/am437x-vpfe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c index 9c037ac10e10..57c8a653da4a 100644 --- a/drivers/media/platform/am437x/am437x-vpfe.c +++ b/drivers/media/platform/am437x/am437x-vpfe.c @@ -510,7 +510,7 @@ static int vpfe_ccdc_set_params(struct vpfe_ccdc *ccdc, void __user *params) if (!vpfe_ccdc_validate_param(ccdc, &raw_params)) { vpfe_ccdc_update_raw_params(ccdc, &raw_params); - return 0; + return 0; } return -EINVAL; -- cgit v1.2.3-59-g8ed1b From c413a9e69091b0cc94ed576047902bfd289aeb72 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 08:57:26 -0300 Subject: [media] am437x: remove unused variable drivers/media/platform/am437x/am437x-vpfe.c: In function 'vpfe_get_subdev_input_index': drivers/media/platform/am437x/am437x-vpfe.c:1679:27: warning: variable 'sdinfo' set but not used [-Wunused-but-set-variable] struct vpfe_subdev_info *sdinfo; ^ Cc: Benoit Parrot Signed-off-by: Mauro Carvalho Chehab Acked-by: Lad, Prabhakar Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/am437x/am437x-vpfe.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c index 57c8a653da4a..73359652e486 100644 --- a/drivers/media/platform/am437x/am437x-vpfe.c +++ b/drivers/media/platform/am437x/am437x-vpfe.c @@ -1675,12 +1675,9 @@ vpfe_get_subdev_input_index(struct vpfe_device *vpfe, int *subdev_input_index, int app_input_index) { - struct vpfe_config *cfg = vpfe->cfg; - struct vpfe_subdev_info *sdinfo; int i, j = 0; for (i = 0; i < ARRAY_SIZE(vpfe->cfg->asd); i++) { - sdinfo = &cfg->sub_devs[i]; if (app_input_index < (j + 1)) { *subdev_index = i; *subdev_input_index = app_input_index - j; -- cgit v1.2.3-59-g8ed1b From 81b7d14e32ddd2ae2709609bb2466f8f2482b8c9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 09:43:17 -0300 Subject: [media] rc: fix bad indenting drivers/media/rc/rc-main.c:749 rc_close() warn: inconsistent indenting There's an extra space there. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/rc-main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index f8c5e47a30aa..0ff388a16168 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -746,7 +746,7 @@ void rc_close(struct rc_dev *rdev) if (rdev) { mutex_lock(&rdev->lock); - if (!--rdev->users && rdev->close != NULL) + if (!--rdev->users && rdev->close != NULL) rdev->close(rdev); mutex_unlock(&rdev->lock); -- cgit v1.2.3-59-g8ed1b From 2f9e682d05e27fef1a78b4089cfde818ea109d25 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 09:50:36 -0300 Subject: [media] cx18: avoid going past input/audio array As reported by smatch: drivers/media/pci/cx18/cx18-driver.c:807 cx18_init_struct2() error: buffer overflow 'cx->card->video_inputs' 6 <= 6 That happens because nof_inputs and nof_audio_inputs can be initialized as CX18_CARD_MAX_VIDEO_INPUTS, instead of CX18_CARD_MAX_VIDEO_INPUTS - 1. Signed-off-by: Mauro Carvalho Chehab Acked-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx18/cx18-driver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/cx18/cx18-driver.c b/drivers/media/pci/cx18/cx18-driver.c index 83f5074706f9..260e462d91b4 100644 --- a/drivers/media/pci/cx18/cx18-driver.c +++ b/drivers/media/pci/cx18/cx18-driver.c @@ -786,11 +786,11 @@ static void cx18_init_struct2(struct cx18 *cx) { int i; - for (i = 0; i < CX18_CARD_MAX_VIDEO_INPUTS; i++) + for (i = 0; i < CX18_CARD_MAX_VIDEO_INPUTS - 1; i++) if (cx->card->video_inputs[i].video_type == 0) break; cx->nof_inputs = i; - for (i = 0; i < CX18_CARD_MAX_AUDIO_INPUTS; i++) + for (i = 0; i < CX18_CARD_MAX_AUDIO_INPUTS - 1; i++) if (cx->card->audio_inputs[i].audio_type == 0) break; cx->nof_audio_inputs = i; -- cgit v1.2.3-59-g8ed1b From f8781a08200c07f5e571b2db0929af615fe28f67 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 09:56:01 -0300 Subject: [media] saa7134: fix indent issues As reported by smatch: drivers/media/pci/saa7134/saa7134-cards.c:7197 saa7134_xc2028_callback() warn: inconsistent indenting drivers/media/pci/saa7134/saa7134-cards.c:7846 saa7134_board_init2() warn: inconsistent indenting drivers/media/pci/saa7134/saa7134-cards.c:7913 saa7134_board_init2() warn: inconsistent indenting While here, fix a few CodingStyle issues on the affected code Signed-off-by: Mauro Carvalho Chehab Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-cards.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c index 3ca078057755..d48fd5338db5 100644 --- a/drivers/media/pci/saa7134/saa7134-cards.c +++ b/drivers/media/pci/saa7134/saa7134-cards.c @@ -7194,7 +7194,7 @@ static int saa7134_xc2028_callback(struct saa7134_dev *dev, saa7134_set_gpio(dev, 20, 1); break; } - return 0; + return 0; } return -EINVAL; } @@ -7842,7 +7842,8 @@ int saa7134_board_init2(struct saa7134_dev *dev) break; case 0x001d: dev->tuner_type = TUNER_PHILIPS_FMD1216ME_MK3; - printk(KERN_INFO "%s Board has DVB-T\n", dev->name); + printk(KERN_INFO "%s Board has DVB-T\n", + dev->name); break; default: printk(KERN_ERR "%s Can't determine tuner type %x from EEPROM\n", dev->name, tuner_t); @@ -7903,13 +7904,15 @@ int saa7134_board_init2(struct saa7134_dev *dev) case SAA7134_BOARD_ASUSTeK_TVFM7135: /* The card below is detected as card=53, but is different */ if (dev->autodetected && (dev->eedata[0x27] == 0x03)) { - dev->board = SAA7134_BOARD_ASUSTeK_P7131_ANALOG; - printk(KERN_INFO "%s: P7131 analog only, using " - "entry of %s\n", - dev->name, saa7134_boards[dev->board].name); + dev->board = SAA7134_BOARD_ASUSTeK_P7131_ANALOG; + printk(KERN_INFO + "%s: P7131 analog only, using entry of %s\n", + dev->name, saa7134_boards[dev->board].name); - /* IR init has already happened for other cards, so - * we have to catch up. */ + /* + * IR init has already happened for other cards, so + * we have to catch up. + */ dev->has_remote = SAA7134_REMOTE_GPIO; saa7134_input_init1(dev); } -- cgit v1.2.3-59-g8ed1b From 5a4faee2d01b615011ceb65c656250e4e6a274ee Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 10:02:07 -0300 Subject: [media] ngene: preventing dereferencing a NULL pointer As reported by smatch: drivers/media/pci/ngene/ngene-core.c:1529 init_channel() error: we previously assumed 'chan->fe' could be null (see line 1521) Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ngene/ngene-core.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/ngene/ngene-core.c b/drivers/media/pci/ngene/ngene-core.c index e29bc3af4baf..1b92d836a564 100644 --- a/drivers/media/pci/ngene/ngene-core.c +++ b/drivers/media/pci/ngene/ngene-core.c @@ -1526,10 +1526,12 @@ static int init_channel(struct ngene_channel *chan) if (chan->fe2) { if (dvb_register_frontend(adapter, chan->fe2) < 0) goto err; - chan->fe2->tuner_priv = chan->fe->tuner_priv; - memcpy(&chan->fe2->ops.tuner_ops, - &chan->fe->ops.tuner_ops, - sizeof(struct dvb_tuner_ops)); + if (chan->fe) { + chan->fe2->tuner_priv = chan->fe->tuner_priv; + memcpy(&chan->fe2->ops.tuner_ops, + &chan->fe->ops.tuner_ops, + sizeof(struct dvb_tuner_ops)); + } } if (chan->has_demux) { -- cgit v1.2.3-59-g8ed1b From 3c71d978c5e6dadfc798e84290014f713f56c97b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 10:07:01 -0300 Subject: [media] saa7164: Check if dev is NULL before dereferencing it As reported by smatch: drivers/media/pci/saa7164/saa7164-core.c:631 saa7164_irq() warn: variable dereferenced before check 'dev' (see line 621) Signed-off-by: Mauro Carvalho Chehab Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7164/saa7164-core.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index 9cf3c6cba498..072dcc8f13d9 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -618,12 +618,7 @@ static irqreturn_t saa7164_irq_ts(struct saa7164_port *port) static irqreturn_t saa7164_irq(int irq, void *dev_id) { struct saa7164_dev *dev = dev_id; - struct saa7164_port *porta = &dev->ports[SAA7164_PORT_TS1]; - struct saa7164_port *portb = &dev->ports[SAA7164_PORT_TS2]; - struct saa7164_port *portc = &dev->ports[SAA7164_PORT_ENC1]; - struct saa7164_port *portd = &dev->ports[SAA7164_PORT_ENC2]; - struct saa7164_port *porte = &dev->ports[SAA7164_PORT_VBI1]; - struct saa7164_port *portf = &dev->ports[SAA7164_PORT_VBI2]; + struct saa7164_port *porta, *portb, *portc, *portd, *porte, *portf; u32 intid, intstat[INT_SIZE/4]; int i, handled = 0, bit; @@ -634,6 +629,13 @@ static irqreturn_t saa7164_irq(int irq, void *dev_id) goto out; } + porta = &dev->ports[SAA7164_PORT_TS1]; + portb = &dev->ports[SAA7164_PORT_TS2]; + portc = &dev->ports[SAA7164_PORT_ENC1]; + portd = &dev->ports[SAA7164_PORT_ENC2]; + porte = &dev->ports[SAA7164_PORT_VBI1]; + portf = &dev->ports[SAA7164_PORT_VBI2]; + /* Check that the hardware is accessible. If the status bytes are * 0xFF then the device is not accessible, the the IRQ belongs * to another driver. -- cgit v1.2.3-59-g8ed1b From 4c7ba4082f903c2df3801a26bf3199544c081830 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 10:28:13 -0300 Subject: [media] saa717x: fix multi-byte read code As reported by smatch: drivers/media/i2c/saa717x.c:155 saa717x_read() warn: mask and shift to zero drivers/media/i2c/saa717x.c:155 saa717x_read() warn: mask and shift to zero This is done right at saa717x_write(), but the read function is broken. Thankfully, there's just one place at saa717x driver that uses multibyte read (for status report, via printk). Yet, let's fix it. From saa717x_write(), it is clear that the bytes are in little endian: mm1[4] = (value >> 16) & 0xff; mm1[3] = (value >> 8) & 0xff; mm1[2] = value & 0xff; So, the same order should be valid for read too. Compile-tested only. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/saa717x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/saa717x.c b/drivers/media/i2c/saa717x.c index 0d0f9a917cd3..17557b2f1b09 100644 --- a/drivers/media/i2c/saa717x.c +++ b/drivers/media/i2c/saa717x.c @@ -152,9 +152,9 @@ static u32 saa717x_read(struct v4l2_subdev *sd, u32 reg) i2c_transfer(adap, msgs, 2); if (fw_addr) - value = (mm2[2] & 0xff) | ((mm2[1] & 0xff) >> 8) | ((mm2[0] & 0xff) >> 16); + value = (mm2[2] << 16) | (mm2[1] << 8) | mm2[0]; else - value = mm2[0] & 0xff; + value = mm2[0]; v4l2_dbg(2, debug, sd, "read: reg 0x%03x=0x%08x\n", reg, value); return value; -- cgit v1.2.3-59-g8ed1b From 1cb3b79532a3012fa4b20c8ac344e48a92b5b4d3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 10:33:57 -0300 Subject: [media] radio-si476x: Fix indent As reported by smatch: drivers/media/radio/radio-si476x.c:571 si476x_radio_do_post_powerup_init() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-si476x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-si476x.c b/drivers/media/radio/radio-si476x.c index dccf58691650..9cbb8cdf0ac0 100644 --- a/drivers/media/radio/radio-si476x.c +++ b/drivers/media/radio/radio-si476x.c @@ -568,8 +568,8 @@ static int si476x_radio_do_post_powerup_init(struct si476x_radio *radio, err = regcache_sync_region(radio->core->regmap, SI476X_PROP_DIGITAL_IO_INPUT_SAMPLE_RATE, SI476X_PROP_DIGITAL_IO_OUTPUT_FORMAT); - if (err < 0) - return err; + if (err < 0) + return err; err = regcache_sync_region(radio->core->regmap, SI476X_PROP_AUDIO_DEEMPHASIS, -- cgit v1.2.3-59-g8ed1b From 09290cc885937cab3b2d60a6d48fe3d2d3e04061 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 10:35:13 -0300 Subject: [media] ivtv: avoid going past input/audio array As reported by smatch: drivers/media/pci/ivtv/ivtv-driver.c:832 ivtv_init_struct2() error: buffer overflow 'itv->card->video_inputs' 6 <= 6 That happens because nof_inputs and nof_audio_inputs can be initialized as IVTV_CARD_MAX_VIDEO_INPUTS, instead of IVTV_CARD_MAX_VIDEO_INPUTS - 1. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ivtv/ivtv-driver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/ivtv/ivtv-driver.c b/drivers/media/pci/ivtv/ivtv-driver.c index c2e60b4f292d..8616fa8193bc 100644 --- a/drivers/media/pci/ivtv/ivtv-driver.c +++ b/drivers/media/pci/ivtv/ivtv-driver.c @@ -805,11 +805,11 @@ static void ivtv_init_struct2(struct ivtv *itv) { int i; - for (i = 0; i < IVTV_CARD_MAX_VIDEO_INPUTS; i++) + for (i = 0; i < IVTV_CARD_MAX_VIDEO_INPUTS - 1; i++) if (itv->card->video_inputs[i].video_type == 0) break; itv->nof_inputs = i; - for (i = 0; i < IVTV_CARD_MAX_AUDIO_INPUTS; i++) + for (i = 0; i < IVTV_CARD_MAX_AUDIO_INPUTS - 1; i++) if (itv->card->audio_inputs[i].audio_type == 0) break; itv->nof_audio_inputs = i; -- cgit v1.2.3-59-g8ed1b From 03e5dcee4cab0361b14ef575db455e8de546a3e5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 11:13:09 -0300 Subject: [media] zoran: fix indent As reported by smatch: drivers/media/pci/zoran/zoran_device.c:1594 zoran_init_hardware() warn: inconsistent indenting Fix indent. While here, fix CodingStyle and remove dead code, as it can always be recovered from git logs. Signed-off-by: Mauro Carvalho Chehab Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/zoran/zoran_device.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/zoran/zoran_device.c b/drivers/media/pci/zoran/zoran_device.c index b6801e035ea4..40119b3c52c1 100644 --- a/drivers/media/pci/zoran/zoran_device.c +++ b/drivers/media/pci/zoran/zoran_device.c @@ -1584,14 +1584,11 @@ zoran_init_hardware (struct zoran *zr) jpeg_codec_sleep(zr, 1); jpeg_codec_sleep(zr, 0); - /* set individual interrupt enables (without GIRQ1) - * but don't global enable until zoran_open() */ - - //btwrite(IRQ_MASK & ~ZR36057_ISR_GIRQ1, ZR36057_ICR); // SW - // It looks like using only JPEGRepIRQEn is not always reliable, - // may be when JPEG codec crashes it won't generate IRQ? So, - /*CP*/ // btwrite(IRQ_MASK, ZR36057_ICR); // Enable Vsync interrupts too. SM WHY ? LP - zr36057_init_vfe(zr); + /* + * set individual interrupt enables (without GIRQ1) + * but don't global enable until zoran_open() + */ + zr36057_init_vfe(zr); zr36057_enable_jpg(zr, BUZ_MODE_IDLE); -- cgit v1.2.3-59-g8ed1b From b4bb1bd7c20aeaf51607e7ffdbcc9f3b79094185 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 12:12:09 -0300 Subject: [media] s3c-camif: Check if fmt is NULL before use As reported by smatch: drivers/media/platform/s3c-camif/camif-capture.c:463 queue_setup() warn: variable dereferenced before check 'fmt' (see line 460) Signed-off-by: Mauro Carvalho Chehab Acked-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s3c-camif/camif-capture.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c index db4d7d23beb9..76e6289a5612 100644 --- a/drivers/media/platform/s3c-camif/camif-capture.c +++ b/drivers/media/platform/s3c-camif/camif-capture.c @@ -449,19 +449,22 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt, struct camif_vp *vp = vb2_get_drv_priv(vq); struct camif_dev *camif = vp->camif; struct camif_frame *frame = &vp->out_frame; - const struct camif_fmt *fmt = vp->out_fmt; + const struct camif_fmt *fmt; unsigned int size; if (pfmt) { pix = &pfmt->fmt.pix; fmt = s3c_camif_find_format(vp, &pix->pixelformat, -1); + if (fmt == NULL) + return -EINVAL; size = (pix->width * pix->height * fmt->depth) / 8; } else { + fmt = vp->out_fmt; + if (fmt == NULL) + return -EINVAL; size = (frame->f_width * frame->f_height * fmt->depth) / 8; } - if (fmt == NULL) - return -EINVAL; *num_planes = 1; if (pix) -- cgit v1.2.3-59-g8ed1b From 1ed991a9fe8278b529510850accdea6dea596d0f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 12:16:52 -0300 Subject: [media] s5p_mfc: remove a dead code As reported by smatch: drivers/media/platform/s5p-mfc/s5p_mfc.c:1340 s5p_mfc_runtime_resume() warn: this array is probably non-NULL. 'm_dev->alloc_ctx' alloc_ctx can never be NULL, as it is embeeded inside the struct s5p_mfc_dev. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 8333fbc2fe96..1263d99d638e 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -1337,8 +1337,6 @@ static int s5p_mfc_runtime_resume(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct s5p_mfc_dev *m_dev = platform_get_drvdata(pdev); - if (!m_dev->alloc_ctx) - return 0; atomic_set(&m_dev->pm.power, 1); return 0; } -- cgit v1.2.3-59-g8ed1b From abefe12a2f3b1cd701158d6bd6a826e057dec2b4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 12:23:56 -0300 Subject: [media] ir-sony-decoder: shutup smatch warnings There are some false-positive warnings produced by smatch: drivers/media/rc/ir-sony-decoder.c:129 ir_sony_decode() warn: missing break? reassigning 'data->state' drivers/media/rc/ir-sony-decoder.c:137 ir_sony_decode() warn: missing break? reassigning 'data->state' drivers/media/rc/ir-sony-decoder.c:165 ir_sony_decode() warn: missing break? reassigning 'data->state' This is due to the logic used there to detect the need of a break. While those are false positives, it is easy to get rid of them without any drawbacks. The side effect is a cleaner function, with is good. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/ir-sony-decoder.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/rc/ir-sony-decoder.c b/drivers/media/rc/ir-sony-decoder.c index d12dc3da5931..58ef06f35175 100644 --- a/drivers/media/rc/ir-sony-decoder.c +++ b/drivers/media/rc/ir-sony-decoder.c @@ -125,30 +125,27 @@ static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev) switch (data->count) { case 12: - if (!(dev->enabled_protocols & RC_BIT_SONY12)) { - data->state = STATE_INACTIVE; - return 0; - } + if (!(dev->enabled_protocols & RC_BIT_SONY12)) + goto finish_state_machine; + device = bitrev8((data->bits << 3) & 0xF8); subdevice = 0; function = bitrev8((data->bits >> 4) & 0xFE); protocol = RC_TYPE_SONY12; break; case 15: - if (!(dev->enabled_protocols & RC_BIT_SONY15)) { - data->state = STATE_INACTIVE; - return 0; - } + if (!(dev->enabled_protocols & RC_BIT_SONY15)) + goto finish_state_machine; + device = bitrev8((data->bits >> 0) & 0xFF); subdevice = 0; function = bitrev8((data->bits >> 7) & 0xFE); protocol = RC_TYPE_SONY15; break; case 20: - if (!(dev->enabled_protocols & RC_BIT_SONY20)) { - data->state = STATE_INACTIVE; - return 0; - } + if (!(dev->enabled_protocols & RC_BIT_SONY20)) + goto finish_state_machine; + device = bitrev8((data->bits >> 5) & 0xF8); subdevice = bitrev8((data->bits >> 0) & 0xFF); function = bitrev8((data->bits >> 12) & 0xFE); @@ -162,8 +159,7 @@ static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev) scancode = device << 16 | subdevice << 8 | function; IR_dprintk(1, "Sony(%u) scancode 0x%05x\n", data->count, scancode); rc_keydown(dev, protocol, scancode, 0); - data->state = STATE_INACTIVE; - return 0; + goto finish_state_machine; } out: @@ -171,6 +167,10 @@ out: data->state, TO_US(ev.duration), TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; + +finish_state_machine: + data->state = STATE_INACTIVE; + return 0; } static struct ir_raw_handler sony_handler = { -- cgit v1.2.3-59-g8ed1b From d202e1bab3c3b61dd562360e5c73e9df7d2cfe09 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 12:32:25 -0300 Subject: [media] wl128x: fix int type for streg_cbdata The streg_cbdata can have a negative error value. So, it should be an integer, and not u8, as reported by smatch: drivers/media/radio/wl128x/fmdrv_common.c:1517 fmc_prepare() warn: assigning (-115) to unsigned variable 'fmdev->streg_cbdata' Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/wl128x/fmdrv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/wl128x/fmdrv.h b/drivers/media/radio/wl128x/fmdrv.h index a587c9bac930..dd203de5de95 100644 --- a/drivers/media/radio/wl128x/fmdrv.h +++ b/drivers/media/radio/wl128x/fmdrv.h @@ -210,7 +210,7 @@ struct fmdev { spinlock_t resp_skb_lock; /* To protect access to received SKB */ long flag; /* FM driver state machine info */ - u8 streg_cbdata; /* status of ST registration */ + int streg_cbdata; /* status of ST registration */ struct sk_buff_head rx_q; /* RX queue */ struct tasklet_struct rx_task; /* RX Tasklet */ -- cgit v1.2.3-59-g8ed1b From efc0ac5a0e54657f74c2d6e73e146d249116a608 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 12:39:02 -0300 Subject: [media] qt1010: Reduce text size by using static const Using static const allows the compiler to optimize the code. Before static const: text data bss dec hex filename 4982 524 1568 7074 1ba2 drivers/media/tuners/qt1010.o After static const: text data bss dec hex filename 4714 524 1568 6806 1a96 drivers/media/tuners/qt1010.o Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/qt1010.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/qt1010.c b/drivers/media/tuners/qt1010.c index bc419f8a9671..74b6b17cdbaf 100644 --- a/drivers/media/tuners/qt1010.c +++ b/drivers/media/tuners/qt1010.c @@ -294,7 +294,7 @@ static int qt1010_init(struct dvb_frontend *fe) int err = 0; u8 i, tmpval, *valptr = NULL; - qt1010_i2c_oper_t i2c_data[] = { + static const qt1010_i2c_oper_t i2c_data[] = { { QT1010_WR, 0x01, 0x80 }, { QT1010_WR, 0x0d, 0x84 }, { QT1010_WR, 0x0e, 0xb7 }, -- cgit v1.2.3-59-g8ed1b From 747598d5b6d1c825ad34fbf743e38113aaca597f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 17:09:23 -0300 Subject: [media] go7007: don't use vb before test if it is not NULL As reported by smatch: drivers/media/usb/go7007/go7007-driver.c:452 frame_boundary() warn: variable dereferenced before check 'vb' (see line 449) Signed-off-by: Mauro Carvalho Chehab Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/go7007/go7007-driver.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/go7007/go7007-driver.c b/drivers/media/usb/go7007/go7007-driver.c index 95cffb771a62..0ab81ec8897a 100644 --- a/drivers/media/usb/go7007/go7007-driver.c +++ b/drivers/media/usb/go7007/go7007-driver.c @@ -446,7 +446,7 @@ static void go7007_motion_regions(struct go7007 *go, struct go7007_buffer *vb) */ static struct go7007_buffer *frame_boundary(struct go7007 *go, struct go7007_buffer *vb) { - u32 *bytesused = &vb->vb.v4l2_planes[0].bytesused; + u32 *bytesused; struct go7007_buffer *vb_tmp = NULL; if (vb == NULL) { @@ -458,6 +458,7 @@ static struct go7007_buffer *frame_boundary(struct go7007 *go, struct go7007_buf go->next_seq++; return vb; } + bytesused = &vb->vb.v4l2_planes[0].bytesused; vb->vb.v4l2_buf.sequence = go->next_seq++; if (vb->modet_active && *bytesused + 216 < GO7007_BUF_SIZE) -- cgit v1.2.3-59-g8ed1b From ebb326341c548077dda501339799760b01502923 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 18:18:28 -0300 Subject: [media] benq: fix indentation drivers/media/usb/gspca/benq.c:239 sd_isoc_irq() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/gspca/benq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/gspca/benq.c b/drivers/media/usb/gspca/benq.c index 05f406deae13..790baed33963 100644 --- a/drivers/media/usb/gspca/benq.c +++ b/drivers/media/usb/gspca/benq.c @@ -236,8 +236,8 @@ static void sd_isoc_irq(struct urb *urb) } data = (u8 *) urb->transfer_buffer + urb->iso_frame_desc[i].offset; - gspca_frame_add(gspca_dev, INTER_PACKET, - data, SD_PKT_SZ); + gspca_frame_add(gspca_dev, INTER_PACKET, + data, SD_PKT_SZ); } /* resubmit the URBs */ -- cgit v1.2.3-59-g8ed1b From 361f2e8d974c43a900f6c6e93d78d7e33ae9a08c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 18:25:14 -0300 Subject: [media] bcm3510: fix indentation drivers/media/dvb-frontends/bcm3510.c:688 bcm3510_reset() warn: inconsistent indenting drivers/media/dvb-frontends/bcm3510.c:711 bcm3510_clear_reset() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/bcm3510.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/bcm3510.c b/drivers/media/dvb-frontends/bcm3510.c index 638c7aa0fb7e..23bfd00d42db 100644 --- a/drivers/media/dvb-frontends/bcm3510.c +++ b/drivers/media/dvb-frontends/bcm3510.c @@ -685,7 +685,7 @@ static int bcm3510_reset(struct bcm3510_state *st) if ((ret = bcm3510_writeB(st,0xa0,v)) < 0) return ret; - t = jiffies + 3*HZ; + t = jiffies + 3*HZ; while (time_before(jiffies, t)) { msleep(10); if ((ret = bcm3510_readB(st,0xa2,&v)) < 0) @@ -708,7 +708,7 @@ static int bcm3510_clear_reset(struct bcm3510_state *st) if ((ret = bcm3510_writeB(st,0xa0,v)) < 0) return ret; - t = jiffies + 3*HZ; + t = jiffies + 3*HZ; while (time_before(jiffies, t)) { msleep(10); if ((ret = bcm3510_readB(st,0xa2,&v)) < 0) -- cgit v1.2.3-59-g8ed1b From c7a092e36e639a963b6923018cabce728aabecf6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 18:29:05 -0300 Subject: [media] dib3000mc: Fix indentation drivers/media/dvb-frontends/dib3000mc.c:134 dib3000mc_setup_pwm_state() warn: inconsistent indenting drivers/media/dvb-frontends/dib3000mc.c:144 dib3000mc_setup_pwm_state() warn: inconsistent indenting drivers/media/dvb-frontends/dib3000mc.c:420 dib3000mc_sleep() warn: inconsistent indenting drivers/media/dvb-frontends/dib3000mc.c:453 dib3000mc_set_channel_cfg() warn: inconsistent indenting The last one is actually due to a commented code. Let's rework it, in order to remove the sparse warning without removing the dead code, as it may be useful in the future. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dib3000mc.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/dib3000mc.c b/drivers/media/dvb-frontends/dib3000mc.c index ffad181a9692..ba5e832eb1d4 100644 --- a/drivers/media/dvb-frontends/dib3000mc.c +++ b/drivers/media/dvb-frontends/dib3000mc.c @@ -131,7 +131,7 @@ static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u32 bw, static int dib3000mc_setup_pwm_state(struct dib3000mc_state *state) { u16 reg_51, reg_52 = state->cfg->agc->setup & 0xfefb; - if (state->cfg->pwm3_inversion) { + if (state->cfg->pwm3_inversion) { reg_51 = (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0); reg_52 |= (1 << 2); } else { @@ -141,7 +141,7 @@ static int dib3000mc_setup_pwm_state(struct dib3000mc_state *state) dib3000mc_write_word(state, 51, reg_51); dib3000mc_write_word(state, 52, reg_52); - if (state->cfg->use_pwm3) + if (state->cfg->use_pwm3) dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0)); else dib3000mc_write_word(state, 245, 0); @@ -417,7 +417,7 @@ static int dib3000mc_sleep(struct dvb_frontend *demod) dib3000mc_write_word(state, 1032, 0xFFFF); dib3000mc_write_word(state, 1033, 0xFFF0); - return 0; + return 0; } static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam) @@ -447,10 +447,14 @@ static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, dib3000mc_set_bandwidth(state, bw); dib3000mc_set_timing(state, ch->transmission_mode, bw, 0); -// if (boost) -// dib3000mc_write_word(state, 100, (11 << 6) + 6); -// else +#if 1 + dib3000mc_write_word(state, 100, (16 << 6) + 9); +#else + if (boost) + dib3000mc_write_word(state, 100, (11 << 6) + 6); + else dib3000mc_write_word(state, 100, (16 << 6) + 9); +#endif dib3000mc_write_word(state, 1027, 0x0800); dib3000mc_write_word(state, 1027, 0x0000); -- cgit v1.2.3-59-g8ed1b From 16afc67216ed94c66672f36d5642e5d287d68b92 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 18:31:21 -0300 Subject: [media] lgdt3306a: fix indentation drivers/media/dvb-frontends/lgdt3306a.c:2104 lgdt3306a_DumpRegs() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/lgdt3306a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c index d9a2b0e768e0..0e2e43e9ede5 100644 --- a/drivers/media/dvb-frontends/lgdt3306a.c +++ b/drivers/media/dvb-frontends/lgdt3306a.c @@ -2101,7 +2101,7 @@ static void lgdt3306a_DumpRegs(struct lgdt3306a_state *state) lgdt3306a_read_reg(state, regtab[i], ®val1[i]); if (regval1[i] != regval2[i]) { lg_debug(" %04X = %02X\n", regtab[i], regval1[i]); - regval2[i] = regval1[i]; + regval2[i] = regval1[i]; } } debug = sav_debug; -- cgit v1.2.3-59-g8ed1b From 451dfbe9f153a28da149729552b26043ae94af28 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 18:46:13 -0300 Subject: [media] stv0288: fix indentation drivers/media/dvb-frontends/stv0288.c:137 stv0288_set_symbolrate() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv0288.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/stv0288.c b/drivers/media/dvb-frontends/stv0288.c index 632b25156e4c..ecf4bb3a3b6b 100644 --- a/drivers/media/dvb-frontends/stv0288.c +++ b/drivers/media/dvb-frontends/stv0288.c @@ -134,20 +134,20 @@ static int stv0288_set_symbolrate(struct dvb_frontend *fe, u32 srate) temp = (unsigned int)srate / 1000; - temp = temp * 32768; - temp = temp / 25; - temp = temp / 125; - b[0] = (unsigned char)((temp >> 12) & 0xff); - b[1] = (unsigned char)((temp >> 4) & 0xff); - b[2] = (unsigned char)((temp << 4) & 0xf0); - stv0288_writeregI(state, 0x28, 0x80); /* SFRH */ - stv0288_writeregI(state, 0x29, 0); /* SFRM */ - stv0288_writeregI(state, 0x2a, 0); /* SFRL */ - - stv0288_writeregI(state, 0x28, b[0]); - stv0288_writeregI(state, 0x29, b[1]); - stv0288_writeregI(state, 0x2a, b[2]); - dprintk("stv0288: stv0288_set_symbolrate\n"); + temp = temp * 32768; + temp = temp / 25; + temp = temp / 125; + b[0] = (unsigned char)((temp >> 12) & 0xff); + b[1] = (unsigned char)((temp >> 4) & 0xff); + b[2] = (unsigned char)((temp << 4) & 0xf0); + stv0288_writeregI(state, 0x28, 0x80); /* SFRH */ + stv0288_writeregI(state, 0x29, 0); /* SFRM */ + stv0288_writeregI(state, 0x2a, 0); /* SFRL */ + + stv0288_writeregI(state, 0x28, b[0]); + stv0288_writeregI(state, 0x29, b[1]); + stv0288_writeregI(state, 0x2a, b[2]); + dprintk("stv0288: stv0288_set_symbolrate\n"); return 0; } -- cgit v1.2.3-59-g8ed1b From 12f4543f5d6811f864e6c4952eb27253c7466c02 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 18:34:40 -0300 Subject: [media] s5h1420: fix a buffer overflow when checking userspace params The maximum size for a DiSEqC command is 6, according to the userspace API. However, the code allows to write up to 7 values: drivers/media/dvb-frontends/s5h1420.c:193 s5h1420_send_master_cmd() error: buffer overflow 'cmd->msg' 6 <= 7 Cc: stable@vger.kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/s5h1420.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/s5h1420.c b/drivers/media/dvb-frontends/s5h1420.c index 93eeaf7118fd..0b4f8fe6bf99 100644 --- a/drivers/media/dvb-frontends/s5h1420.c +++ b/drivers/media/dvb-frontends/s5h1420.c @@ -180,7 +180,7 @@ static int s5h1420_send_master_cmd (struct dvb_frontend* fe, int result = 0; dprintk("enter %s\n", __func__); - if (cmd->msg_len > 8) + if (cmd->msg_len > sizeof(cmd->msg)) return -EINVAL; /* setup for DISEQC */ -- cgit v1.2.3-59-g8ed1b From 1fa2337a315a2448c5434f41e00d56b01a22283c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 18:51:17 -0300 Subject: [media] cx24116: fix a buffer overflow when checking userspace params The maximum size for a DiSEqC command is 6, according to the userspace API. However, the code allows to write up much more values: drivers/media/dvb-frontends/cx24116.c:983 cx24116_send_diseqc_msg() error: buffer overflow 'd->msg' 6 <= 23 Cc: stable@vger.kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24116.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24116.c b/drivers/media/dvb-frontends/cx24116.c index 2916d7c74a1d..7bc68b355c0b 100644 --- a/drivers/media/dvb-frontends/cx24116.c +++ b/drivers/media/dvb-frontends/cx24116.c @@ -963,6 +963,10 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend *fe, struct cx24116_state *state = fe->demodulator_priv; int i, ret; + /* Validate length */ + if (d->msg_len > sizeof(d->msg)) + return -EINVAL; + /* Dump DiSEqC message */ if (debug) { printk(KERN_INFO "cx24116: %s(", __func__); @@ -974,10 +978,6 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend *fe, printk(") toneburst=%d\n", toneburst); } - /* Validate length */ - if (d->msg_len > (CX24116_ARGLEN - CX24116_DISEQC_MSGOFS)) - return -EINVAL; - /* DiSEqC message */ for (i = 0; i < d->msg_len; i++) state->dsec_cmd.args[CX24116_DISEQC_MSGOFS + i] = d->msg[i]; -- cgit v1.2.3-59-g8ed1b From d7b76c91f471413de9ded837bddeca2164786571 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 19:02:19 -0300 Subject: [media] af9013: Don't accept invalid bandwidth If userspace sends an invalid bandwidth, it should either return EINVAL or switch to auto mode. This driver will go past an array and program the hardware on a wrong way if this happens. Cc: stable@vger.kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/af9013.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/af9013.c b/drivers/media/dvb-frontends/af9013.c index 8001690d7576..ba6c8f6c42a1 100644 --- a/drivers/media/dvb-frontends/af9013.c +++ b/drivers/media/dvb-frontends/af9013.c @@ -605,6 +605,10 @@ static int af9013_set_frontend(struct dvb_frontend *fe) } } + /* Return an error if can't find bandwidth or the right clock */ + if (i == ARRAY_SIZE(coeff_lut)) + return -EINVAL; + ret = af9013_wr_regs(state, 0xae00, coeff_lut[i].val, sizeof(coeff_lut[i].val)); } -- cgit v1.2.3-59-g8ed1b From 82e3b88b679049f043fe9b03991d6d66fc0a43c8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 19:03:59 -0300 Subject: [media] cx24117: fix a buffer overflow when checking userspace params The maximum size for a DiSEqC command is 6, according to the userspace API. However, the code allows to write up much more values: drivers/media/dvb-frontends/cx24116.c:983 cx24116_send_diseqc_msg() error: buffer overflow 'd->msg' 6 <= 23 Cc: stable@vger.kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24117.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24117.c b/drivers/media/dvb-frontends/cx24117.c index acb965ce0358..af6363573efd 100644 --- a/drivers/media/dvb-frontends/cx24117.c +++ b/drivers/media/dvb-frontends/cx24117.c @@ -1043,7 +1043,7 @@ static int cx24117_send_diseqc_msg(struct dvb_frontend *fe, dev_dbg(&state->priv->i2c->dev, ")\n"); /* Validate length */ - if (d->msg_len > 15) + if (d->msg_len > sizeof(d->msg)) return -EINVAL; /* DiSEqC message */ -- cgit v1.2.3-59-g8ed1b From b036f1cb6e268f2a8c4433c3c26cbef95642b79d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 19:39:53 -0300 Subject: [media] zc3xx: don't go past quality array drivers/media/usb/gspca/zc3xx.c:6363 zcxx_s_ctrl() error: buffer overflow 'jpeg_qual' 3 <= 3 Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/gspca/zc3xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/gspca/zc3xx.c b/drivers/media/usb/gspca/zc3xx.c index d3e1b6d8bf49..3762a045f744 100644 --- a/drivers/media/usb/gspca/zc3xx.c +++ b/drivers/media/usb/gspca/zc3xx.c @@ -6360,7 +6360,7 @@ static int zcxx_s_ctrl(struct v4l2_ctrl *ctrl) if (ctrl->val <= jpeg_qual[i]) break; } - if (i > 0 && i == qual && ctrl->val < jpeg_qual[i]) + if (i == ARRAY_SIZE(jpeg_qual) || (i > 0 && i == qual && ctrl->val < jpeg_qual[i])) i--; /* With high quality settings we need max bandwidth */ -- cgit v1.2.3-59-g8ed1b From 094af36a3a57ddfeb942fd2990f15b570430a81e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 19:49:07 -0300 Subject: [media] zc3xx: remove dead code and uneeded gotos As reported by smatch: drivers/media/usb/gspca/zc3xx.c:5994 transfer_update() info: ignoring unreachable code. That happens because there's a return that it is never called, as the work queue runs an infinite loop, except when the device is put to sleep or an error happens. When an error happens, a break statement is enough to go out of the loop. So, let's remove the goto, as break is the typical instruction used to end a loop. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/gspca/zc3xx.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/gspca/zc3xx.c b/drivers/media/usb/gspca/zc3xx.c index 3762a045f744..c5d8ee6fa3c7 100644 --- a/drivers/media/usb/gspca/zc3xx.c +++ b/drivers/media/usb/gspca/zc3xx.c @@ -5942,23 +5942,23 @@ static void transfer_update(struct work_struct *work) reg07 = 0; good = 0; - for (;;) { + while (1) { msleep(100); /* To protect gspca_dev->usb_buf and gspca_dev->usb_err */ mutex_lock(&gspca_dev->usb_lock); #ifdef CONFIG_PM if (gspca_dev->frozen) - goto err; + break; #endif if (!gspca_dev->present || !gspca_dev->streaming) - goto err; + break; /* Bit 0 of register 11 indicates FIFO overflow */ gspca_dev->usb_err = 0; reg11 = reg_r(gspca_dev, 0x0011); if (gspca_dev->usb_err) - goto err; + break; change = reg11 & 0x01; if (change) { /* overflow */ @@ -5987,12 +5987,12 @@ static void transfer_update(struct work_struct *work) gspca_dev->usb_err = 0; reg_w(gspca_dev, reg07, 0x0007); if (gspca_dev->usb_err) - goto err; + break; } mutex_unlock(&gspca_dev->usb_lock); } - return; -err: + + /* Something went wrong. Unlock and return */ mutex_unlock(&gspca_dev->usb_lock); } -- cgit v1.2.3-59-g8ed1b From 322583c410b6206700f5daa98f965b31c99bb8c2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Apr 2015 20:00:55 -0300 Subject: [media] vivid-radio-rx: Don't go past buffer drivers/media/platform/vivid/vivid-radio-rx.c:198 vivid_radio_rx_s_hw_freq_seek() error: buffer overflow 'vivid_radio_bands' 3 <= 3 Signed-off-by: Mauro Carvalho Chehab Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-radio-rx.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/platform/vivid/vivid-radio-rx.c b/drivers/media/platform/vivid/vivid-radio-rx.c index c7651a506668..f99092ca8f5c 100644 --- a/drivers/media/platform/vivid/vivid-radio-rx.c +++ b/drivers/media/platform/vivid/vivid-radio-rx.c @@ -195,6 +195,8 @@ int vivid_radio_rx_s_hw_freq_seek(struct file *file, void *fh, const struct v4l2 if (dev->radio_rx_freq >= vivid_radio_bands[band].rangelow && dev->radio_rx_freq <= vivid_radio_bands[band].rangehigh) break; + if (band == TOT_BANDS) + return -EINVAL; low = vivid_radio_bands[band].rangelow; high = vivid_radio_bands[band].rangehigh; } -- cgit v1.2.3-59-g8ed1b From 4682b58e5af01ee856a706083eac71238fb69cd0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 09:33:02 -0300 Subject: [media] qt1010: avoid going past array As reported by smatch: drivers/media/tuners/qt1010.c:357 qt1010_init() error: buffer overflow 'i2c_data' 34 <= 34 This should not happen with the current code, as the i2c_data array doesn't end with a QT1010_M1, but it doesn't hurt add a BUG_ON to notify if one modifies it and breaks. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/qt1010.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/qt1010.c b/drivers/media/tuners/qt1010.c index 74b6b17cdbaf..ae8cbece6d2b 100644 --- a/drivers/media/tuners/qt1010.c +++ b/drivers/media/tuners/qt1010.c @@ -354,13 +354,17 @@ static int qt1010_init(struct dvb_frontend *fe) valptr = &priv->reg1f_init_val; else valptr = &tmpval; + + BUG_ON(i >= ARRAY_SIZE(i2c_data) - 1); + err = qt1010_init_meas1(priv, i2c_data[i+1].reg, i2c_data[i].reg, i2c_data[i].val, valptr); i++; break; } - if (err) return err; + if (err) + return err; } for (i = 0x31; i < 0x3a; i++) /* 0x31 - 0x39 */ -- cgit v1.2.3-59-g8ed1b From c0d5e4380fa611e60eff8f0356f8401843936af2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 09:38:06 -0300 Subject: [media] mantis: remove dead code drivers/media/pci/mantis/mantis_cards.c:229 mantis_pci_probe() info: ignoring unreachable code. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/mantis/mantis_cards.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/mantis/mantis_cards.c b/drivers/media/pci/mantis/mantis_cards.c index 801fc55b6167..f437646aa9aa 100644 --- a/drivers/media/pci/mantis/mantis_cards.c +++ b/drivers/media/pci/mantis/mantis_cards.c @@ -226,9 +226,6 @@ static int mantis_pci_probe(struct pci_dev *pdev, return err; - dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART exit! <%d>", err); - mantis_uart_exit(mantis); - fail6: fail4: dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA exit! <%d>", err); -- cgit v1.2.3-59-g8ed1b From 2b257d18f02dc2894ccb94fdb0f305ca0ded6376 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 09:38:59 -0300 Subject: [media] tda1004x: fix identation drivers/media/dvb-frontends/tda1004x.c:653 tda10046_init() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/tda1004x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/tda1004x.c b/drivers/media/dvb-frontends/tda1004x.c index a2631be7ffac..d2b8ecbea81e 100644 --- a/drivers/media/dvb-frontends/tda1004x.c +++ b/drivers/media/dvb-frontends/tda1004x.c @@ -650,7 +650,7 @@ static int tda10046_init(struct dvb_frontend* fe) if (tda10046_fwupload(fe)) { printk("tda1004x: firmware upload failed\n"); - return -EIO; + return -EIO; } // tda setup -- cgit v1.2.3-59-g8ed1b From 2be20f74c07be7a651da982d5865a04f42f174d8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 09:40:24 -0300 Subject: [media] r820t: fix identing drivers/media/tuners/r820t.c:945 r820t_sysfreq_sel() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/r820t.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/r820t.c b/drivers/media/tuners/r820t.c index 71159a58860f..a7a8452e99d2 100644 --- a/drivers/media/tuners/r820t.c +++ b/drivers/media/tuners/r820t.c @@ -941,8 +941,8 @@ static int r820t_sysfreq_sel(struct r820t_priv *priv, u32 freq, rc = r820t_write_reg_mask(priv, 0x10, 0x00, 0x04); if (rc < 0) return rc; - } - return 0; + } + return 0; } static int r820t_set_tv_standard(struct r820t_priv *priv, -- cgit v1.2.3-59-g8ed1b From 57eedc316ea19680d50eb3789cbddf50a8986719 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 09:41:34 -0300 Subject: [media] bttv: fix indenting drivers/media/pci/bt8xx/bttv-driver.c:2679 bttv_s_fbuf() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-driver.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index bc12060e0882..0f10e051f7fd 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -2676,7 +2676,8 @@ static int bttv_s_fbuf(struct file *file, void *f, fh->ov.w.height = fb->fmt.height; btv->init.ov.w.width = fb->fmt.width; btv->init.ov.w.height = fb->fmt.height; - kfree(fh->ov.clips); + + kfree(fh->ov.clips); fh->ov.clips = NULL; fh->ov.nclips = 0; -- cgit v1.2.3-59-g8ed1b From 2267d2d747ba57a2a70ad6f3a6a273c12e3bd505 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 09:42:43 -0300 Subject: [media] zl10353: fix indenting drivers/media/dvb-frontends/zl10353.c:536 zl10353_read_ucblocks() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/zl10353.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/zl10353.c b/drivers/media/dvb-frontends/zl10353.c index 82946cd517f5..4e62a6611847 100644 --- a/drivers/media/dvb-frontends/zl10353.c +++ b/drivers/media/dvb-frontends/zl10353.c @@ -533,13 +533,13 @@ static int zl10353_read_snr(struct dvb_frontend *fe, u16 *snr) static int zl10353_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) { struct zl10353_state *state = fe->demodulator_priv; - u32 ubl = 0; + u32 ubl = 0; - ubl = zl10353_read_register(state, RS_UBC_1) << 8 | - zl10353_read_register(state, RS_UBC_0); + ubl = zl10353_read_register(state, RS_UBC_1) << 8 | + zl10353_read_register(state, RS_UBC_0); - state->ucblocks += ubl; - *ucblocks = state->ucblocks; + state->ucblocks += ubl; + *ucblocks = state->ucblocks; return 0; } -- cgit v1.2.3-59-g8ed1b From 5e6b681b1249a6db33ae12ef13a8285d0de39679 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 09:46:24 -0300 Subject: [media] stv0297: change typecast to u64 to avoid smatch warnings drivers/media/dvb-frontends/stv0297.c:140 stv0297_get_symbolrate() warn: should 'stv0297_readreg(state, 86) << 8' be a 64 bit type? drivers/media/dvb-frontends/stv0297.c:141 stv0297_get_symbolrate() warn: should 'stv0297_readreg(state, 87) << 16' be a 64 bit type? drivers/media/dvb-frontends/stv0297.c:142 stv0297_get_symbolrate() warn: should 'stv0297_readreg(state, 88) << 24' be a 64 bit type? Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv0297.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/stv0297.c b/drivers/media/dvb-frontends/stv0297.c index d40f226160ef..dfc14d5c3999 100644 --- a/drivers/media/dvb-frontends/stv0297.c +++ b/drivers/media/dvb-frontends/stv0297.c @@ -136,10 +136,10 @@ static u32 stv0297_get_symbolrate(struct stv0297_state *state) { u64 tmp; - tmp = stv0297_readreg(state, 0x55); - tmp |= stv0297_readreg(state, 0x56) << 8; - tmp |= stv0297_readreg(state, 0x57) << 16; - tmp |= stv0297_readreg(state, 0x58) << 24; + tmp = (u64)(stv0297_readreg(state, 0x55) + | (stv0297_readreg(state, 0x56) << 8) + | (stv0297_readreg(state, 0x57) << 16) + | (stv0297_readreg(state, 0x58) << 24)); tmp *= STV0297_CLOCK_KHZ; tmp >>= 32; -- cgit v1.2.3-59-g8ed1b From d487df9ef9659b6453751674994178f7f2564dd2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 09:50:41 -0300 Subject: [media] ov7670: check read error also for REG_AECHH on ov7670_s_exp() ov7670_s_exp() checks read error for 2 registers: REG_COM1 and REG_COM8. But, although it uses the value latter, it doesn't check errors on REG_AECHH read. Yet, as it is doing a bitmask operation there, the read operation should succeed. So, fix the code to also check if this succeeded. This fixes this smatch report: drivers/media/i2c/ov7670.c:1366 ov7670_s_exp() warn: inconsistent indenting Compile-tested only. Signed-off-by: Mauro Carvalho Chehab Acked-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov7670.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c index b9847527eb5a..f2fe20aad274 100644 --- a/drivers/media/i2c/ov7670.c +++ b/drivers/media/i2c/ov7670.c @@ -1362,7 +1362,7 @@ static int ov7670_s_exp(struct v4l2_subdev *sd, int value) unsigned char com1, com8, aech, aechh; ret = ov7670_read(sd, REG_COM1, &com1) + - ov7670_read(sd, REG_COM8, &com8); + ov7670_read(sd, REG_COM8, &com8) + ov7670_read(sd, REG_AECHH, &aechh); if (ret) return ret; -- cgit v1.2.3-59-g8ed1b From 6962685384d3d6465f0385cefb37573c40610eaf Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 10:00:39 -0300 Subject: [media] cx231xx: fix bad indenting drivers/media/usb/cx231xx/cx231xx-avcore.c:1598 cx231xx_set_DIF_bandpass() warn: inconsistent indenting drivers/media/usb/cx231xx/cx231xx-core.c:656 cx231xx_demod_reset() warn: inconsistent indenting drivers/media/usb/cx231xx/cx231xx-core.c:659 cx231xx_demod_reset() warn: inconsistent indenting drivers/media/usb/cx231xx/cx231xx-core.c:664 cx231xx_demod_reset() warn: inconsistent indenting drivers/media/usb/cx231xx/cx231xx-core.c:669 cx231xx_demod_reset() warn: inconsistent indenting drivers/media/usb/cx231xx/cx231xx-core.c:673 cx231xx_demod_reset() warn: inconsistent indenting drivers/media/usb/cx231xx/cx231xx-417.c:1164 cx231xx_initialize_codec() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-417.c | 6 ++-- drivers/media/usb/cx231xx/cx231xx-avcore.c | 44 +++++++++++++++--------------- drivers/media/usb/cx231xx/cx231xx-core.c | 30 ++++++++++---------- 3 files changed, 39 insertions(+), 41 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index 983ea8339154..3096e291735c 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c @@ -1160,9 +1160,9 @@ static int cx231xx_initialize_codec(struct cx231xx *dev) } cx231xx_enable656(dev); - /* stop mpeg capture */ - cx231xx_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, - 3, 0, 1, 3, 4); + + /* stop mpeg capture */ + cx231xx_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, 1, 3, 4); cx231xx_codec_settings(dev); msleep(60); diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c index 39e887925e3d..491913778bcc 100644 --- a/drivers/media/usb/cx231xx/cx231xx-avcore.c +++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c @@ -1595,31 +1595,31 @@ void cx231xx_set_DIF_bandpass(struct cx231xx *dev, u32 if_freq, /*pll_freq_word = 0x3463497;*/ vid_blk_write_word(dev, DIF_PLL_FREQ_WORD, pll_freq_word); - if (spectral_invert) { - if_freq -= 400000; - /* Enable Spectral Invert*/ - vid_blk_read_word(dev, DIF_MISC_CTRL, - &dif_misc_ctrl_value); - dif_misc_ctrl_value = dif_misc_ctrl_value | 0x00200000; - vid_blk_write_word(dev, DIF_MISC_CTRL, - dif_misc_ctrl_value); - } else { - if_freq += 400000; - /* Disable Spectral Invert*/ - vid_blk_read_word(dev, DIF_MISC_CTRL, - &dif_misc_ctrl_value); - dif_misc_ctrl_value = dif_misc_ctrl_value & 0xFFDFFFFF; - vid_blk_write_word(dev, DIF_MISC_CTRL, - dif_misc_ctrl_value); - } + if (spectral_invert) { + if_freq -= 400000; + /* Enable Spectral Invert*/ + vid_blk_read_word(dev, DIF_MISC_CTRL, + &dif_misc_ctrl_value); + dif_misc_ctrl_value = dif_misc_ctrl_value | 0x00200000; + vid_blk_write_word(dev, DIF_MISC_CTRL, + dif_misc_ctrl_value); + } else { + if_freq += 400000; + /* Disable Spectral Invert*/ + vid_blk_read_word(dev, DIF_MISC_CTRL, + &dif_misc_ctrl_value); + dif_misc_ctrl_value = dif_misc_ctrl_value & 0xFFDFFFFF; + vid_blk_write_word(dev, DIF_MISC_CTRL, + dif_misc_ctrl_value); + } - if_freq = (if_freq/100000)*100000; + if_freq = (if_freq / 100000) * 100000; - if (if_freq < 3000000) - if_freq = 3000000; + if (if_freq < 3000000) + if_freq = 3000000; - if (if_freq > 16000000) - if_freq = 16000000; + if (if_freq > 16000000) + if_freq = 16000000; } dev_dbg(dev->dev, "Enter IF=%zu\n", ARRAY_SIZE(Dif_set_array)); diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c index e42bde081cd7..a2fd49b6be83 100644 --- a/drivers/media/usb/cx231xx/cx231xx-core.c +++ b/drivers/media/usb/cx231xx/cx231xx-core.c @@ -653,22 +653,20 @@ int cx231xx_demod_reset(struct cx231xx *dev) cx231xx_coredbg("Enter cx231xx_demod_reset()\n"); - value[1] = (u8) 0x3; - status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, - PWR_CTL_EN, value, 4); - msleep(10); - - value[1] = (u8) 0x0; - status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, - PWR_CTL_EN, value, 4); - msleep(10); - - value[1] = (u8) 0x3; - status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, - PWR_CTL_EN, value, 4); - msleep(10); - - + value[1] = (u8) 0x3; + status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, + PWR_CTL_EN, value, 4); + msleep(10); + + value[1] = (u8) 0x0; + status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, + PWR_CTL_EN, value, 4); + msleep(10); + + value[1] = (u8) 0x3; + status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, + PWR_CTL_EN, value, 4); + msleep(10); status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value, 4); -- cgit v1.2.3-59-g8ed1b From f9e2e0e8bac7e0c9ed5d0c30ccc08556ed0e11c6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 10:06:17 -0300 Subject: [media] dib3000mc: fix bad indenting drivers/media/dvb-frontends/dib3000mc.c:149 dib3000mc_setup_pwm_state() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dib3000mc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/dib3000mc.c b/drivers/media/dvb-frontends/dib3000mc.c index ba5e832eb1d4..a9b8081a0fbc 100644 --- a/drivers/media/dvb-frontends/dib3000mc.c +++ b/drivers/media/dvb-frontends/dib3000mc.c @@ -146,7 +146,7 @@ static int dib3000mc_setup_pwm_state(struct dib3000mc_state *state) else dib3000mc_write_word(state, 245, 0); - dib3000mc_write_word(state, 1040, 0x3); + dib3000mc_write_word(state, 1040, 0x3); return 0; } -- cgit v1.2.3-59-g8ed1b From f3f8ef22744bac7af1b01e6b066337f504fb352c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 12:23:49 -0300 Subject: [media] dib0070: Fix indenting The indentation on this driver were deadly broken. On lots of places, it was using 4 spaces instead of tab to indent. On other parts, it were using tabs. Also, on several places, it were not even being properly aligned, as reported by smatch: drivers/media/dvb-frontends/dib0070.c:179 dib0070_set_bandwidth() warn: inconsistent indenting drivers/media/dvb-frontends/dib0070.c:198 dib0070_captrim() warn: inconsistent indenting drivers/media/dvb-frontends/dib0070.c:246 dib0070_set_ctrl_lo5() warn: inconsistent indenting drivers/media/dvb-frontends/dib0070.c:260 dib0070_ctrl_agc_filter() warn: inconsistent indenting drivers/media/dvb-frontends/dib0070.c:494 dib0070_tune_digital() warn: inconsistent indenting drivers/media/dvb-frontends/dib0070.c:498 dib0070_tune_digital() warn: inconsistent indenting drivers/media/dvb-frontends/dib0070.c:655 dib0070_reset() warn: inconsistent indenting drivers/media/dvb-frontends/dib0070.c:711 dib0070_reset() warn: curly braces intended? drivers/media/dvb-frontends/dib0070.c:713 dib0070_reset() warn: inconsistent indenting My first idea were to leave it as-is or to just touch the above. However, this won't be fixing anything. So, as painful as it is, let's fix indentation globally on the driver, and then address the inconsistencies. Hopefully, this driver doesn't have much patches, so it likely won't conflict to any other patch during this merge window. Besides the big size of this patch, no functional changes were done. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dib0070.c | 575 +++++++++++++++++----------------- 1 file changed, 287 insertions(+), 288 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/dib0070.c b/drivers/media/dvb-frontends/dib0070.c index 3b024bfe980a..0b8fb5dd1889 100644 --- a/drivers/media/dvb-frontends/dib0070.c +++ b/drivers/media/dvb-frontends/dib0070.c @@ -58,10 +58,10 @@ struct dib0070_state { u16 wbd_ff_offset; u8 revision; - enum frontend_tune_state tune_state; - u32 current_rf; + enum frontend_tune_state tune_state; + u32 current_rf; - /* for the captrim binary search */ + /* for the captrim binary search */ s8 step; u16 adc_diff; @@ -72,7 +72,7 @@ struct dib0070_state { const struct dib0070_tuning *current_tune_table_index; const struct dib0070_lna_match *lna_match; - u8 wbd_gain_current; + u8 wbd_gain_current; u16 wbd_offset_3_3[2]; /* for the I2C transfer */ @@ -151,31 +151,31 @@ static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val) } while (0) static int dib0070_set_bandwidth(struct dvb_frontend *fe) -{ - struct dib0070_state *state = fe->tuner_priv; - u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff; - - if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 7000) - tmp |= (0 << 14); - else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 6000) - tmp |= (1 << 14); - else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 5000) - tmp |= (2 << 14); - else - tmp |= (3 << 14); - - dib0070_write_reg(state, 0x02, tmp); - - /* sharpen the BB filter in ISDB-T to have higher immunity to adjacent channels */ - if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) { - u16 value = dib0070_read_reg(state, 0x17); - - dib0070_write_reg(state, 0x17, value & 0xfffc); - tmp = dib0070_read_reg(state, 0x01) & 0x01ff; - dib0070_write_reg(state, 0x01, tmp | (60 << 9)); - - dib0070_write_reg(state, 0x17, value); - } + { + struct dib0070_state *state = fe->tuner_priv; + u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff; + + if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 7000) + tmp |= (0 << 14); + else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 6000) + tmp |= (1 << 14); + else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 5000) + tmp |= (2 << 14); + else + tmp |= (3 << 14); + + dib0070_write_reg(state, 0x02, tmp); + + /* sharpen the BB filter in ISDB-T to have higher immunity to adjacent channels */ + if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) { + u16 value = dib0070_read_reg(state, 0x17); + + dib0070_write_reg(state, 0x17, value & 0xfffc); + tmp = dib0070_read_reg(state, 0x01) & 0x01ff; + dib0070_write_reg(state, 0x01, tmp | (60 << 9)); + + dib0070_write_reg(state, 0x17, value); + } return 0; } @@ -186,7 +186,6 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state int ret = 0; if (*tune_state == CT_TUNER_STEP_0) { - dib0070_write_reg(state, 0x0f, 0xed10); dib0070_write_reg(state, 0x17, 0x0034); @@ -195,7 +194,7 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state state->adc_diff = 3000; ret = 20; - *tune_state = CT_TUNER_STEP_1; + *tune_state = CT_TUNER_STEP_1; } else if (*tune_state == CT_TUNER_STEP_1) { state->step /= 2; dib0070_write_reg(state, 0x14, state->lo4 | state->captrim); @@ -220,9 +219,6 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state dprintk("CAPTRIM=%hd is closer to target (%hd/%hd)", state->captrim, adc, state->adc_diff); state->adc_diff = adc; state->fcaptrim = state->captrim; - - - } state->captrim += (step_sign * state->step); @@ -243,7 +239,8 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf_div_trim, u8 cp_current, u8 third_order_filt) { struct dib0070_state *state = fe->tuner_priv; - u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0); + u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0); + dprintk("CTRL_LO5: 0x%x", lo5); return dib0070_write_reg(state, 0x15, lo5); } @@ -257,281 +254,282 @@ void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open) dib0070_write_reg(state, 0x1a, 0x0000); } else { dib0070_write_reg(state, 0x1b, 0x4112); - if (state->cfg->vga_filter != 0) { - dib0070_write_reg(state, 0x1a, state->cfg->vga_filter); - dprintk("vga filter register is set to %x", state->cfg->vga_filter); - } else - dib0070_write_reg(state, 0x1a, 0x0009); + if (state->cfg->vga_filter != 0) { + dib0070_write_reg(state, 0x1a, state->cfg->vga_filter); + dprintk("vga filter register is set to %x", state->cfg->vga_filter); + } else + dib0070_write_reg(state, 0x1a, 0x0009); } } EXPORT_SYMBOL(dib0070_ctrl_agc_filter); struct dib0070_tuning { - u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */ - u8 switch_trim; - u8 vco_band; - u8 hfdiv; - u8 vco_multi; - u8 presc; - u8 wbdmux; - u16 tuner_enable; + u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */ + u8 switch_trim; + u8 vco_band; + u8 hfdiv; + u8 vco_multi; + u8 presc; + u8 wbdmux; + u16 tuner_enable; }; struct dib0070_lna_match { - u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */ - u8 lna_band; + u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */ + u8 lna_band; }; static const struct dib0070_tuning dib0070s_tuning_table[] = { - { 570000, 2, 1, 3, 6, 6, 2, 0x4000 | 0x0800 }, /* UHF */ - { 700000, 2, 0, 2, 4, 2, 2, 0x4000 | 0x0800 }, - { 863999, 2, 1, 2, 4, 2, 2, 0x4000 | 0x0800 }, - { 1500000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 }, /* LBAND */ - { 1600000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 }, - { 2000000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 }, - { 0xffffffff, 0, 0, 8, 1, 2, 1, 0x8000 | 0x1000 }, /* SBAND */ + { 570000, 2, 1, 3, 6, 6, 2, 0x4000 | 0x0800 }, /* UHF */ + { 700000, 2, 0, 2, 4, 2, 2, 0x4000 | 0x0800 }, + { 863999, 2, 1, 2, 4, 2, 2, 0x4000 | 0x0800 }, + { 1500000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 }, /* LBAND */ + { 1600000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 }, + { 2000000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 }, + { 0xffffffff, 0, 0, 8, 1, 2, 1, 0x8000 | 0x1000 }, /* SBAND */ }; static const struct dib0070_tuning dib0070_tuning_table[] = { - { 115000, 1, 0, 7, 24, 2, 1, 0x8000 | 0x1000 }, /* FM below 92MHz cannot be tuned */ - { 179500, 1, 0, 3, 16, 2, 1, 0x8000 | 0x1000 }, /* VHF */ - { 189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000 }, - { 250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000 }, - { 569999, 2, 1, 5, 6, 2, 2, 0x4000 | 0x0800 }, /* UHF */ - { 699999, 2, 0, 1, 4, 2, 2, 0x4000 | 0x0800 }, - { 863999, 2, 1, 1, 4, 2, 2, 0x4000 | 0x0800 }, - { 0xffffffff, 0, 1, 0, 2, 2, 4, 0x2000 | 0x0400 }, /* LBAND or everything higher than UHF */ + { 115000, 1, 0, 7, 24, 2, 1, 0x8000 | 0x1000 }, /* FM below 92MHz cannot be tuned */ + { 179500, 1, 0, 3, 16, 2, 1, 0x8000 | 0x1000 }, /* VHF */ + { 189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000 }, + { 250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000 }, + { 569999, 2, 1, 5, 6, 2, 2, 0x4000 | 0x0800 }, /* UHF */ + { 699999, 2, 0, 1, 4, 2, 2, 0x4000 | 0x0800 }, + { 863999, 2, 1, 1, 4, 2, 2, 0x4000 | 0x0800 }, + { 0xffffffff, 0, 1, 0, 2, 2, 4, 0x2000 | 0x0400 }, /* LBAND or everything higher than UHF */ }; static const struct dib0070_lna_match dib0070_lna_flip_chip[] = { - { 180000, 0 }, /* VHF */ - { 188000, 1 }, - { 196400, 2 }, - { 250000, 3 }, - { 550000, 0 }, /* UHF */ - { 590000, 1 }, - { 666000, 3 }, - { 864000, 5 }, - { 1500000, 0 }, /* LBAND or everything higher than UHF */ - { 1600000, 1 }, - { 2000000, 3 }, - { 0xffffffff, 7 }, + { 180000, 0 }, /* VHF */ + { 188000, 1 }, + { 196400, 2 }, + { 250000, 3 }, + { 550000, 0 }, /* UHF */ + { 590000, 1 }, + { 666000, 3 }, + { 864000, 5 }, + { 1500000, 0 }, /* LBAND or everything higher than UHF */ + { 1600000, 1 }, + { 2000000, 3 }, + { 0xffffffff, 7 }, }; static const struct dib0070_lna_match dib0070_lna[] = { - { 180000, 0 }, /* VHF */ - { 188000, 1 }, - { 196400, 2 }, - { 250000, 3 }, - { 550000, 2 }, /* UHF */ - { 650000, 3 }, - { 750000, 5 }, - { 850000, 6 }, - { 864000, 7 }, - { 1500000, 0 }, /* LBAND or everything higher than UHF */ - { 1600000, 1 }, - { 2000000, 3 }, - { 0xffffffff, 7 }, + { 180000, 0 }, /* VHF */ + { 188000, 1 }, + { 196400, 2 }, + { 250000, 3 }, + { 550000, 2 }, /* UHF */ + { 650000, 3 }, + { 750000, 5 }, + { 850000, 6 }, + { 864000, 7 }, + { 1500000, 0 }, /* LBAND or everything higher than UHF */ + { 1600000, 1 }, + { 2000000, 3 }, + { 0xffffffff, 7 }, }; #define LPF 100 static int dib0070_tune_digital(struct dvb_frontend *fe) { - struct dib0070_state *state = fe->tuner_priv; + struct dib0070_state *state = fe->tuner_priv; - const struct dib0070_tuning *tune; - const struct dib0070_lna_match *lna_match; + const struct dib0070_tuning *tune; + const struct dib0070_lna_match *lna_match; - enum frontend_tune_state *tune_state = &state->tune_state; - int ret = 10; /* 1ms is the default delay most of the time */ + enum frontend_tune_state *tune_state = &state->tune_state; + int ret = 10; /* 1ms is the default delay most of the time */ - u8 band = (u8)BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency/1000); - u32 freq = fe->dtv_property_cache.frequency/1000 + (band == BAND_VHF ? state->cfg->freq_offset_khz_vhf : state->cfg->freq_offset_khz_uhf); + u8 band = (u8)BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency/1000); + u32 freq = fe->dtv_property_cache.frequency/1000 + (band == BAND_VHF ? state->cfg->freq_offset_khz_vhf : state->cfg->freq_offset_khz_uhf); #ifdef CONFIG_SYS_ISDBT - if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1) - if (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) - && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))) - || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0) - && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == (state->fe->dtv_property_cache.isdbt_sb_segment_count / 2))) - || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0) - && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))) - freq += 850; + if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1) + if (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) + && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))) + || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0) + && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == (state->fe->dtv_property_cache.isdbt_sb_segment_count / 2))) + || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0) + && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))) + freq += 850; #endif - if (state->current_rf != freq) { - - switch (state->revision) { - case DIB0070S_P1A: - tune = dib0070s_tuning_table; - lna_match = dib0070_lna; - break; - default: - tune = dib0070_tuning_table; - if (state->cfg->flip_chip) - lna_match = dib0070_lna_flip_chip; - else - lna_match = dib0070_lna; - break; - } - while (freq > tune->max_freq) /* find the right one */ - tune++; - while (freq > lna_match->max_freq) /* find the right one */ - lna_match++; - - state->current_tune_table_index = tune; - state->lna_match = lna_match; - } - - if (*tune_state == CT_TUNER_START) { - dprintk("Tuning for Band: %hd (%d kHz)", band, freq); if (state->current_rf != freq) { - u8 REFDIV; - u32 FBDiv, Rest, FREF, VCOF_kHz; - u8 Den; - - state->current_rf = freq; - state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7); - - - dib0070_write_reg(state, 0x17, 0x30); - - - VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2; - - switch (band) { - case BAND_VHF: - REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000); - break; - case BAND_FM: - REFDIV = (u8) ((state->cfg->clock_khz) / 1000); - break; - default: - REFDIV = (u8) (state->cfg->clock_khz / 10000); - break; - } - FREF = state->cfg->clock_khz / REFDIV; - - switch (state->revision) { case DIB0070S_P1A: - FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF); - Rest = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF; - break; - - case DIB0070_P1G: - case DIB0070_P1F: + tune = dib0070s_tuning_table; + lna_match = dib0070_lna; + break; default: - FBDiv = (freq / (FREF / 2)); - Rest = 2 * freq - FBDiv * FREF; - break; - } - - if (Rest < LPF) - Rest = 0; - else if (Rest < 2 * LPF) - Rest = 2 * LPF; - else if (Rest > (FREF - LPF)) { - Rest = 0; - FBDiv += 1; - } else if (Rest > (FREF - 2 * LPF)) - Rest = FREF - 2 * LPF; - Rest = (Rest * 6528) / (FREF / 10); - - Den = 1; - if (Rest > 0) { - state->lo4 |= (1 << 14) | (1 << 12); - Den = 255; + tune = dib0070_tuning_table; + if (state->cfg->flip_chip) + lna_match = dib0070_lna_flip_chip; + else + lna_match = dib0070_lna; + break; } + while (freq > tune->max_freq) /* find the right one */ + tune++; + while (freq > lna_match->max_freq) /* find the right one */ + lna_match++; + state->current_tune_table_index = tune; + state->lna_match = lna_match; + } - dib0070_write_reg(state, 0x11, (u16)FBDiv); - dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV); - dib0070_write_reg(state, 0x13, (u16) Rest); - - if (state->revision == DIB0070S_P1A) { - - if (band == BAND_SBAND) { - dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0); - dib0070_write_reg(state, 0x1d, 0xFFFF); - } else - dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1); + if (*tune_state == CT_TUNER_START) { + dprintk("Tuning for Band: %hd (%d kHz)", band, freq); + if (state->current_rf != freq) { + u8 REFDIV; + u32 FBDiv, Rest, FREF, VCOF_kHz; + u8 Den; + + state->current_rf = freq; + state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7); + + + dib0070_write_reg(state, 0x17, 0x30); + + + VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2; + + switch (band) { + case BAND_VHF: + REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000); + break; + case BAND_FM: + REFDIV = (u8) ((state->cfg->clock_khz) / 1000); + break; + default: + REFDIV = (u8) (state->cfg->clock_khz / 10000); + break; + } + FREF = state->cfg->clock_khz / REFDIV; + + + + switch (state->revision) { + case DIB0070S_P1A: + FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF); + Rest = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF; + break; + + case DIB0070_P1G: + case DIB0070_P1F: + default: + FBDiv = (freq / (FREF / 2)); + Rest = 2 * freq - FBDiv * FREF; + break; + } + + if (Rest < LPF) + Rest = 0; + else if (Rest < 2 * LPF) + Rest = 2 * LPF; + else if (Rest > (FREF - LPF)) { + Rest = 0; + FBDiv += 1; + } else if (Rest > (FREF - 2 * LPF)) + Rest = FREF - 2 * LPF; + Rest = (Rest * 6528) / (FREF / 10); + + Den = 1; + if (Rest > 0) { + state->lo4 |= (1 << 14) | (1 << 12); + Den = 255; + } + + + dib0070_write_reg(state, 0x11, (u16)FBDiv); + dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV); + dib0070_write_reg(state, 0x13, (u16) Rest); + + if (state->revision == DIB0070S_P1A) { + + if (band == BAND_SBAND) { + dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0); + dib0070_write_reg(state, 0x1d, 0xFFFF); + } else + dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1); + } + + dib0070_write_reg(state, 0x20, + 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable); + + dprintk("REFDIV: %hd, FREF: %d", REFDIV, FREF); + dprintk("FBDIV: %d, Rest: %d", FBDiv, Rest); + dprintk("Num: %hd, Den: %hd, SD: %hd", (u16) Rest, Den, (state->lo4 >> 12) & 0x1); + dprintk("HFDIV code: %hd", state->current_tune_table_index->hfdiv); + dprintk("VCO = %hd", state->current_tune_table_index->vco_band); + dprintk("VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq); + + *tune_state = CT_TUNER_STEP_0; + } else { /* we are already tuned to this frequency - the configuration is correct */ + ret = 50; /* wakeup time */ + *tune_state = CT_TUNER_STEP_5; } + } else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) { - dib0070_write_reg(state, 0x20, - 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable); - - dprintk("REFDIV: %hd, FREF: %d", REFDIV, FREF); - dprintk("FBDIV: %d, Rest: %d", FBDiv, Rest); - dprintk("Num: %hd, Den: %hd, SD: %hd", (u16) Rest, Den, (state->lo4 >> 12) & 0x1); - dprintk("HFDIV code: %hd", state->current_tune_table_index->hfdiv); - dprintk("VCO = %hd", state->current_tune_table_index->vco_band); - dprintk("VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq); - - *tune_state = CT_TUNER_STEP_0; - } else { /* we are already tuned to this frequency - the configuration is correct */ - ret = 50; /* wakeup time */ - *tune_state = CT_TUNER_STEP_5; - } - } else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) { - - ret = dib0070_captrim(state, tune_state); + ret = dib0070_captrim(state, tune_state); - } else if (*tune_state == CT_TUNER_STEP_4) { - const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain; - if (tmp != NULL) { - while (freq/1000 > tmp->freq) /* find the right one */ - tmp++; - dib0070_write_reg(state, 0x0f, - (0 << 15) | (1 << 14) | (3 << 12) - | (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7) - | (state->current_tune_table_index->wbdmux << 0)); - state->wbd_gain_current = tmp->wbd_gain_val; - } else { + } else if (*tune_state == CT_TUNER_STEP_4) { + const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain; + if (tmp != NULL) { + while (freq/1000 > tmp->freq) /* find the right one */ + tmp++; dib0070_write_reg(state, 0x0f, - (0 << 15) | (1 << 14) | (3 << 12) | (6 << 9) | (0 << 8) | (1 << 7) | (state->current_tune_table_index-> - wbdmux << 0)); - state->wbd_gain_current = 6; - } + (0 << 15) | (1 << 14) | (3 << 12) + | (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7) + | (state->current_tune_table_index->wbdmux << 0)); + state->wbd_gain_current = tmp->wbd_gain_val; + } else { + dib0070_write_reg(state, 0x0f, + (0 << 15) | (1 << 14) | (3 << 12) + | (6 << 9) | (0 << 8) | (1 << 7) + | (state->current_tune_table_index->wbdmux << 0)); + state->wbd_gain_current = 6; + } - dib0070_write_reg(state, 0x06, 0x3fff); + dib0070_write_reg(state, 0x06, 0x3fff); dib0070_write_reg(state, 0x07, (state->current_tune_table_index->switch_trim << 11) | (7 << 8) | (state->lna_match->lna_band << 3) | (3 << 0)); - dib0070_write_reg(state, 0x08, (state->lna_match->lna_band << 10) | (3 << 7) | (127)); - dib0070_write_reg(state, 0x0d, 0x0d80); + dib0070_write_reg(state, 0x08, (state->lna_match->lna_band << 10) | (3 << 7) | (127)); + dib0070_write_reg(state, 0x0d, 0x0d80); - dib0070_write_reg(state, 0x18, 0x07ff); - dib0070_write_reg(state, 0x17, 0x0033); + dib0070_write_reg(state, 0x18, 0x07ff); + dib0070_write_reg(state, 0x17, 0x0033); - *tune_state = CT_TUNER_STEP_5; - } else if (*tune_state == CT_TUNER_STEP_5) { - dib0070_set_bandwidth(fe); - *tune_state = CT_TUNER_STOP; - } else { - ret = FE_CALLBACK_TIME_NEVER; /* tuner finished, time to call again infinite */ - } - return ret; + *tune_state = CT_TUNER_STEP_5; + } else if (*tune_state == CT_TUNER_STEP_5) { + dib0070_set_bandwidth(fe); + *tune_state = CT_TUNER_STOP; + } else { + ret = FE_CALLBACK_TIME_NEVER; /* tuner finished, time to call again infinite */ + } + return ret; } static int dib0070_tune(struct dvb_frontend *fe) { - struct dib0070_state *state = fe->tuner_priv; - uint32_t ret; + struct dib0070_state *state = fe->tuner_priv; + uint32_t ret; - state->tune_state = CT_TUNER_START; + state->tune_state = CT_TUNER_START; - do { - ret = dib0070_tune_digital(fe); - if (ret != FE_CALLBACK_TIME_NEVER) - msleep(ret/10); - else - break; - } while (state->tune_state != CT_TUNER_STOP); + do { + ret = dib0070_tune_digital(fe); + if (ret != FE_CALLBACK_TIME_NEVER) + msleep(ret/10); + else + break; + } while (state->tune_state != CT_TUNER_STOP); - return 0; + return 0; } static int dib0070_wakeup(struct dvb_frontend *fe) @@ -610,48 +608,48 @@ static const u16 dib0070_p1f_defaults[] = static u16 dib0070_read_wbd_offset(struct dib0070_state *state, u8 gain) { - u16 tuner_en = dib0070_read_reg(state, 0x20); - u16 offset; - - dib0070_write_reg(state, 0x18, 0x07ff); - dib0070_write_reg(state, 0x20, 0x0800 | 0x4000 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001); - dib0070_write_reg(state, 0x0f, (1 << 14) | (2 << 12) | (gain << 9) | (1 << 8) | (1 << 7) | (0 << 0)); - msleep(9); - offset = dib0070_read_reg(state, 0x19); - dib0070_write_reg(state, 0x20, tuner_en); - return offset; + u16 tuner_en = dib0070_read_reg(state, 0x20); + u16 offset; + + dib0070_write_reg(state, 0x18, 0x07ff); + dib0070_write_reg(state, 0x20, 0x0800 | 0x4000 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001); + dib0070_write_reg(state, 0x0f, (1 << 14) | (2 << 12) | (gain << 9) | (1 << 8) | (1 << 7) | (0 << 0)); + msleep(9); + offset = dib0070_read_reg(state, 0x19); + dib0070_write_reg(state, 0x20, tuner_en); + return offset; } static void dib0070_wbd_offset_calibration(struct dib0070_state *state) { - u8 gain; - for (gain = 6; gain < 8; gain++) { - state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2); - dprintk("Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain-6]); - } + u8 gain; + for (gain = 6; gain < 8; gain++) { + state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2); + dprintk("Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain-6]); + } } u16 dib0070_wbd_offset(struct dvb_frontend *fe) { - struct dib0070_state *state = fe->tuner_priv; - const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain; - u32 freq = fe->dtv_property_cache.frequency/1000; - - if (tmp != NULL) { - while (freq/1000 > tmp->freq) /* find the right one */ - tmp++; - state->wbd_gain_current = tmp->wbd_gain_val; + struct dib0070_state *state = fe->tuner_priv; + const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain; + u32 freq = fe->dtv_property_cache.frequency/1000; + + if (tmp != NULL) { + while (freq/1000 > tmp->freq) /* find the right one */ + tmp++; + state->wbd_gain_current = tmp->wbd_gain_val; } else - state->wbd_gain_current = 6; + state->wbd_gain_current = 6; - return state->wbd_offset_3_3[state->wbd_gain_current - 6]; + return state->wbd_offset_3_3[state->wbd_gain_current - 6]; } EXPORT_SYMBOL(dib0070_wbd_offset); #define pgm_read_word(w) (*w) static int dib0070_reset(struct dvb_frontend *fe) { - struct dib0070_state *state = fe->tuner_priv; + struct dib0070_state *state = fe->tuner_priv; u16 l, r, *n; HARD_RESET(state); @@ -664,7 +662,7 @@ static int dib0070_reset(struct dvb_frontend *fe) #else #warning forcing SBAND #endif - state->revision = DIB0070S_P1A; + state->revision = DIB0070S_P1A; /* P1F or not */ dprintk("Revision: %x", state->revision); @@ -703,24 +701,25 @@ static int dib0070_reset(struct dvb_frontend *fe) dib0070_write_reg(state, 0x02, r | (1 << 5)); } - if (state->revision == DIB0070S_P1A) - dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0); - else - dib0070_set_ctrl_lo5(fe, 5, 4, state->cfg->charge_pump, state->cfg->enable_third_order_filter); + if (state->revision == DIB0070S_P1A) + dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0); + else + dib0070_set_ctrl_lo5(fe, 5, 4, state->cfg->charge_pump, + state->cfg->enable_third_order_filter); dib0070_write_reg(state, 0x01, (54 << 9) | 0xc8); - dib0070_wbd_offset_calibration(state); + dib0070_wbd_offset_calibration(state); - return 0; + return 0; } static int dib0070_get_frequency(struct dvb_frontend *fe, u32 *frequency) { - struct dib0070_state *state = fe->tuner_priv; + struct dib0070_state *state = fe->tuner_priv; - *frequency = 1000 * state->current_rf; - return 0; + *frequency = 1000 * state->current_rf; + return 0; } static int dib0070_release(struct dvb_frontend *fe) -- cgit v1.2.3-59-g8ed1b From 6629e4de828080f6111b78b556afa096c089045a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 12:44:18 -0300 Subject: [media] go7007: Comment some dead code drivers/media/usb/go7007/go7007-usb.c:1099 go7007_usb_probe() info: ignoring unreachable code. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/go7007/go7007-usb.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/usb/go7007/go7007-usb.c b/drivers/media/usb/go7007/go7007-usb.c index 3f986e1178ce..4857c467e76c 100644 --- a/drivers/media/usb/go7007/go7007-usb.c +++ b/drivers/media/usb/go7007/go7007-usb.c @@ -338,6 +338,7 @@ static const struct go7007_usb_board board_matrix_revolution = { }, }; +#if 0 static const struct go7007_usb_board board_lifeview_lr192 = { .flags = GO7007_USB_EZUSB, .main_info = { @@ -364,6 +365,7 @@ static const struct go7007_usb_board board_lifeview_lr192 = { }, }, }; +#endif static const struct go7007_usb_board board_endura = { .flags = 0, @@ -1096,8 +1098,10 @@ static int go7007_usb_probe(struct usb_interface *intf, case GO7007_BOARDID_LIFEVIEW_LR192: dev_err(&intf->dev, "The Lifeview TV Walker Ultra is not supported. Sorry!\n"); return -ENODEV; +#if 0 name = "Lifeview TV Walker Ultra"; board = &board_lifeview_lr192; +#endif break; case GO7007_BOARDID_SENSORAY_2250: dev_info(&intf->dev, "Sensoray 2250 found\n"); -- cgit v1.2.3-59-g8ed1b From 269d91f53fe34b263c0b7735937f3b4ac5f56580 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 14:56:50 -0300 Subject: [media] vp702x: comment dead code Since the first version of this driver, the remote controller code is disabled, adding an early return inside vp702x_rc_query(). Let's disable the code with #if 0, to remove this warning: drivers/media/usb/dvb-usb/vp702x.c:268 vp702x_rc_query() info: ignoring unreachable code. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/vp702x.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb/vp702x.c b/drivers/media/usb/dvb-usb/vp702x.c index 22cf9f96cb9e..ee1e19e36445 100644 --- a/drivers/media/usb/dvb-usb/vp702x.c +++ b/drivers/media/usb/dvb-usb/vp702x.c @@ -259,12 +259,11 @@ static struct rc_map_table rc_map_vp702x_table[] = { /* remote control stuff (does not work with my box) */ static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state) { +/* remove the following return to enabled remote querying */ +#if 0 u8 *key; int i; -/* remove the following return to enabled remote querying */ - return 0; - key = kmalloc(10, GFP_KERNEL); if (!key) return -ENOMEM; @@ -286,6 +285,8 @@ static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state) break; } kfree(key); +#endif + return 0; } -- cgit v1.2.3-59-g8ed1b From 6948524d577dcad963bcdfcbf6e7d934cd18b8f7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 15:00:30 -0300 Subject: [media] redrat3: change return argument on redrat3_send_cmd() to int redrat3_send_cmd() can return an error or the read data. However, it currently returns an u8, as reported by smatch: drivers/media/rc/redrat3.c:416 redrat3_send_cmd() warn: signedness bug returning '(-12)' Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/redrat3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index c4def66f9aa2..c83292ad1b34 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -405,7 +405,7 @@ static void redrat3_process_ir_data(struct redrat3_dev *rr3) } /* Util fn to send rr3 cmds */ -static u8 redrat3_send_cmd(int cmd, struct redrat3_dev *rr3) +static int redrat3_send_cmd(int cmd, struct redrat3_dev *rr3) { struct usb_device *udev; u8 *data; -- cgit v1.2.3-59-g8ed1b From 513641293d1758a36c90cb8bb102eaafb696e153 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 15:05:28 -0300 Subject: [media] sonixj: fix bad indenting drivers/media/usb/gspca/sonixj.c:1792 expo_adjust() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/gspca/sonixj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/gspca/sonixj.c b/drivers/media/usb/gspca/sonixj.c index c69b45d7cfbf..fd1c8706d86a 100644 --- a/drivers/media/usb/gspca/sonixj.c +++ b/drivers/media/usb/gspca/sonixj.c @@ -1789,7 +1789,7 @@ static u32 expo_adjust(struct gspca_dev *gspca_dev, if (expo > 0x03ff) expo = 0x03ff; - if (expo < 0x0001) + if (expo < 0x0001) expo = 0x0001; gainOm[3] = expo >> 2; i2c_w8(gspca_dev, gainOm); -- cgit v1.2.3-59-g8ed1b From e2f233d97b113402a97e322f5d4360915be741cc Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 15:06:20 -0300 Subject: [media] stk014: fix bad indenting drivers/media/usb/gspca/stk014.c:279 sd_start() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/gspca/stk014.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/gspca/stk014.c b/drivers/media/usb/gspca/stk014.c index b0c70fea760b..d324d001e114 100644 --- a/drivers/media/usb/gspca/stk014.c +++ b/drivers/media/usb/gspca/stk014.c @@ -276,7 +276,7 @@ static int sd_start(struct gspca_dev *gspca_dev) gspca_dev->usb_err = ret; goto out; } - reg_r(gspca_dev, 0x0630); + reg_r(gspca_dev, 0x0630); rcv_val(gspca_dev, 0x000020); /* << (value ff ff ff ff) */ reg_r(gspca_dev, 0x0650); snd_val(gspca_dev, 0x000020, 0xffffffff); -- cgit v1.2.3-59-g8ed1b From f419edd4f737ce893c2a4e8dc6863dfe853f6cf4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 15:14:40 -0300 Subject: [media] pvrusb2: fix inconsistent indenting smatch complains about multiple issues here: drivers/media/usb/pvrusb2/pvrusb2-context.c:402 pvr2_channel_claim_stream() warn: inconsistent indenting drivers/media/usb/pvrusb2/pvrusb2-ioread.c:240 pvr2_ioread_setup() warn: inconsistent indenting drivers/media/usb/pvrusb2/pvrusb2-ioread.c:255 pvr2_ioread_set_enabled() warn: inconsistent indenting drivers/media/usb/pvrusb2/pvrusb2-ioread.c:485 pvr2_ioread_read() warn: inconsistent indenting drivers/media/usb/pvrusb2/pvrusb2-io.c:522 pvr2_stream_set_callback() warn: inconsistent indenting drivers/media/usb/pvrusb2/pvrusb2-io.c:561 pvr2_stream_set_buffer_count() warn: inconsistent indenting drivers/media/usb/pvrusb2/pvrusb2-io.c:640 pvr2_buffer_queue() warn: inconsistent indenting drivers/media/usb/pvrusb2/pvrusb2-io.c:667 pvr2_buffer_set_buffer() warn: inconsistent indenting drivers/media/usb/pvrusb2/pvrusb2-io.c:668 pvr2_buffer_set_buffer() warn: inconsistent indenting drivers/media/usb/pvrusb2/pvrusb2-hdw.c:2614 pvr2_hdw_create() warn: inconsistent indenting drivers/media/usb/pvrusb2/pvrusb2-hdw.c:2740 pvr2_hdw_destroy() warn: inconsistent indenting drivers/media/usb/pvrusb2/pvrusb2-hdw.c:3353 pvr2_hdw_trigger_module_log() warn: inconsistent indenting Let's get rid of those, in order to cleanup as much as possible the smatch error log. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/pvrusb2/pvrusb2-context.c | 3 ++- drivers/media/usb/pvrusb2/pvrusb2-hdw.c | 18 +++++++++++------ drivers/media/usb/pvrusb2/pvrusb2-io.c | 30 +++++++++++++++++++---------- drivers/media/usb/pvrusb2/pvrusb2-ioread.c | 24 +++++++++++++++-------- 4 files changed, 50 insertions(+), 25 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/pvrusb2/pvrusb2-context.c b/drivers/media/usb/pvrusb2/pvrusb2-context.c index 924fc4c6019a..fd888a604462 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-context.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-context.c @@ -398,7 +398,8 @@ int pvr2_channel_claim_stream(struct pvr2_channel *cp, if (!sp) break; sp->user = cp; cp->stream = sp; - } while (0); pvr2_context_exit(cp->mc_head); + } while (0); + pvr2_context_exit(cp->mc_head); return code; } diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c index 930593d7028d..775aa5ed92ee 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c @@ -2602,14 +2602,16 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, "Error registering with v4l core, giving up"); goto fail; } - mutex_lock(&pvr2_unit_mtx); do { + mutex_lock(&pvr2_unit_mtx); + do { for (idx = 0; idx < PVR_NUM; idx++) { if (unit_pointers[idx]) continue; hdw->unit_number = idx; unit_pointers[idx] = hdw; break; } - } while (0); mutex_unlock(&pvr2_unit_mtx); + } while (0); + mutex_unlock(&pvr2_unit_mtx); cnt1 = 0; cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2"); @@ -2730,13 +2732,15 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw) pvr2_i2c_core_done(hdw); v4l2_device_unregister(&hdw->v4l2_dev); pvr2_hdw_remove_usb_stuff(hdw); - mutex_lock(&pvr2_unit_mtx); do { + mutex_lock(&pvr2_unit_mtx); + do { if ((hdw->unit_number >= 0) && (hdw->unit_number < PVR_NUM) && (unit_pointers[hdw->unit_number] == hdw)) { unit_pointers[hdw->unit_number] = NULL; } - } while (0); mutex_unlock(&pvr2_unit_mtx); + } while (0); + mutex_unlock(&pvr2_unit_mtx); kfree(hdw->controls); kfree(hdw->mpeg_ctrl_info); kfree(hdw); @@ -3343,14 +3347,16 @@ struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *hp) void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw) { int nr = pvr2_hdw_get_unit_number(hdw); - LOCK_TAKE(hdw->big_lock); do { + LOCK_TAKE(hdw->big_lock); + do { printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr); v4l2_device_call_all(&hdw->v4l2_dev, 0, core, log_status); pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:"); cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2"); pvr2_hdw_state_log_state(hdw); printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr); - } while (0); LOCK_GIVE(hdw->big_lock); + } while (0); + LOCK_GIVE(hdw->big_lock); } diff --git a/drivers/media/usb/pvrusb2/pvrusb2-io.c b/drivers/media/usb/pvrusb2/pvrusb2-io.c index 0c08f22bdfce..d860344de84e 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-io.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-io.c @@ -514,12 +514,14 @@ void pvr2_stream_set_callback(struct pvr2_stream *sp, void *data) { unsigned long irq_flags; - mutex_lock(&sp->mutex); do { + mutex_lock(&sp->mutex); + do { spin_lock_irqsave(&sp->list_lock,irq_flags); sp->callback_data = data; sp->callback_func = func; spin_unlock_irqrestore(&sp->list_lock,irq_flags); - } while(0); mutex_unlock(&sp->mutex); + } while(0); + mutex_unlock(&sp->mutex); } void pvr2_stream_get_stats(struct pvr2_stream *sp, @@ -554,10 +556,12 @@ int pvr2_stream_set_buffer_count(struct pvr2_stream *sp,unsigned int cnt) { int ret; if (sp->buffer_target_count == cnt) return 0; - mutex_lock(&sp->mutex); do { + mutex_lock(&sp->mutex); + do { sp->buffer_target_count = cnt; ret = pvr2_stream_achieve_buffer_count(sp); - } while(0); mutex_unlock(&sp->mutex); + } while(0); + mutex_unlock(&sp->mutex); return ret; } @@ -590,7 +594,8 @@ int pvr2_stream_get_ready_count(struct pvr2_stream *sp) void pvr2_stream_kill(struct pvr2_stream *sp) { struct pvr2_buffer *bp; - mutex_lock(&sp->mutex); do { + mutex_lock(&sp->mutex); + do { pvr2_stream_internal_flush(sp); while ((bp = pvr2_stream_get_ready_buffer(sp)) != NULL) { pvr2_buffer_set_idle(bp); @@ -598,7 +603,8 @@ void pvr2_stream_kill(struct pvr2_stream *sp) if (sp->buffer_total_count != sp->buffer_target_count) { pvr2_stream_achieve_buffer_count(sp); } - } while(0); mutex_unlock(&sp->mutex); + } while(0); + mutex_unlock(&sp->mutex); } int pvr2_buffer_queue(struct pvr2_buffer *bp) @@ -612,7 +618,8 @@ int pvr2_buffer_queue(struct pvr2_buffer *bp) struct pvr2_stream *sp; if (!bp) return -EINVAL; sp = bp->stream; - mutex_lock(&sp->mutex); do { + mutex_lock(&sp->mutex); + do { pvr2_buffer_wipe(bp); if (!sp->dev) { ret = -EIO; @@ -636,7 +643,8 @@ int pvr2_buffer_queue(struct pvr2_buffer *bp) buffer_complete, bp); usb_submit_urb(bp->purb,GFP_KERNEL); - } while(0); mutex_unlock(&sp->mutex); + } while(0); + mutex_unlock(&sp->mutex); return ret; } @@ -647,7 +655,8 @@ int pvr2_buffer_set_buffer(struct pvr2_buffer *bp,void *ptr,unsigned int cnt) struct pvr2_stream *sp; if (!bp) return -EINVAL; sp = bp->stream; - mutex_lock(&sp->mutex); do { + mutex_lock(&sp->mutex); + do { spin_lock_irqsave(&sp->list_lock,irq_flags); if (bp->state != pvr2_buffer_state_idle) { ret = -EPERM; @@ -664,7 +673,8 @@ int pvr2_buffer_set_buffer(struct pvr2_buffer *bp,void *ptr,unsigned int cnt) bp->stream->i_bcount,bp->stream->i_count); } spin_unlock_irqrestore(&sp->list_lock,irq_flags); - } while(0); mutex_unlock(&sp->mutex); + } while(0); + mutex_unlock(&sp->mutex); return ret; } diff --git a/drivers/media/usb/pvrusb2/pvrusb2-ioread.c b/drivers/media/usb/pvrusb2/pvrusb2-ioread.c index cd995b54732e..614d55767a4e 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-ioread.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-ioread.c @@ -205,7 +205,8 @@ int pvr2_ioread_setup(struct pvr2_ioread *cp,struct pvr2_stream *sp) unsigned int idx; struct pvr2_buffer *bp; - mutex_lock(&cp->mutex); do { + mutex_lock(&cp->mutex); + do { if (cp->stream) { pvr2_trace(PVR2_TRACE_START_STOP, "/*---TRACE_READ---*/" @@ -235,7 +236,8 @@ int pvr2_ioread_setup(struct pvr2_ioread *cp,struct pvr2_stream *sp) } cp->stream = sp; } - } while (0); mutex_unlock(&cp->mutex); + } while (0); + mutex_unlock(&cp->mutex); return 0; } @@ -245,13 +247,15 @@ int pvr2_ioread_set_enabled(struct pvr2_ioread *cp,int fl) int ret = 0; if ((!fl) == (!(cp->enabled))) return ret; - mutex_lock(&cp->mutex); do { + mutex_lock(&cp->mutex); + do { if (fl) { ret = pvr2_ioread_start(cp); } else { pvr2_ioread_stop(cp); } - } while (0); mutex_unlock(&cp->mutex); + } while (0); + mutex_unlock(&cp->mutex); return ret; } @@ -315,7 +319,8 @@ static void pvr2_ioread_filter(struct pvr2_ioread *cp) // Search the stream for our synchronization key. This is made // complicated by the fact that in order to be honest with // ourselves here we must search across buffer boundaries... - mutex_lock(&cp->mutex); while (1) { + mutex_lock(&cp->mutex); + while (1) { // Ensure we have a buffer if (!pvr2_ioread_get_buffer(cp)) break; if (!cp->c_data_len) break; @@ -362,7 +367,8 @@ static void pvr2_ioread_filter(struct pvr2_ioread *cp) } continue; // (for clarity) - } mutex_unlock(&cp->mutex); + } + mutex_unlock(&cp->mutex); } int pvr2_ioread_avail(struct pvr2_ioread *cp) @@ -422,7 +428,8 @@ int pvr2_ioread_read(struct pvr2_ioread *cp,void __user *buf,unsigned int cnt) cp->stream_running = !0; - mutex_lock(&cp->mutex); do { + mutex_lock(&cp->mutex); + do { // Suck data out of the buffers and copy to the user copied_cnt = 0; @@ -480,7 +487,8 @@ int pvr2_ioread_read(struct pvr2_ioread *cp,void __user *buf,unsigned int cnt) } } - } while (0); mutex_unlock(&cp->mutex); + } while (0); + mutex_unlock(&cp->mutex); if (!ret) { if (copied_cnt) { -- cgit v1.2.3-59-g8ed1b From e118120bd775f6a8718d4d9f2a42082a572fbc57 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 15:18:20 -0300 Subject: [media] cx25840: fix bad identing drivers/media/i2c/cx25840/cx25840-core.c:974 input_change() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab Acked-by: Lad, Prabhakar Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/cx25840/cx25840-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c index bd496447749a..18e3615737f2 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.c +++ b/drivers/media/i2c/cx25840/cx25840-core.c @@ -971,7 +971,7 @@ static void input_change(struct i2c_client *client) not used by any public broadcast network, force 6.5 MHz carrier to be interpreted as System DK, this avoids DK audio detection instability */ - cx25840_write(client, 0x80b, 0x00); + cx25840_write(client, 0x80b, 0x00); } else if (std & V4L2_STD_SECAM) { /* Autodetect audio standard and audio system */ cx25840_write(client, 0x808, 0xff); -- cgit v1.2.3-59-g8ed1b From 4e0b0036210daea5ec34c00bafd98e9457e93bcb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 15:41:45 -0300 Subject: [media] stv0900: fix bad indenting drivers/media/dvb-frontends/stv0900_sw.c:1559 stv0900_search_srate_fine() warn: inconsistent indenting drivers/media/dvb-frontends/stv0900_sw.c:2012 stv0900_algo() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv0900_sw.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/stv0900_sw.c b/drivers/media/dvb-frontends/stv0900_sw.c index a0a7b1664c53..fa63a9e929ce 100644 --- a/drivers/media/dvb-frontends/stv0900_sw.c +++ b/drivers/media/dvb-frontends/stv0900_sw.c @@ -1556,8 +1556,8 @@ static u32 stv0900_search_srate_fine(struct dvb_frontend *fe) } symbcomp = 13 * (coarse_srate / 10); - coarse_freq = (stv0900_read_reg(intp, CFR2) << 8) - | stv0900_read_reg(intp, CFR1); + coarse_freq = (stv0900_read_reg(intp, CFR2) << 8) + | stv0900_read_reg(intp, CFR1); if (symbcomp < intp->symbol_rate[demod]) coarse_srate = 0; @@ -2009,7 +2009,7 @@ enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe) signal_type = STV0900_NODATA; no_signal = stv0900_check_signal_presence(intp, demod); - intp->result[demod].locked = FALSE; + intp->result[demod].locked = FALSE; } } -- cgit v1.2.3-59-g8ed1b From 05a848ecbb06d2b6cc5fc86ca227862a83ea0183 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 15:46:24 -0300 Subject: [media] s5h1420: use only one statement per line drivers/media/dvb-frontends/s5h1420.c:565 s5h1420_setfec_inversion() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/s5h1420.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/s5h1420.c b/drivers/media/dvb-frontends/s5h1420.c index 0b4f8fe6bf99..dfc20665e372 100644 --- a/drivers/media/dvb-frontends/s5h1420.c +++ b/drivers/media/dvb-frontends/s5h1420.c @@ -561,27 +561,33 @@ static void s5h1420_setfec_inversion(struct s5h1420_state* state, } else { switch (p->fec_inner) { case FEC_1_2: - vit08 = 0x01; vit09 = 0x10; + vit08 = 0x01; + vit09 = 0x10; break; case FEC_2_3: - vit08 = 0x02; vit09 = 0x11; + vit08 = 0x02; + vit09 = 0x11; break; case FEC_3_4: - vit08 = 0x04; vit09 = 0x12; + vit08 = 0x04; + vit09 = 0x12; break; case FEC_5_6: - vit08 = 0x08; vit09 = 0x13; + vit08 = 0x08; + vit09 = 0x13; break; case FEC_6_7: - vit08 = 0x10; vit09 = 0x14; + vit08 = 0x10; + vit09 = 0x14; break; case FEC_7_8: - vit08 = 0x20; vit09 = 0x15; + vit08 = 0x20; + vit09 = 0x15; break; default: -- cgit v1.2.3-59-g8ed1b From b674ac290e47623aa8e6791aed2d7395f7ea313f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 15:48:10 -0300 Subject: [media] tda10086: change typecast to u64 to avoid smatch warnings drivers/media/dvb-frontends/tda10086.c:476 tda10086_get_frontend() warn: should 'tda10086_read_byte(state, 81) << 8' be a 64 bit type? Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/tda10086.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/tda10086.c b/drivers/media/dvb-frontends/tda10086.c index fcfe2e080cb0..f1a752187d08 100644 --- a/drivers/media/dvb-frontends/tda10086.c +++ b/drivers/media/dvb-frontends/tda10086.c @@ -472,8 +472,8 @@ static int tda10086_get_frontend(struct dvb_frontend *fe) return -EINVAL; /* calculate the updated frequency (note: we convert from Hz->kHz) */ - tmp64 = tda10086_read_byte(state, 0x52); - tmp64 |= (tda10086_read_byte(state, 0x51) << 8); + tmp64 = ((u64)tda10086_read_byte(state, 0x52) + | (tda10086_read_byte(state, 0x51) << 8)); if (tmp64 & 0x8000) tmp64 |= 0xffffffffffff0000ULL; tmp64 = (tmp64 * (SACLK/1000ULL)); -- cgit v1.2.3-59-g8ed1b From 3192e0064571b725115452d7c35105ce458dd51f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 20:06:07 -0300 Subject: [media] bttv: fix audio hooks as reported by smatch: drivers/media/pci/bt8xx/bttv-audio-hook.c:201 lt9415_audio() warn: bitwise AND condition is false here drivers/media/pci/bt8xx/bttv-audio-hook.c:241 winfast2000_audio() warn: bitwise AND condition is false here drivers/media/pci/bt8xx/bttv-audio-hook.c:276 pvbt878p9b_audio() warn: bitwise AND condition is false here drivers/media/pci/bt8xx/bttv-audio-hook.c:307 fv2000s_audio() warn: bitwise AND condition is false here drivers/media/pci/bt8xx/bttv-audio-hook.c:334 windvr_audio() warn: bitwise AND condition is false here drivers/media/pci/bt8xx/bttv-audio-hook.c:371 adtvk503_audio() warn: bitwise AND condition is false here there are some serious issues at the audio hook implementation. They're not following what's specified at the DocBook: http://linuxtv.org/downloads/v4l-dvb-apis/vidioc-g-tuner.html#tuner-audmode Basically, it was assuming that the audmode (V4L2_TUNER_MODE_foo) is a variable with a bit maskk. However, it isn't. The bitmask only applies to rxsubchans field (V4L2_TUNER_SUB_foo). As the code is also too complex, and not all hooks were returning both audmode and rxsubchans to a VIDIOC_G_TUNER, rewrite the functions, in order to fix both for get and set tuner ioctls. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-audio-hook.c | 443 +++++++++++++++++++----------- 1 file changed, 275 insertions(+), 168 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/bt8xx/bttv-audio-hook.c b/drivers/media/pci/bt8xx/bttv-audio-hook.c index 2364d16586b3..9f1f9169fb5b 100644 --- a/drivers/media/pci/bt8xx/bttv-audio-hook.c +++ b/drivers/media/pci/bt8xx/bttv-audio-hook.c @@ -54,23 +54,33 @@ void winview_volume(struct bttv *btv, __u16 volume) void gvbctv3pci_audio(struct bttv *btv, struct v4l2_tuner *t, int set) { - unsigned int con = 0; + unsigned int con; - if (set) { - gpio_inout(0x300, 0x300); - if (t->audmode & V4L2_TUNER_MODE_LANG1) - con = 0x000; - if (t->audmode & V4L2_TUNER_MODE_LANG2) - con = 0x300; - if (t->audmode & V4L2_TUNER_MODE_STEREO) - con = 0x200; -/* if (t->audmode & V4L2_TUNER_MODE_MONO) - * con = 0x100; */ - gpio_bits(0x300, con); - } else { - t->audmode = V4L2_TUNER_MODE_STEREO | - V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; + if (!set) { + /* Not much to do here */ + t->audmode = V4L2_TUNER_MODE_LANG1; + t->rxsubchans = V4L2_TUNER_SUB_MONO | + V4L2_TUNER_SUB_STEREO | + V4L2_TUNER_SUB_LANG1 | + V4L2_TUNER_SUB_LANG2; + + return; + } + + gpio_inout(0x300, 0x300); + switch (t->audmode) { + case V4L2_TUNER_MODE_LANG1: + default: + con = 0x000; + break; + case V4L2_TUNER_MODE_LANG2: + con = 0x300; + break; + case V4L2_TUNER_MODE_STEREO: + con = 0x200; + break; } + gpio_bits(0x300, con); } void gvbctv5pci_audio(struct bttv *btv, struct v4l2_tuner *t, int set) @@ -82,47 +92,51 @@ void gvbctv5pci_audio(struct bttv *btv, struct v4l2_tuner *t, int set) val = gpio_read(); if (set) { - con = 0x000; - if (t->audmode & V4L2_TUNER_MODE_LANG2) { - if (t->audmode & V4L2_TUNER_MODE_LANG1) { - /* LANG1 + LANG2 */ - con = 0x100; - } - else { - /* LANG2 */ - con = 0x300; - } + switch (t->audmode) { + case V4L2_TUNER_MODE_LANG2: + con = 0x300; + break; + case V4L2_TUNER_MODE_LANG1_LANG2: + con = 0x100; + break; + default: + con = 0x000; + break; } if (con != (val & 0x300)) { gpio_bits(0x300, con); if (bttv_gpio) - bttv_gpio_tracking(btv,"gvbctv5pci"); + bttv_gpio_tracking(btv, "gvbctv5pci"); } } else { switch (val & 0x70) { case 0x10: t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; + t->audmode = V4L2_TUNER_MODE_LANG1_LANG2; break; case 0x30: t->rxsubchans = V4L2_TUNER_SUB_LANG2; + t->audmode = V4L2_TUNER_MODE_LANG1_LANG2; break; case 0x50: t->rxsubchans = V4L2_TUNER_SUB_LANG1; + t->audmode = V4L2_TUNER_MODE_LANG1_LANG2; break; case 0x60: t->rxsubchans = V4L2_TUNER_SUB_STEREO; + t->audmode = V4L2_TUNER_MODE_STEREO; break; case 0x70: t->rxsubchans = V4L2_TUNER_SUB_MONO; + t->audmode = V4L2_TUNER_MODE_MONO; break; default: t->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; + t->audmode = V4L2_TUNER_MODE_LANG1; } - t->audmode = V4L2_TUNER_MODE_STEREO | - V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; } } @@ -142,23 +156,32 @@ void gvbctv5pci_audio(struct bttv *btv, struct v4l2_tuner *t, int set) void avermedia_tvphone_audio(struct bttv *btv, struct v4l2_tuner *t, int set) { - int val = 0; + int val; - if (set) { - if (t->audmode & V4L2_TUNER_MODE_LANG2) /* SAP */ - val = 0x02; - if (t->audmode & V4L2_TUNER_MODE_STEREO) - val = 0x01; - if (val) { - gpio_bits(0x03,val); - if (bttv_gpio) - bttv_gpio_tracking(btv,"avermedia"); - } - } else { - t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO | - V4L2_TUNER_MODE_LANG1; + if (!set) { + /* Not much to do here */ + t->audmode = V4L2_TUNER_MODE_LANG1; + t->rxsubchans = V4L2_TUNER_SUB_MONO | + V4L2_TUNER_SUB_STEREO | + V4L2_TUNER_SUB_LANG1 | + V4L2_TUNER_SUB_LANG2; + + return; + } + + switch (t->audmode) { + case V4L2_TUNER_MODE_LANG2: /* SAP */ + val = 0x02; + break; + case V4L2_TUNER_MODE_STEREO: + val = 0x01; + break; + default: return; } + gpio_bits(0x03, val); + if (bttv_gpio) + bttv_gpio_tracking(btv, "avermedia"); } @@ -166,19 +189,31 @@ void avermedia_tv_stereo_audio(struct bttv *btv, struct v4l2_tuner *t, int set) { int val = 0; - if (set) { - if (t->audmode & V4L2_TUNER_MODE_LANG2) /* SAP */ - val = 0x01; - if (t->audmode & V4L2_TUNER_MODE_STEREO) /* STEREO */ - val = 0x02; - btaor(val, ~0x03, BT848_GPIO_DATA); - if (bttv_gpio) - bttv_gpio_tracking(btv,"avermedia"); - } else { - t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO | - V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; + if (!set) { + /* Not much to do here */ + t->audmode = V4L2_TUNER_MODE_LANG1; + t->rxsubchans = V4L2_TUNER_SUB_MONO | + V4L2_TUNER_SUB_STEREO | + V4L2_TUNER_SUB_LANG1 | + V4L2_TUNER_SUB_LANG2; + return; } + + switch (t->audmode) { + case V4L2_TUNER_MODE_LANG2: /* SAP */ + val = 0x01; + break; + case V4L2_TUNER_MODE_STEREO: + val = 0x02; + break; + default: + val = 0; + break; + } + btaor(val, ~0x03, BT848_GPIO_DATA); + if (bttv_gpio) + bttv_gpio_tracking(btv, "avermedia"); } /* Lifetec 9415 handling */ @@ -192,23 +227,32 @@ void lt9415_audio(struct bttv *btv, struct v4l2_tuner *t, int set) return; } - if (set) { - if (t->audmode & V4L2_TUNER_MODE_LANG2) /* A2 SAP */ - val = 0x0080; - if (t->audmode & V4L2_TUNER_MODE_STEREO) /* A2 stereo */ - val = 0x0880; - if ((t->audmode & V4L2_TUNER_MODE_LANG1) || - (t->audmode & V4L2_TUNER_MODE_MONO)) - val = 0; - gpio_bits(0x0880, val); - if (bttv_gpio) - bttv_gpio_tracking(btv,"lt9415"); - } else { - /* autodetect doesn't work with this card :-( */ - t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO | - V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; + if (!set) { + /* Not much to do here */ + t->audmode = V4L2_TUNER_MODE_LANG1; + t->rxsubchans = V4L2_TUNER_SUB_MONO | + V4L2_TUNER_SUB_STEREO | + V4L2_TUNER_SUB_LANG1 | + V4L2_TUNER_SUB_LANG2; + return; } + + switch (t->audmode) { + case V4L2_TUNER_MODE_LANG2: /* A2 SAP */ + val = 0x0080; + break; + case V4L2_TUNER_MODE_STEREO: /* A2 stereo */ + val = 0x0880; + break; + default: + val = 0; + break; + } + + gpio_bits(0x0880, val); + if (bttv_gpio) + bttv_gpio_tracking(btv, "lt9415"); } /* TDA9821 on TerraTV+ Bt848, Bt878 */ @@ -216,45 +260,69 @@ void terratv_audio(struct bttv *btv, struct v4l2_tuner *t, int set) { unsigned int con = 0; - if (set) { - gpio_inout(0x180000,0x180000); - if (t->audmode & V4L2_TUNER_MODE_LANG2) - con = 0x080000; - if (t->audmode & V4L2_TUNER_MODE_STEREO) - con = 0x180000; - gpio_bits(0x180000, con); - if (bttv_gpio) - bttv_gpio_tracking(btv,"terratv"); - } else { - t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO | - V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; + if (!set) { + /* Not much to do here */ + t->audmode = V4L2_TUNER_MODE_LANG1; + t->rxsubchans = V4L2_TUNER_SUB_MONO | + V4L2_TUNER_SUB_STEREO | + V4L2_TUNER_SUB_LANG1 | + V4L2_TUNER_SUB_LANG2; + + return; + } + + gpio_inout(0x180000, 0x180000); + switch (t->audmode) { + case V4L2_TUNER_MODE_LANG2: + con = 0x080000; + break; + case V4L2_TUNER_MODE_STEREO: + con = 0x180000; + break; + default: + con = 0; + break; } + gpio_bits(0x180000, con); + if (bttv_gpio) + bttv_gpio_tracking(btv, "terratv"); } void winfast2000_audio(struct bttv *btv, struct v4l2_tuner *t, int set) { - unsigned long val = 0; + unsigned long val; - if (set) { - /*btor (0xc32000, BT848_GPIO_OUT_EN);*/ - if (t->audmode & V4L2_TUNER_MODE_MONO) /* Mono */ - val = 0x420000; - if (t->audmode & V4L2_TUNER_MODE_LANG1) /* Mono */ - val = 0x420000; - if (t->audmode & V4L2_TUNER_MODE_LANG2) /* SAP */ - val = 0x410000; - if (t->audmode & V4L2_TUNER_MODE_STEREO) /* Stereo */ - val = 0x020000; - if (val) { - gpio_bits(0x430000, val); - if (bttv_gpio) - bttv_gpio_tracking(btv,"winfast2000"); - } - } else { - t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO | - V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; + if (!set) { + /* Not much to do here */ + t->audmode = V4L2_TUNER_MODE_LANG1; + t->rxsubchans = V4L2_TUNER_SUB_MONO | + V4L2_TUNER_SUB_STEREO | + V4L2_TUNER_SUB_LANG1 | + V4L2_TUNER_SUB_LANG2; + + return; } + + /*btor (0xc32000, BT848_GPIO_OUT_EN);*/ + switch (t->audmode) { + case V4L2_TUNER_MODE_MONO: + case V4L2_TUNER_MODE_LANG1: + val = 0x420000; + break; + case V4L2_TUNER_MODE_LANG2: /* SAP */ + val = 0x410000; + break; + case V4L2_TUNER_MODE_STEREO: + val = 0x020000; + break; + default: + return; + } + + gpio_bits(0x430000, val); + if (bttv_gpio) + bttv_gpio_tracking(btv, "winfast2000"); } /* @@ -272,23 +340,33 @@ void pvbt878p9b_audio(struct bttv *btv, struct v4l2_tuner *t, int set) if (btv->radio_user) return; - if (set) { - if (t->audmode & V4L2_TUNER_MODE_MONO) { - val = 0x01; - } - if ((t->audmode & (V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2)) - || (t->audmode & V4L2_TUNER_MODE_STEREO)) { - val = 0x02; - } - if (val) { - gpio_bits(0x03,val); - if (bttv_gpio) - bttv_gpio_tracking(btv,"pvbt878p9b"); - } - } else { - t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO | - V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; + if (!set) { + /* Not much to do here */ + t->audmode = V4L2_TUNER_MODE_LANG1; + t->rxsubchans = V4L2_TUNER_SUB_MONO | + V4L2_TUNER_SUB_STEREO | + V4L2_TUNER_SUB_LANG1 | + V4L2_TUNER_SUB_LANG2; + + return; } + + switch (t->audmode) { + case V4L2_TUNER_MODE_MONO: + val = 0x01; + break; + case V4L2_TUNER_MODE_LANG1: + case V4L2_TUNER_MODE_LANG2: + case V4L2_TUNER_MODE_STEREO: + val = 0x02; + break; + default: + return; + } + + gpio_bits(0x03, val); + if (bttv_gpio) + bttv_gpio_tracking(btv, "pvbt878p9b"); } /* @@ -298,28 +376,37 @@ void pvbt878p9b_audio(struct bttv *btv, struct v4l2_tuner *t, int set) */ void fv2000s_audio(struct bttv *btv, struct v4l2_tuner *t, int set) { - unsigned int val = 0xffff; + unsigned int val; if (btv->radio_user) return; - if (set) { - if (t->audmode & V4L2_TUNER_MODE_MONO) { - val = 0x0000; - } - if ((t->audmode & (V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2)) - || (t->audmode & V4L2_TUNER_MODE_STEREO)) { - val = 0x1080; /*-dk-???: 0x0880, 0x0080, 0x1800 ... */ - } - if (val != 0xffff) { - gpio_bits(0x1800, val); - if (bttv_gpio) - bttv_gpio_tracking(btv,"fv2000s"); - } - } else { - t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO | - V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; + if (!set) { + /* Not much to do here */ + t->audmode = V4L2_TUNER_MODE_LANG1; + t->rxsubchans = V4L2_TUNER_SUB_MONO | + V4L2_TUNER_SUB_STEREO | + V4L2_TUNER_SUB_LANG1 | + V4L2_TUNER_SUB_LANG2; + + return; } + + switch (t->audmode) { + case V4L2_TUNER_MODE_MONO: + val = 0x0000; + break; + case V4L2_TUNER_MODE_LANG1: + case V4L2_TUNER_MODE_LANG2: + case V4L2_TUNER_MODE_STEREO: + val = 0x1080; /*-dk-???: 0x0880, 0x0080, 0x1800 ... */ + break; + default: + return; + } + gpio_bits(0x1800, val); + if (bttv_gpio) + bttv_gpio_tracking(btv, "fv2000s"); } /* @@ -328,26 +415,33 @@ void fv2000s_audio(struct bttv *btv, struct v4l2_tuner *t, int set) */ void windvr_audio(struct bttv *btv, struct v4l2_tuner *t, int set) { - unsigned long val = 0; + unsigned long val; - if (set) { - if (t->audmode & V4L2_TUNER_MODE_MONO) - val = 0x040000; - if (t->audmode & V4L2_TUNER_MODE_LANG1) - val = 0; - if (t->audmode & V4L2_TUNER_MODE_LANG2) - val = 0x100000; - if (t->audmode & V4L2_TUNER_MODE_STEREO) - val = 0; - if (val) { - gpio_bits(0x140000, val); - if (bttv_gpio) - bttv_gpio_tracking(btv,"windvr"); - } - } else { - t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO | - V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; + if (!set) { + /* Not much to do here */ + t->audmode = V4L2_TUNER_MODE_LANG1; + t->rxsubchans = V4L2_TUNER_SUB_MONO | + V4L2_TUNER_SUB_STEREO | + V4L2_TUNER_SUB_LANG1 | + V4L2_TUNER_SUB_LANG2; + + return; + } + + switch (t->audmode) { + case V4L2_TUNER_MODE_MONO: + val = 0x040000; + break; + case V4L2_TUNER_MODE_LANG2: + val = 0x100000; + break; + default: + return; } + + gpio_bits(0x140000, val); + if (bttv_gpio) + bttv_gpio_tracking(btv, "windvr"); } /* @@ -360,23 +454,36 @@ void adtvk503_audio(struct bttv *btv, struct v4l2_tuner *t, int set) /* btaor(0x1e0000, ~0x1e0000, BT848_GPIO_OUT_EN); */ - if (set) { - /* btor(***, BT848_GPIO_OUT_EN); */ - if (t->audmode & V4L2_TUNER_MODE_LANG1) - con = 0x00000000; - if (t->audmode & V4L2_TUNER_MODE_LANG2) - con = 0x00180000; - if (t->audmode & V4L2_TUNER_MODE_STEREO) - con = 0x00000000; - if (t->audmode & V4L2_TUNER_MODE_MONO) - con = 0x00060000; - if (con != 0xffffff) { - gpio_bits(0x1e0000,con); - if (bttv_gpio) - bttv_gpio_tracking(btv, "adtvk503"); - } - } else { - t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO | - V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; + if (!set) { + /* Not much to do here */ + t->audmode = V4L2_TUNER_MODE_LANG1; + t->rxsubchans = V4L2_TUNER_SUB_MONO | + V4L2_TUNER_SUB_STEREO | + V4L2_TUNER_SUB_LANG1 | + V4L2_TUNER_SUB_LANG2; + + return; } + + /* btor(***, BT848_GPIO_OUT_EN); */ + switch (t->audmode) { + case V4L2_TUNER_MODE_LANG1: + con = 0x00000000; + break; + case V4L2_TUNER_MODE_LANG2: + con = 0x00180000; + break; + case V4L2_TUNER_MODE_STEREO: + con = 0x00000000; + break; + case V4L2_TUNER_MODE_MONO: + con = 0x00060000; + break; + default: + return; + } + + gpio_bits(0x1e0000, con); + if (bttv_gpio) + bttv_gpio_tracking(btv, "adtvk503"); } -- cgit v1.2.3-59-g8ed1b From 3ff105ed9fa7e5f33ac12871d830477d89871cb7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 17:09:50 -0300 Subject: [media] ttusb-dec: fix bad indentation drivers/media/usb/ttusb-dec/ttusb_dec.c:1434 ttusb_dec_init_stb() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/ttusb-dec/ttusb_dec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c index 15ab584cf265..322b53a4f1dd 100644 --- a/drivers/media/usb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c @@ -1431,8 +1431,8 @@ static int ttusb_dec_init_stb(struct ttusb_dec *dec) __func__, model); return -ENOENT; } - if (version >= 0x01770000) - dec->can_playback = 1; + if (version >= 0x01770000) + dec->can_playback = 1; } return 0; } -- cgit v1.2.3-59-g8ed1b From 69148bcd23cba0b4f457631847dda30560623449 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 17:10:47 -0300 Subject: [media] s5p-mfc: fix bad indentation drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c:187 s5p_mfc_alloc_codec_buffers_v5() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c index b09bcd140491..c7adc3d26792 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c @@ -184,7 +184,7 @@ static int s5p_mfc_alloc_codec_buffers_v5(struct s5p_mfc_ctx *ctx) ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_r, &ctx->bank2); if (ret) { mfc_err("Failed to allocate Bank2 temporary buffer\n"); - s5p_mfc_release_priv_buf(ctx->dev->mem_dev_l, &ctx->bank1); + s5p_mfc_release_priv_buf(ctx->dev->mem_dev_l, &ctx->bank1); return ret; } BUG_ON(ctx->bank2.dma & ((1 << MFC_BANK2_ALIGN_ORDER) - 1)); -- cgit v1.2.3-59-g8ed1b From ff1522d54618504e622db5757774a9f4349ea770 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 17:11:35 -0300 Subject: [media] usbvision: fix bad indentation drivers/media/usb/usbvision/usbvision-core.c:2395 usbvision_init_isoc() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/usbvision/usbvision-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/usbvision/usbvision-core.c b/drivers/media/usb/usbvision/usbvision-core.c index 44b0c28d69b6..7c04ef697fb6 100644 --- a/drivers/media/usb/usbvision/usbvision-core.c +++ b/drivers/media/usb/usbvision/usbvision-core.c @@ -2390,8 +2390,8 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) /* Submit all URBs */ for (buf_idx = 0; buf_idx < USBVISION_NUMSBUF; buf_idx++) { - err_code = usb_submit_urb(usbvision->sbuf[buf_idx].urb, - GFP_KERNEL); + err_code = usb_submit_urb(usbvision->sbuf[buf_idx].urb, + GFP_KERNEL); if (err_code) { dev_err(&usbvision->dev->dev, "%s: usb_submit_urb(%d) failed: error %d\n", -- cgit v1.2.3-59-g8ed1b From 3c2580f9ff6d6ec1d07a55bfbea8c69158f442be Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 17:14:31 -0300 Subject: [media] saa7134: fix bad indenting drivers/media/pci/saa7134/saa7134-dvb.c:1682 dvb_init() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-dvb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7134/saa7134-dvb.c b/drivers/media/pci/saa7134/saa7134-dvb.c index 73ffbabf831c..bcfebd56fa2b 100644 --- a/drivers/media/pci/saa7134/saa7134-dvb.c +++ b/drivers/media/pci/saa7134/saa7134-dvb.c @@ -1679,7 +1679,7 @@ static int dvb_init(struct saa7134_dev *dev) &dev->i2c_adap, 0, 0) == NULL) { wprintk("%s: Asus Tiger 3in1, no lnbp21" " found!\n", __func__); - goto detach_frontend; + goto detach_frontend; } } } -- cgit v1.2.3-59-g8ed1b From 316c46b8f3468199b106e1c5e334b22bd34d0985 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 17:16:27 -0300 Subject: [media] dib0700: fix bad indentation drivers/media/usb/dvb-usb/dib0700_devices.c:864 dib7770_set_param_override() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/dib0700_devices.c | 32 ++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c index d7d55a20e959..90cee380d3aa 100644 --- a/drivers/media/usb/dvb-usb/dib0700_devices.c +++ b/drivers/media/usb/dvb-usb/dib0700_devices.c @@ -861,22 +861,22 @@ static int dib7770_set_param_override(struct dvb_frontend *fe) struct dvb_usb_adapter *adap = fe->dvb->priv; struct dib0700_adapter_state *state = adap->priv; - u16 offset; - u8 band = BAND_OF_FREQUENCY(p->frequency/1000); - switch (band) { - case BAND_VHF: - state->dib7000p_ops.set_gpio(fe, 0, 0, 1); - offset = 850; - break; - case BAND_UHF: - default: - state->dib7000p_ops.set_gpio(fe, 0, 0, 0); - offset = 250; - break; - } - deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe)); - state->dib7000p_ops.set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); - return state->set_param_save(fe); + u16 offset; + u8 band = BAND_OF_FREQUENCY(p->frequency/1000); + switch (band) { + case BAND_VHF: + state->dib7000p_ops.set_gpio(fe, 0, 0, 1); + offset = 850; + break; + case BAND_UHF: + default: + state->dib7000p_ops.set_gpio(fe, 0, 0, 0); + offset = 250; + break; + } + deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe)); + state->dib7000p_ops.set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); + return state->set_param_save(fe); } static int dib7770p_tuner_attach(struct dvb_usb_adapter *adap) -- cgit v1.2.3-59-g8ed1b From ab4bc55ebd6d8f37674b0f0b228e643c118da3e0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 17:17:24 -0300 Subject: [media] af9005: fix bad indenting drivers/media/usb/dvb-usb/af9005-fe.c:484 af9005_fe_read_status() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/af9005-fe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb/af9005-fe.c b/drivers/media/usb/dvb-usb/af9005-fe.c index 740f3f496f12..6e84a546dfdc 100644 --- a/drivers/media/usb/dvb-usb/af9005-fe.c +++ b/drivers/media/usb/dvb-usb/af9005-fe.c @@ -481,7 +481,7 @@ static int af9005_fe_read_status(struct dvb_frontend *fe, fe_status_t * stat) return ret; if (temp != state->strong) { deb_info("adjust for strong signal %d\n", temp); - state->strong = temp; + state->strong = temp; } return 0; } -- cgit v1.2.3-59-g8ed1b From 48902bc7d0ca096da7ca17ad1428c370ed97f61b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 20:19:20 -0300 Subject: [media] dw2102: fix bad indenting drivers/media/usb/dvb-usb/dw2102.c:440 dw2104_i2c_transfer() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/dw2102.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c index f1f357f43ff0..28fd6bacb852 100644 --- a/drivers/media/usb/dvb-usb/dw2102.c +++ b/drivers/media/usb/dvb-usb/dw2102.c @@ -437,7 +437,7 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i ibuf, msg[j].len + 2, DW210X_READ_MSG); memcpy(msg[j].buf, ibuf + 2, msg[j].len); - mdelay(10); + mdelay(10); } else if (((msg[j].buf[0] == 0xb0) && (msg[j].addr == 0x68)) || ((msg[j].buf[0] == 0xf7) && -- cgit v1.2.3-59-g8ed1b From cd65d24e0373db95931c8542636aaa9ad1719e74 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 20:22:20 -0300 Subject: [media] xirlink_cit: comment unreachable code drivers/media/usb/gspca/xirlink_cit.c:1776 cit_start_model2() info: ignoring unreachable code. drivers/media/usb/gspca/xirlink_cit.c:1858 cit_start_model2() info: ignoring unreachable code. drivers/media/usb/gspca/xirlink_cit.c:1910 cit_start_model2() info: ignoring unreachable code. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/gspca/xirlink_cit.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/gspca/xirlink_cit.c b/drivers/media/usb/gspca/xirlink_cit.c index a41aa7817c54..d5ed9d36ce25 100644 --- a/drivers/media/usb/gspca/xirlink_cit.c +++ b/drivers/media/usb/gspca/xirlink_cit.c @@ -1772,7 +1772,8 @@ static int cit_start_model2(struct gspca_dev *gspca_dev) cit_write_reg(gspca_dev, 0x0070, 0x0119); /* All except 176x144 */ sd->sof_len = 2; break; - /* case VIDEOSIZE_352x240: */ +#if 0 + case VIDEOSIZE_352x240: cit_write_reg(gspca_dev, 0x002c, 0x0103); /* All except 320x240 */ cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */ cit_write_reg(gspca_dev, 0x001e, 0x0105); /* 320x240, 352x240 */ @@ -1780,6 +1781,7 @@ static int cit_start_model2(struct gspca_dev *gspca_dev) cit_write_reg(gspca_dev, 0x0070, 0x0119); /* All except 176x144 */ sd->sof_len = 2; break; +#endif case 352: /* 352x288 */ cit_write_reg(gspca_dev, 0x002c, 0x0103); /* All except 320x240 */ cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */ @@ -1853,13 +1855,15 @@ static int cit_start_model2(struct gspca_dev *gspca_dev) cit_model2_Packet1(gspca_dev, 0x0018, 0x0044); /* Another hardware setting */ clock_div = 8; break; - /* case VIDEOSIZE_352x240: */ +#if 0 + case VIDEOSIZE_352x240: /* This mode doesn't work as Windows programs it; changed to work */ cit_model2_Packet1(gspca_dev, 0x0014, 0x0009); /* Windows sets this to 8 */ cit_model2_Packet1(gspca_dev, 0x0016, 0x0003); /* Horizontal shift */ cit_model2_Packet1(gspca_dev, 0x0018, 0x0044); /* Windows sets this to 0x0045 */ clock_div = 10; break; +#endif case 352: /* 352x288 */ cit_model2_Packet1(gspca_dev, 0x0014, 0x0003); cit_model2_Packet1(gspca_dev, 0x0016, 0x0002); /* Horizontal shift */ @@ -1906,9 +1910,11 @@ static int cit_start_model2(struct gspca_dev *gspca_dev) case 320: /* 320x240 */ cit_model2_Packet1(gspca_dev, 0x0026, 0x0044); break; - /* case VIDEOSIZE_352x240: */ +#if 0 + case VIDEOSIZE_352x240: cit_model2_Packet1(gspca_dev, 0x0026, 0x0046); break; +#endif case 352: /* 352x288 */ cit_model2_Packet1(gspca_dev, 0x0026, 0x0048); break; -- cgit v1.2.3-59-g8ed1b From ee120ae03b22d56dbd4194e90d9d23ead4dcc2f0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 20:24:56 -0300 Subject: [media] vivid: fix bad indenting drivers/media/platform/vivid/vivid-vid-out.c:1155 vivid_vid_out_g_parm() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-vid-out.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/vivid/vivid-vid-out.c b/drivers/media/platform/vivid/vivid-vid-out.c index 0af43dc7715c..00f42df947c0 100644 --- a/drivers/media/platform/vivid/vivid-vid-out.c +++ b/drivers/media/platform/vivid/vivid-vid-out.c @@ -1152,7 +1152,8 @@ int vivid_vid_out_g_parm(struct file *file, void *priv, parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME; parm->parm.output.timeperframe = dev->timeperframe_vid_out; parm->parm.output.writebuffers = 1; -return 0; + + return 0; } int vidioc_subscribe_event(struct v4l2_fh *fh, -- cgit v1.2.3-59-g8ed1b From d5fbbb762bb51484bef3aecfddf0a31c2e708450 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 20:29:10 -0300 Subject: [media] cx23885: fix bad indentation drivers/media/pci/cx23885/altera-ci.c:762 altera_ci_init() warn: inconsistent indenting Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/altera-ci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/cx23885/altera-ci.c b/drivers/media/pci/cx23885/altera-ci.c index 0a91df2c9f08..aaf4e46ff3e9 100644 --- a/drivers/media/pci/cx23885/altera-ci.c +++ b/drivers/media/pci/cx23885/altera-ci.c @@ -759,7 +759,7 @@ int altera_ci_init(struct altera_ci_config *config, int ci_nr) if (0 != ret) goto err; - inter->state[ci_nr - 1] = state; + inter->state[ci_nr - 1] = state; altera_hw_filt_init(config, ci_nr); -- cgit v1.2.3-59-g8ed1b From 82f72c53813da40303214f4c4d65122b2c1ccc41 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 29 Apr 2015 20:32:48 -0300 Subject: [media] m2m-deinterlace: remove dead code As reported by smatch: drivers/media/platform/m2m-deinterlace.c:1063 deinterlace_probe() info: ignoring unreachable code. There's no need to call v4l2_m2m_release() here, as the last possible failure in this code is to allocate the m2m struct. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/m2m-deinterlace.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/m2m-deinterlace.c b/drivers/media/platform/m2m-deinterlace.c index 92d954973ccf..c07f367aa436 100644 --- a/drivers/media/platform/m2m-deinterlace.c +++ b/drivers/media/platform/m2m-deinterlace.c @@ -1060,7 +1060,6 @@ static int deinterlace_probe(struct platform_device *pdev) return 0; - v4l2_m2m_release(pcdev->m2m_dev); err_m2m: video_unregister_device(&pcdev->vfd); err_ctx: -- cgit v1.2.3-59-g8ed1b From ba3002045f8022f3a7e88511c4ebd9876a467ac8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 20 Mar 2015 09:05:22 -0300 Subject: [media] v4l2-ioctl: fill in the description for VIDIOC_ENUM_FMT The descriptions used in drivers for the formats returned with ENUM_FMT are all over the place. So instead allow the core to fill them in if the driver didn't. This allows drivers to drop the description and flags. Based on an earlier patch from Philipp Zabel: http://comments.gmane.org/gmane.linux.drivers.video-input-infrastructure/81411 Signed-off-by: Hans Verkuil Acked-by: Philipp Zabel Acked-by: Laurent Pinchart Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ioctl.c | 199 +++++++++++++++++++++++++++++++++-- 1 file changed, 192 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index aa407cb5f830..24dc45fb2a52 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1103,6 +1103,182 @@ static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops, return ops->vidioc_enum_output(file, fh, p); } +static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) +{ + const unsigned sz = sizeof(fmt->description); + const char *descr = NULL; + u32 flags = 0; + + /* + * We depart from the normal coding style here since the descriptions + * should be aligned so it is easy to see which descriptions will be + * longer than 31 characters (the max length for a description). + * And frankly, this is easier to read anyway. + * + * Note that gcc will use O(log N) comparisons to find the right case. + */ + switch (fmt->pixelformat) { + /* Max description length mask: descr = "0123456789012345678901234567890" */ + case V4L2_PIX_FMT_RGB332: descr = "8-bit RGB 3-3-2"; break; + case V4L2_PIX_FMT_RGB444: descr = "16-bit A/XRGB 4-4-4-4"; break; + case V4L2_PIX_FMT_ARGB444: descr = "16-bit ARGB 4-4-4-4"; break; + case V4L2_PIX_FMT_XRGB444: descr = "16-bit XRGB 4-4-4-4"; break; + case V4L2_PIX_FMT_RGB555: descr = "16-bit A/XRGB 1-5-5-5"; break; + case V4L2_PIX_FMT_ARGB555: descr = "16-bit ARGB 1-5-5-5"; break; + case V4L2_PIX_FMT_XRGB555: descr = "16-bit XRGB 1-5-5-5"; break; + case V4L2_PIX_FMT_RGB565: descr = "16-bit RGB 5-6-5"; break; + case V4L2_PIX_FMT_RGB555X: descr = "16-bit A/XRGB 1-5-5-5 BE"; break; + case V4L2_PIX_FMT_ARGB555X: descr = "16-bit ARGB 1-5-5-5 BE"; break; + case V4L2_PIX_FMT_XRGB555X: descr = "16-bit XRGB 1-5-5-5 BE"; break; + case V4L2_PIX_FMT_RGB565X: descr = "16-bit RGB 5-6-5 BE"; break; + case V4L2_PIX_FMT_BGR666: descr = "18-bit BGRX 6-6-6-14"; break; + case V4L2_PIX_FMT_BGR24: descr = "24-bit BGR 8-8-8"; break; + case V4L2_PIX_FMT_RGB24: descr = "24-bit RGB 8-8-8"; break; + case V4L2_PIX_FMT_BGR32: descr = "32-bit BGRA/X 8-8-8-8"; break; + case V4L2_PIX_FMT_ABGR32: descr = "32-bit BGRA 8-8-8-8"; break; + case V4L2_PIX_FMT_XBGR32: descr = "32-bit BGRX 8-8-8-8"; break; + case V4L2_PIX_FMT_RGB32: descr = "32-bit A/XRGB 8-8-8-8"; break; + case V4L2_PIX_FMT_ARGB32: descr = "32-bit ARGB 8-8-8-8"; break; + case V4L2_PIX_FMT_XRGB32: descr = "32-bit XRGB 8-8-8-8"; break; + case V4L2_PIX_FMT_GREY: descr = "8-bit Greyscale"; break; + case V4L2_PIX_FMT_Y4: descr = "4-bit Greyscale"; break; + case V4L2_PIX_FMT_Y6: descr = "6-bit Greyscale"; break; + case V4L2_PIX_FMT_Y10: descr = "10-bit Greyscale"; break; + case V4L2_PIX_FMT_Y12: descr = "12-bit Greyscale"; break; + case V4L2_PIX_FMT_Y16: descr = "16-bit Greyscale"; break; + case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; break; + case V4L2_PIX_FMT_PAL8: descr = "8-bit Palette"; break; + case V4L2_PIX_FMT_UV8: descr = "8-bit Chrominance UV 4-4"; break; + case V4L2_PIX_FMT_YVU410: descr = "Planar YVU 4:1:0"; break; + case V4L2_PIX_FMT_YVU420: descr = "Planar YVU 4:2:0"; break; + case V4L2_PIX_FMT_YUYV: descr = "YUYV 4:2:2"; break; + case V4L2_PIX_FMT_YYUV: descr = "YYUV 4:2:2"; break; + case V4L2_PIX_FMT_YVYU: descr = "YVYU 4:2:2"; break; + case V4L2_PIX_FMT_UYVY: descr = "UYVY 4:2:2"; break; + case V4L2_PIX_FMT_VYUY: descr = "VYUY 4:2:2"; break; + case V4L2_PIX_FMT_YUV422P: descr = "Planar YVU 4:2:2"; break; + case V4L2_PIX_FMT_YUV411P: descr = "Planar YUV 4:1:1"; break; + case V4L2_PIX_FMT_Y41P: descr = "YUV 4:1:1 (Packed)"; break; + case V4L2_PIX_FMT_YUV444: descr = "16-bit A/XYUV 4-4-4-4"; break; + case V4L2_PIX_FMT_YUV555: descr = "16-bit A/XYUV 1-5-5-5"; break; + case V4L2_PIX_FMT_YUV565: descr = "16-bit YUV 5-6-5"; break; + case V4L2_PIX_FMT_YUV32: descr = "32-bit A/XYUV 8-8-8-8"; break; + case V4L2_PIX_FMT_YUV410: descr = "Planar YUV 4:1:0"; break; + case V4L2_PIX_FMT_YUV420: descr = "Planar YUV 4:2:0"; break; + case V4L2_PIX_FMT_HI240: descr = "8-bit Dithered RGB (BTTV)"; break; + case V4L2_PIX_FMT_HM12: descr = "YUV 4:2:0 (16x16 Macroblocks)"; break; + case V4L2_PIX_FMT_M420: descr = "YUV 4:2:0 (M420)"; break; + case V4L2_PIX_FMT_NV12: descr = "Y/CbCr 4:2:0"; break; + case V4L2_PIX_FMT_NV21: descr = "Y/CrCb 4:2:0"; break; + case V4L2_PIX_FMT_NV16: descr = "Y/CbCr 4:2:2"; break; + case V4L2_PIX_FMT_NV61: descr = "Y/CrCb 4:2:2"; break; + case V4L2_PIX_FMT_NV24: descr = "Y/CbCr 4:4:4"; break; + case V4L2_PIX_FMT_NV42: descr = "Y/CrCb 4:4:4"; break; + case V4L2_PIX_FMT_NV12M: descr = "Y/CbCr 4:2:0 (N-C)"; break; + case V4L2_PIX_FMT_NV21M: descr = "Y/CrCb 4:2:0 (N-C)"; break; + case V4L2_PIX_FMT_NV16M: descr = "Y/CbCr 4:2:2 (N-C)"; break; + case V4L2_PIX_FMT_NV61M: descr = "Y/CrCb 4:2:2 (N-C)"; break; + case V4L2_PIX_FMT_NV12MT: descr = "Y/CbCr 4:2:0 (64x32 MB, N-C)"; break; + case V4L2_PIX_FMT_NV12MT_16X16: descr = "Y/CbCr 4:2:0 (16x16 MB, N-C)"; break; + case V4L2_PIX_FMT_YUV420M: descr = "Planar YUV 4:2:0 (N-C)"; break; + case V4L2_PIX_FMT_YVU420M: descr = "Planar YVU 4:2:0 (N-C)"; break; + case V4L2_PIX_FMT_SBGGR8: descr = "8-bit Bayer BGBG/GRGR"; break; + case V4L2_PIX_FMT_SGBRG8: descr = "8-bit Bayer GBGB/RGRG"; break; + case V4L2_PIX_FMT_SGRBG8: descr = "8-bit Bayer GRGR/BGBG"; break; + case V4L2_PIX_FMT_SRGGB8: descr = "8-bit Bayer RGRG/GBGB"; break; + case V4L2_PIX_FMT_SBGGR10: descr = "10-bit Bayer BGBG/GRGR"; break; + case V4L2_PIX_FMT_SGBRG10: descr = "10-bit Bayer GBGB/RGRG"; break; + case V4L2_PIX_FMT_SGRBG10: descr = "10-bit Bayer GRGR/BGBG"; break; + case V4L2_PIX_FMT_SRGGB10: descr = "10-bit Bayer RGRG/GBGB"; break; + case V4L2_PIX_FMT_SBGGR12: descr = "12-bit Bayer BGBG/GRGR"; break; + case V4L2_PIX_FMT_SGBRG12: descr = "12-bit Bayer GBGB/RGRG"; break; + case V4L2_PIX_FMT_SGRBG12: descr = "12-bit Bayer GRGR/BGBG"; break; + case V4L2_PIX_FMT_SRGGB12: descr = "12-bit Bayer RGRG/GBGB"; break; + case V4L2_PIX_FMT_SBGGR10P: descr = "10-bit Bayer BGBG/GRGR Packed"; break; + case V4L2_PIX_FMT_SGBRG10P: descr = "10-bit Bayer GBGB/RGRG Packed"; break; + case V4L2_PIX_FMT_SGRBG10P: descr = "10-bit Bayer GRGR/BGBG Packed"; break; + case V4L2_PIX_FMT_SRGGB10P: descr = "10-bit Bayer RGRG/GBGB Packed"; break; + case V4L2_PIX_FMT_SBGGR10ALAW8: descr = "8-bit Bayer BGBG/GRGR (A-law)"; break; + case V4L2_PIX_FMT_SGBRG10ALAW8: descr = "8-bit Bayer GBGB/RGRG (A-law)"; break; + case V4L2_PIX_FMT_SGRBG10ALAW8: descr = "8-bit Bayer GRGR/BGBG (A-law)"; break; + case V4L2_PIX_FMT_SRGGB10ALAW8: descr = "8-bit Bayer RGRG/GBGB (A-law)"; break; + case V4L2_PIX_FMT_SBGGR10DPCM8: descr = "8-bit Bayer BGBG/GRGR (DPCM)"; break; + case V4L2_PIX_FMT_SGBRG10DPCM8: descr = "8-bit Bayer GBGB/RGRG (DPCM)"; break; + case V4L2_PIX_FMT_SGRBG10DPCM8: descr = "8-bit Bayer GRGR/BGBG (DPCM)"; break; + case V4L2_PIX_FMT_SRGGB10DPCM8: descr = "8-bit Bayer RGRG/GBGB (DPCM)"; break; + case V4L2_PIX_FMT_SBGGR16: descr = "16-bit Bayer BGBG/GRGR (Exp.)"; break; + case V4L2_PIX_FMT_SN9C20X_I420: descr = "GSPCA SN9C20X I420"; + case V4L2_PIX_FMT_SPCA501: descr = "GSPCA SPCA501"; break; + case V4L2_PIX_FMT_SPCA505: descr = "GSPCA SPCA505"; break; + case V4L2_PIX_FMT_SPCA508: descr = "GSPCA SPCA508"; break; + case V4L2_PIX_FMT_STV0680: descr = "GSPCA STV0680"; break; + case V4L2_PIX_FMT_TM6000: descr = "A/V + VBI Mux Packet"; break; + case V4L2_PIX_FMT_CIT_YYVYUY: descr = "GSPCA CIT YYVYUY"; break; + case V4L2_PIX_FMT_KONICA420: descr = "GSPCA KONICA420"; break; + case V4L2_SDR_FMT_CU8: descr = "Complex U8 (Emulated)"; break; + case V4L2_SDR_FMT_CU16LE: descr = "Complex U16LE (Emulated)"; break; + case V4L2_SDR_FMT_CS8: descr = "Complex S8"; break; + case V4L2_SDR_FMT_CS14LE: descr = "Complex S14LE"; break; + case V4L2_SDR_FMT_RU12LE: descr = "Real U12LE"; break; + + default: + /* Compressed formats */ + flags = V4L2_FMT_FLAG_COMPRESSED; + switch (fmt->pixelformat) { + /* Max description length mask: descr = "0123456789012345678901234567890" */ + case V4L2_PIX_FMT_MJPEG: descr = "Motion-JPEG"; break; + case V4L2_PIX_FMT_JPEG: descr = "JFIF JPEG"; break; + case V4L2_PIX_FMT_DV: descr = "1394"; break; + case V4L2_PIX_FMT_MPEG: descr = "MPEG-1/2/4"; break; + case V4L2_PIX_FMT_H264: descr = "H.264"; break; + case V4L2_PIX_FMT_H264_NO_SC: descr = "H.264 (No Start Codes)"; break; + case V4L2_PIX_FMT_H264_MVC: descr = "H.264 MVC"; break; + case V4L2_PIX_FMT_H263: descr = "H.263"; break; + case V4L2_PIX_FMT_MPEG1: descr = "MPEG-1 ES"; break; + case V4L2_PIX_FMT_MPEG2: descr = "MPEG-2 ES"; break; + case V4L2_PIX_FMT_MPEG4: descr = "MPEG-4 part 2 ES"; break; + case V4L2_PIX_FMT_XVID: descr = "Xvid"; break; + case V4L2_PIX_FMT_VC1_ANNEX_G: descr = "VC-1 (SMPTE 412M Annex G)"; break; + case V4L2_PIX_FMT_VC1_ANNEX_L: descr = "VC-1 (SMPTE 412M Annex L)"; break; + case V4L2_PIX_FMT_VP8: descr = "VP8"; break; + case V4L2_PIX_FMT_CPIA1: descr = "GSPCA CPiA YUV"; break; + case V4L2_PIX_FMT_WNVA: descr = "WNVA"; break; + case V4L2_PIX_FMT_SN9C10X: descr = "GSPCA SN9C10X"; break; + case V4L2_PIX_FMT_PWC1: descr = "Raw Philips Webcam Type (Old)"; break; + case V4L2_PIX_FMT_PWC2: descr = "Raw Philips Webcam Type (New)"; break; + case V4L2_PIX_FMT_ET61X251: descr = "GSPCA ET61X251"; break; + case V4L2_PIX_FMT_SPCA561: descr = "GSPCA SPCA561"; break; + case V4L2_PIX_FMT_PAC207: descr = "GSPCA PAC207"; break; + case V4L2_PIX_FMT_MR97310A: descr = "GSPCA MR97310A"; break; + case V4L2_PIX_FMT_JL2005BCD: descr = "GSPCA JL2005BCD"; break; + case V4L2_PIX_FMT_SN9C2028: descr = "GSPCA SN9C2028"; break; + case V4L2_PIX_FMT_SQ905C: descr = "GSPCA SQ905C"; break; + case V4L2_PIX_FMT_PJPG: descr = "GSPCA PJPG"; break; + case V4L2_PIX_FMT_OV511: descr = "GSPCA OV511"; break; + case V4L2_PIX_FMT_OV518: descr = "GSPCA OV518"; break; + case V4L2_PIX_FMT_JPGL: descr = "JPEG Lite"; break; + case V4L2_PIX_FMT_SE401: descr = "GSPCA SE401"; break; + case V4L2_PIX_FMT_S5C_UYVY_JPG: descr = "S5C73MX interleaved UYVY/JPEG"; break; + default: + WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat); + if (fmt->description[0]) + return; + flags = 0; + snprintf(fmt->description, sz, "%c%c%c%c%s", + (char)(fmt->pixelformat & 0x7f), + (char)((fmt->pixelformat >> 8) & 0x7f), + (char)((fmt->pixelformat >> 16) & 0x7f), + (char)((fmt->pixelformat >> 24) & 0x7f), + (fmt->pixelformat & (1 << 31)) ? "-BE" : ""); + break; + } + } + + if (descr) + WARN_ON(strlcpy(fmt->description, descr, sz) >= sz); + fmt->flags = flags; +} + static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops, struct file *file, void *fh, void *arg) { @@ -1112,34 +1288,43 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops, bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR; bool is_rx = vfd->vfl_dir != VFL_DIR_TX; bool is_tx = vfd->vfl_dir != VFL_DIR_RX; + int ret = -EINVAL; switch (p->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_cap)) break; - return ops->vidioc_enum_fmt_vid_cap(file, fh, arg); + ret = ops->vidioc_enum_fmt_vid_cap(file, fh, arg); + break; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_cap_mplane)) break; - return ops->vidioc_enum_fmt_vid_cap_mplane(file, fh, arg); + ret = ops->vidioc_enum_fmt_vid_cap_mplane(file, fh, arg); + break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_overlay)) break; - return ops->vidioc_enum_fmt_vid_overlay(file, fh, arg); + ret = ops->vidioc_enum_fmt_vid_overlay(file, fh, arg); + break; case V4L2_BUF_TYPE_VIDEO_OUTPUT: if (unlikely(!is_tx || !is_vid || !ops->vidioc_enum_fmt_vid_out)) break; - return ops->vidioc_enum_fmt_vid_out(file, fh, arg); + ret = ops->vidioc_enum_fmt_vid_out(file, fh, arg); + break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: if (unlikely(!is_tx || !is_vid || !ops->vidioc_enum_fmt_vid_out_mplane)) break; - return ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg); + ret = ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg); + break; case V4L2_BUF_TYPE_SDR_CAPTURE: if (unlikely(!is_rx || !is_sdr || !ops->vidioc_enum_fmt_sdr_cap)) break; - return ops->vidioc_enum_fmt_sdr_cap(file, fh, arg); + ret = ops->vidioc_enum_fmt_sdr_cap(file, fh, arg); + break; } - return -EINVAL; + if (ret == 0) + v4l_fill_fmtdesc(p); + return ret; } static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops, -- cgit v1.2.3-59-g8ed1b From 99b7427761fe6381932a188a417ff4c47515b72e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 1 May 2015 06:54:03 -0300 Subject: v4l2-ioctl: add a missing break at v4l_fill_fmtdesc() The changeset ba3002045f8022 added a logic at the core to fill the format description, however, a break is missing on one of the formats, as reported by smatch: drivers/media/v4l2-core/v4l2-ioctl.c:1211 v4l_fill_fmtdesc() warn: missing break? reassigning 'descr' Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 24dc45fb2a52..14766029bf49 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1207,7 +1207,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_SGRBG10DPCM8: descr = "8-bit Bayer GRGR/BGBG (DPCM)"; break; case V4L2_PIX_FMT_SRGGB10DPCM8: descr = "8-bit Bayer RGRG/GBGB (DPCM)"; break; case V4L2_PIX_FMT_SBGGR16: descr = "16-bit Bayer BGBG/GRGR (Exp.)"; break; - case V4L2_PIX_FMT_SN9C20X_I420: descr = "GSPCA SN9C20X I420"; + case V4L2_PIX_FMT_SN9C20X_I420: descr = "GSPCA SN9C20X I420"; break; case V4L2_PIX_FMT_SPCA501: descr = "GSPCA SPCA501"; break; case V4L2_PIX_FMT_SPCA505: descr = "GSPCA SPCA505"; break; case V4L2_PIX_FMT_SPCA508: descr = "GSPCA SPCA508"; break; -- cgit v1.2.3-59-g8ed1b From 5b7ccde2b4b888de332ede17f43de05efcdca632 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 21 Apr 2015 10:39:30 -0300 Subject: [media] vim2m: drop format description The format description is now filled in by the core, so we can drop this in this virtual m2m driver. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vim2m.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c index 4d6b4cc57c57..cecfd75b58d7 100644 --- a/drivers/media/platform/vim2m.c +++ b/drivers/media/platform/vim2m.c @@ -80,7 +80,6 @@ static struct platform_device vim2m_pdev = { }; struct vim2m_fmt { - char *name; u32 fourcc; int depth; /* Types the format can be used for */ @@ -89,14 +88,12 @@ struct vim2m_fmt { static struct vim2m_fmt formats[] = { { - .name = "RGB565 (BE)", .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */ .depth = 16, /* Both capture and output format */ .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT, }, { - .name = "4:2:2, packed, YUYV", .fourcc = V4L2_PIX_FMT_YUYV, .depth = 16, /* Output-only format */ @@ -458,7 +455,6 @@ static int enum_fmt(struct v4l2_fmtdesc *f, u32 type) if (i < NUM_FORMATS) { /* Format found */ fmt = &formats[i]; - strncpy(f->description, fmt->name, sizeof(f->description) - 1); f->pixelformat = fmt->fourcc; return 0; } -- cgit v1.2.3-59-g8ed1b From 6752d73046bb54efa04afd1072dd3c283aba01f2 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 21 Apr 2015 10:39:49 -0300 Subject: [media] vivid: drop format description The format description is now filled in by the core, so we can drop this in this virtual driver. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-core.h | 1 - drivers/media/platform/vivid/vivid-vid-cap.c | 4 -- drivers/media/platform/vivid/vivid-vid-common.c | 50 ------------------------- 3 files changed, 55 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h index 9e15aee9a52e..bf26173f1e3b 100644 --- a/drivers/media/platform/vivid/vivid-core.h +++ b/drivers/media/platform/vivid/vivid-core.h @@ -77,7 +77,6 @@ extern const struct v4l2_rect vivid_max_rect; extern unsigned vivid_debug; struct vivid_fmt { - const char *name; u32 fourcc; /* v4l2 format id */ bool is_yuv; bool can_do_overlay; diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c index 09afc933ab80..fd7adc43f63d 100644 --- a/drivers/media/platform/vivid/vivid-vid-cap.c +++ b/drivers/media/platform/vivid/vivid-vid-cap.c @@ -40,7 +40,6 @@ static const struct v4l2_fract static const struct vivid_fmt formats_ovl[] = { { - .name = "RGB565 (LE)", .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ .vdownsampling = { 1 }, .bit_depth = { 16 }, @@ -48,7 +47,6 @@ static const struct vivid_fmt formats_ovl[] = { .buffers = 1, }, { - .name = "XRGB555 (LE)", .fourcc = V4L2_PIX_FMT_XRGB555, /* gggbbbbb arrrrrgg */ .vdownsampling = { 1 }, .bit_depth = { 16 }, @@ -56,7 +54,6 @@ static const struct vivid_fmt formats_ovl[] = { .buffers = 1, }, { - .name = "ARGB555 (LE)", .fourcc = V4L2_PIX_FMT_ARGB555, /* gggbbbbb arrrrrgg */ .vdownsampling = { 1 }, .bit_depth = { 16 }, @@ -1033,7 +1030,6 @@ int vidioc_enum_fmt_vid_overlay(struct file *file, void *priv, fmt = &formats_ovl[f->index]; - strlcpy(f->description, fmt->name, sizeof(f->description)); f->pixelformat = fmt->fourcc; return 0; } diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c index aa446271ad34..6ba874420485 100644 --- a/drivers/media/platform/vivid/vivid-vid-common.c +++ b/drivers/media/platform/vivid/vivid-vid-common.c @@ -45,7 +45,6 @@ const struct v4l2_dv_timings_cap vivid_dv_timings_cap = { struct vivid_fmt vivid_formats[] = { { - .name = "4:2:2, packed, YUYV", .fourcc = V4L2_PIX_FMT_YUYV, .vdownsampling = { 1 }, .bit_depth = { 16 }, @@ -55,7 +54,6 @@ struct vivid_fmt vivid_formats[] = { .data_offset = { PLANE0_DATA_OFFSET }, }, { - .name = "4:2:2, packed, UYVY", .fourcc = V4L2_PIX_FMT_UYVY, .vdownsampling = { 1 }, .bit_depth = { 16 }, @@ -64,7 +62,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "4:2:2, packed, YVYU", .fourcc = V4L2_PIX_FMT_YVYU, .vdownsampling = { 1 }, .bit_depth = { 16 }, @@ -73,7 +70,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "4:2:2, packed, VYUY", .fourcc = V4L2_PIX_FMT_VYUY, .vdownsampling = { 1 }, .bit_depth = { 16 }, @@ -82,7 +78,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "YUV 4:2:2 triplanar", .fourcc = V4L2_PIX_FMT_YUV422P, .vdownsampling = { 1, 1, 1 }, .bit_depth = { 8, 4, 4 }, @@ -91,7 +86,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "YUV 4:2:0 triplanar", .fourcc = V4L2_PIX_FMT_YUV420, .vdownsampling = { 1, 2, 2 }, .bit_depth = { 8, 4, 4 }, @@ -100,7 +94,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "YVU 4:2:0 triplanar", .fourcc = V4L2_PIX_FMT_YVU420, .vdownsampling = { 1, 2, 2 }, .bit_depth = { 8, 4, 4 }, @@ -109,7 +102,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "YUV 4:2:0 biplanar", .fourcc = V4L2_PIX_FMT_NV12, .vdownsampling = { 1, 2 }, .bit_depth = { 8, 8 }, @@ -118,7 +110,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "YVU 4:2:0 biplanar", .fourcc = V4L2_PIX_FMT_NV21, .vdownsampling = { 1, 2 }, .bit_depth = { 8, 8 }, @@ -127,7 +118,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "YUV 4:2:2 biplanar", .fourcc = V4L2_PIX_FMT_NV16, .vdownsampling = { 1, 1 }, .bit_depth = { 8, 8 }, @@ -136,7 +126,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "YVU 4:2:2 biplanar", .fourcc = V4L2_PIX_FMT_NV61, .vdownsampling = { 1, 1 }, .bit_depth = { 8, 8 }, @@ -145,7 +134,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "YUV 4:4:4 biplanar", .fourcc = V4L2_PIX_FMT_NV24, .vdownsampling = { 1, 1 }, .bit_depth = { 8, 16 }, @@ -154,7 +142,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "YVU 4:4:4 biplanar", .fourcc = V4L2_PIX_FMT_NV42, .vdownsampling = { 1, 1 }, .bit_depth = { 8, 16 }, @@ -163,7 +150,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "YUV555 (LE)", .fourcc = V4L2_PIX_FMT_YUV555, /* uuuvvvvv ayyyyyuu */ .vdownsampling = { 1 }, .bit_depth = { 16 }, @@ -172,7 +158,6 @@ struct vivid_fmt vivid_formats[] = { .alpha_mask = 0x8000, }, { - .name = "YUV565 (LE)", .fourcc = V4L2_PIX_FMT_YUV565, /* uuuvvvvv yyyyyuuu */ .vdownsampling = { 1 }, .bit_depth = { 16 }, @@ -180,7 +165,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "YUV444", .fourcc = V4L2_PIX_FMT_YUV444, /* uuuuvvvv aaaayyyy */ .vdownsampling = { 1 }, .bit_depth = { 16 }, @@ -189,7 +173,6 @@ struct vivid_fmt vivid_formats[] = { .alpha_mask = 0xf000, }, { - .name = "YUV32 (LE)", .fourcc = V4L2_PIX_FMT_YUV32, /* ayuv */ .vdownsampling = { 1 }, .bit_depth = { 32 }, @@ -198,7 +181,6 @@ struct vivid_fmt vivid_formats[] = { .alpha_mask = 0x000000ff, }, { - .name = "Monochrome", .fourcc = V4L2_PIX_FMT_GREY, .vdownsampling = { 1 }, .bit_depth = { 8 }, @@ -207,7 +189,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "RGB332", .fourcc = V4L2_PIX_FMT_RGB332, /* rrrgggbb */ .vdownsampling = { 1 }, .bit_depth = { 8 }, @@ -215,7 +196,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "RGB565 (LE)", .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ .vdownsampling = { 1 }, .bit_depth = { 16 }, @@ -224,7 +204,6 @@ struct vivid_fmt vivid_formats[] = { .can_do_overlay = true, }, { - .name = "RGB565 (BE)", .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */ .vdownsampling = { 1 }, .bit_depth = { 16 }, @@ -233,7 +212,6 @@ struct vivid_fmt vivid_formats[] = { .can_do_overlay = true, }, { - .name = "RGB444", .fourcc = V4L2_PIX_FMT_RGB444, /* xxxxrrrr ggggbbbb */ .vdownsampling = { 1 }, .bit_depth = { 16 }, @@ -241,7 +219,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "XRGB444", .fourcc = V4L2_PIX_FMT_XRGB444, /* xxxxrrrr ggggbbbb */ .vdownsampling = { 1 }, .bit_depth = { 16 }, @@ -249,7 +226,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "ARGB444", .fourcc = V4L2_PIX_FMT_ARGB444, /* aaaarrrr ggggbbbb */ .vdownsampling = { 1 }, .bit_depth = { 16 }, @@ -258,7 +234,6 @@ struct vivid_fmt vivid_formats[] = { .alpha_mask = 0x00f0, }, { - .name = "RGB555 (LE)", .fourcc = V4L2_PIX_FMT_RGB555, /* gggbbbbb xrrrrrgg */ .vdownsampling = { 1 }, .bit_depth = { 16 }, @@ -267,7 +242,6 @@ struct vivid_fmt vivid_formats[] = { .can_do_overlay = true, }, { - .name = "XRGB555 (LE)", .fourcc = V4L2_PIX_FMT_XRGB555, /* gggbbbbb xrrrrrgg */ .vdownsampling = { 1 }, .bit_depth = { 16 }, @@ -276,7 +250,6 @@ struct vivid_fmt vivid_formats[] = { .can_do_overlay = true, }, { - .name = "ARGB555 (LE)", .fourcc = V4L2_PIX_FMT_ARGB555, /* gggbbbbb arrrrrgg */ .vdownsampling = { 1 }, .bit_depth = { 16 }, @@ -286,7 +259,6 @@ struct vivid_fmt vivid_formats[] = { .alpha_mask = 0x8000, }, { - .name = "RGB555 (BE)", .fourcc = V4L2_PIX_FMT_RGB555X, /* xrrrrrgg gggbbbbb */ .vdownsampling = { 1 }, .bit_depth = { 16 }, @@ -294,7 +266,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "XRGB555 (BE)", .fourcc = V4L2_PIX_FMT_XRGB555X, /* xrrrrrgg gggbbbbb */ .vdownsampling = { 1 }, .bit_depth = { 16 }, @@ -302,7 +273,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "ARGB555 (BE)", .fourcc = V4L2_PIX_FMT_ARGB555X, /* arrrrrgg gggbbbbb */ .vdownsampling = { 1 }, .bit_depth = { 16 }, @@ -311,7 +281,6 @@ struct vivid_fmt vivid_formats[] = { .alpha_mask = 0x0080, }, { - .name = "RGB24 (LE)", .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */ .vdownsampling = { 1 }, .bit_depth = { 24 }, @@ -319,7 +288,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "RGB24 (BE)", .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */ .vdownsampling = { 1 }, .bit_depth = { 24 }, @@ -327,7 +295,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "BGR666", .fourcc = V4L2_PIX_FMT_BGR666, /* bbbbbbgg ggggrrrr rrxxxxxx */ .vdownsampling = { 1 }, .bit_depth = { 32 }, @@ -335,7 +302,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "RGB32 (LE)", .fourcc = V4L2_PIX_FMT_RGB32, /* xrgb */ .vdownsampling = { 1 }, .bit_depth = { 32 }, @@ -343,7 +309,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "RGB32 (BE)", .fourcc = V4L2_PIX_FMT_BGR32, /* bgrx */ .vdownsampling = { 1 }, .bit_depth = { 32 }, @@ -351,7 +316,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "XRGB32 (LE)", .fourcc = V4L2_PIX_FMT_XRGB32, /* xrgb */ .vdownsampling = { 1 }, .bit_depth = { 32 }, @@ -359,7 +323,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "XRGB32 (BE)", .fourcc = V4L2_PIX_FMT_XBGR32, /* bgrx */ .vdownsampling = { 1 }, .bit_depth = { 32 }, @@ -367,7 +330,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "ARGB32 (LE)", .fourcc = V4L2_PIX_FMT_ARGB32, /* argb */ .vdownsampling = { 1 }, .bit_depth = { 32 }, @@ -376,7 +338,6 @@ struct vivid_fmt vivid_formats[] = { .alpha_mask = 0x000000ff, }, { - .name = "ARGB32 (BE)", .fourcc = V4L2_PIX_FMT_ABGR32, /* bgra */ .vdownsampling = { 1 }, .bit_depth = { 32 }, @@ -385,7 +346,6 @@ struct vivid_fmt vivid_formats[] = { .alpha_mask = 0xff000000, }, { - .name = "Bayer BG/GR", .fourcc = V4L2_PIX_FMT_SBGGR8, /* Bayer BG/GR */ .vdownsampling = { 1 }, .bit_depth = { 8 }, @@ -393,7 +353,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "Bayer GB/RG", .fourcc = V4L2_PIX_FMT_SGBRG8, /* Bayer GB/RG */ .vdownsampling = { 1 }, .bit_depth = { 8 }, @@ -401,7 +360,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "Bayer GR/BG", .fourcc = V4L2_PIX_FMT_SGRBG8, /* Bayer GR/BG */ .vdownsampling = { 1 }, .bit_depth = { 8 }, @@ -409,7 +367,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "Bayer RG/GB", .fourcc = V4L2_PIX_FMT_SRGGB8, /* Bayer RG/GB */ .vdownsampling = { 1 }, .bit_depth = { 8 }, @@ -417,7 +374,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { - .name = "4:2:2, biplanar, YUV", .fourcc = V4L2_PIX_FMT_NV16M, .vdownsampling = { 1, 1 }, .bit_depth = { 8, 8 }, @@ -427,7 +383,6 @@ struct vivid_fmt vivid_formats[] = { .data_offset = { PLANE0_DATA_OFFSET, 0 }, }, { - .name = "4:2:2, biplanar, YVU", .fourcc = V4L2_PIX_FMT_NV61M, .vdownsampling = { 1, 1 }, .bit_depth = { 8, 8 }, @@ -437,7 +392,6 @@ struct vivid_fmt vivid_formats[] = { .data_offset = { 0, PLANE0_DATA_OFFSET }, }, { - .name = "4:2:0, triplanar, YUV", .fourcc = V4L2_PIX_FMT_YUV420M, .vdownsampling = { 1, 2, 2 }, .bit_depth = { 8, 4, 4 }, @@ -446,7 +400,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 3, }, { - .name = "4:2:0, triplanar, YVU", .fourcc = V4L2_PIX_FMT_YVU420M, .vdownsampling = { 1, 2, 2 }, .bit_depth = { 8, 4, 4 }, @@ -455,7 +408,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 3, }, { - .name = "4:2:0, biplanar, YUV", .fourcc = V4L2_PIX_FMT_NV12M, .vdownsampling = { 1, 2 }, .bit_depth = { 8, 8 }, @@ -464,7 +416,6 @@ struct vivid_fmt vivid_formats[] = { .buffers = 2, }, { - .name = "4:2:0, biplanar, YVU", .fourcc = V4L2_PIX_FMT_NV21M, .vdownsampling = { 1, 2 }, .bit_depth = { 8, 8 }, @@ -750,7 +701,6 @@ int vivid_enum_fmt_vid(struct file *file, void *priv, fmt = &vivid_formats[f->index]; - strlcpy(f->description, fmt->name, sizeof(f->description)); f->pixelformat = fmt->fourcc; return 0; } -- cgit v1.2.3-59-g8ed1b From 9450684b7439202f62a37183104b31d884ff0de3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 3 Apr 2015 07:22:40 -0300 Subject: [media] cx88: v4l2-compliance fixes Fix three v4l2-compliance failures: - the colorspace wasn't set in vidioc_try_fmt_vid_cap(). - the field wasn't set in v4l2_buffer when vb2_buffer_done() was called. - the sequence wasn't set in v4l2_buffer when vb2_buffer_done() was called. This fix also removes the unused buf->count field and starts the count at 0 instead of 1. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-core.c | 2 ++ drivers/media/pci/cx88/cx88-mpeg.c | 6 +----- drivers/media/pci/cx88/cx88-vbi.c | 6 +----- drivers/media/pci/cx88/cx88-video.c | 7 ++----- drivers/media/pci/cx88/cx88.h | 1 - 5 files changed, 6 insertions(+), 16 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c index 3501be9f19d8..aab7cf4c9825 100644 --- a/drivers/media/pci/cx88/cx88-core.c +++ b/drivers/media/pci/cx88/cx88-core.c @@ -519,6 +519,8 @@ void cx88_wakeup(struct cx88_core *core, buf = list_entry(q->active.next, struct cx88_buffer, list); v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp); + buf->vb.v4l2_buf.field = core->field; + buf->vb.v4l2_buf.sequence = q->count++; list_del(&buf->list); vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE); } diff --git a/drivers/media/pci/cx88/cx88-mpeg.c b/drivers/media/pci/cx88/cx88-mpeg.c index 98344540c51f..34f505744477 100644 --- a/drivers/media/pci/cx88/cx88-mpeg.c +++ b/drivers/media/pci/cx88/cx88-mpeg.c @@ -173,7 +173,7 @@ int cx8802_start_dma(struct cx8802_dev *dev, /* reset counter */ cx_write(MO_TS_GPCNTRL, GP_COUNT_CONTROL_RESET); - q->count = 1; + q->count = 0; /* enable irqs */ dprintk( 1, "setting the interrupt mask\n" ); @@ -216,8 +216,6 @@ static int cx8802_restart_queue(struct cx8802_dev *dev, dprintk(2,"restart_queue [%p/%d]: restart dma\n", buf, buf->vb.v4l2_buf.index); cx8802_start_dma(dev, q, buf); - list_for_each_entry(buf, &q->active, list) - buf->count = q->count++; return 0; } @@ -260,7 +258,6 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) if (list_empty(&cx88q->active)) { dprintk( 1, "queue is empty - first active\n" ); list_add_tail(&buf->list, &cx88q->active); - buf->count = cx88q->count++; dprintk(1,"[%p/%d] %s - first active\n", buf, buf->vb.v4l2_buf.index, __func__); @@ -269,7 +266,6 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) dprintk( 1, "queue is not empty - append to active\n" ); prev = list_entry(cx88q->active.prev, struct cx88_buffer, list); list_add_tail(&buf->list, &cx88q->active); - buf->count = cx88q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); dprintk( 1, "[%p/%d] %s - append to active\n", buf, buf->vb.v4l2_buf.index, __func__); diff --git a/drivers/media/pci/cx88/cx88-vbi.c b/drivers/media/pci/cx88/cx88-vbi.c index 32eb7fdb875e..7510e80eb2ff 100644 --- a/drivers/media/pci/cx88/cx88-vbi.c +++ b/drivers/media/pci/cx88/cx88-vbi.c @@ -59,7 +59,7 @@ static int cx8800_start_vbi_dma(struct cx8800_dev *dev, /* reset counter */ cx_write(MO_VBI_GPCNTRL, GP_COUNT_CONTROL_RESET); - q->count = 1; + q->count = 0; /* enable irqs */ cx_set(MO_PCI_INTMSK, core->pci_irqmask | PCI_INT_VIDINT); @@ -102,8 +102,6 @@ int cx8800_restart_vbi_queue(struct cx8800_dev *dev, dprintk(2,"restart_queue [%p/%d]: restart dma\n", buf, buf->vb.v4l2_buf.index); cx8800_start_vbi_dma(dev, q, buf); - list_for_each_entry(buf, &q->active, list) - buf->count = q->count++; return 0; } @@ -175,7 +173,6 @@ static void buffer_queue(struct vb2_buffer *vb) if (list_empty(&q->active)) { list_add_tail(&buf->list, &q->active); cx8800_start_vbi_dma(dev, q, buf); - buf->count = q->count++; dprintk(2,"[%p/%d] vbi_queue - first active\n", buf, buf->vb.v4l2_buf.index); @@ -183,7 +180,6 @@ static void buffer_queue(struct vb2_buffer *vb) buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1); prev = list_entry(q->active.prev, struct cx88_buffer, list); list_add_tail(&buf->list, &q->active); - buf->count = q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); dprintk(2,"[%p/%d] buffer_queue - append to active\n", buf, buf->vb.v4l2_buf.index); diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index c9decd80bf61..cebb07d87617 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -370,7 +370,7 @@ static int start_video_dma(struct cx8800_dev *dev, /* reset counter */ cx_write(MO_VIDY_GPCNTRL,GP_COUNT_CONTROL_RESET); - q->count = 1; + q->count = 0; /* enable irqs */ cx_set(MO_PCI_INTMSK, core->pci_irqmask | PCI_INT_VIDINT); @@ -423,8 +423,6 @@ static int restart_video_queue(struct cx8800_dev *dev, dprintk(2,"restart_queue [%p/%d]: restart dma\n", buf, buf->vb.v4l2_buf.index); start_video_dma(dev, q, buf); - list_for_each_entry(buf, &q->active, list) - buf->count = q->count++; } return 0; } @@ -523,7 +521,6 @@ static void buffer_queue(struct vb2_buffer *vb) if (list_empty(&q->active)) { list_add_tail(&buf->list, &q->active); - buf->count = q->count++; dprintk(2,"[%p/%d] buffer_queue - first active\n", buf, buf->vb.v4l2_buf.index); @@ -531,7 +528,6 @@ static void buffer_queue(struct vb2_buffer *vb) buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1); prev = list_entry(q->active.prev, struct cx88_buffer, list); list_add_tail(&buf->list, &q->active); - buf->count = q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); dprintk(2, "[%p/%d] buffer_queue - append to active\n", buf, buf->vb.v4l2_buf.index); @@ -771,6 +767,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, (f->fmt.pix.width * fmt->depth) >> 3; f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; + f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; return 0; } diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h index b9fe1ac24803..e75547827c52 100644 --- a/drivers/media/pci/cx88/cx88.h +++ b/drivers/media/pci/cx88/cx88.h @@ -327,7 +327,6 @@ struct cx88_buffer { /* cx88 specific */ unsigned int bpl; struct cx88_riscmem risc; - u32 count; }; struct cx88_dmaqueue { -- cgit v1.2.3-59-g8ed1b From de73e1321c263aa6760ca79b99af2600c9b4ac32 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 3 Apr 2015 08:13:14 -0300 Subject: [media] bttv: fix missing irq after reloading driver If pci_disable_device() isn't called when the driver is removed, then the next time when it is loaded the irq isn't found. I'm pretty sure this used to work in the past, but calling pci_disable_device() is clearly the correct method and this makes it work again. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-driver.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index 0f10e051f7fd..3632958f2158 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -4239,6 +4239,7 @@ fail0: iounmap(btv->bt848_mmio); release_mem_region(pci_resource_start(btv->c.pci,0), pci_resource_len(btv->c.pci,0)); + pci_disable_device(btv->c.pci); return result; } @@ -4282,6 +4283,7 @@ static void bttv_remove(struct pci_dev *pci_dev) iounmap(btv->bt848_mmio); release_mem_region(pci_resource_start(btv->c.pci,0), pci_resource_len(btv->c.pci,0)); + pci_disable_device(btv->c.pci); v4l2_device_unregister(&btv->c.v4l2_dev); bttvs[btv->c.nr] = NULL; -- cgit v1.2.3-59-g8ed1b From 50f2468ea0bfa1f93e47b433399ccb1b82f6818d Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 5 Apr 2015 09:06:22 -0300 Subject: [media] si4713: fix error return code Return a negative error code on failure. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ identifier ret; expression e1,e2; @@ ( if (\(ret < 0\|ret != 0\)) { ... return ret; } | ret = 0 ) ... when != ret = e1 when != &ret *if(...) { ... when != ret = e2 when forall return ret; } // Signed-off-by: Julia Lawall Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/si4713/si4713.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/si4713/si4713.c b/drivers/media/radio/si4713/si4713.c index e9d03ac69a27..0b04b56571da 100644 --- a/drivers/media/radio/si4713/si4713.c +++ b/drivers/media/radio/si4713/si4713.c @@ -1609,8 +1609,10 @@ static int si4713_probe(struct i2c_client *client, return 0; si4713_pdev = platform_device_alloc("radio-si4713", -1); - if (!si4713_pdev) + if (!si4713_pdev) { + rval = -ENOMEM; goto put_main_pdev; + } si4713_pdev_pdata.subdev = client; rval = platform_device_add_data(si4713_pdev, &si4713_pdev_pdata, -- cgit v1.2.3-59-g8ed1b From bfe40b79e9158f45be087a961da0454681e8d9fe Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 5 Apr 2015 09:06:23 -0300 Subject: [media] as102: fix error return code Return a negative error code on failure. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ identifier ret; expression e1,e2; @@ ( if (\(ret < 0\|ret != 0\)) { ... return ret; } | ret = 0 ) ... when != ret = e1 when != &ret *if(...) { ... when != ret = e2 when forall return ret; } // Signed-off-by: Julia Lawall Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/as102/as102_drv.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/usb/as102/as102_drv.c b/drivers/media/usb/as102/as102_drv.c index 8be1474b2c36..9dd7c7cb06b1 100644 --- a/drivers/media/usb/as102/as102_drv.c +++ b/drivers/media/usb/as102/as102_drv.c @@ -337,6 +337,7 @@ int as102_dvb_register(struct as102_dev_t *as102_dev) &as102_dev->bus_adap, as102_dev->elna_cfg); if (!as102_dev->dvb_fe) { + ret = -ENODEV; dev_err(dev, "%s: as102_attach() failed: %d", __func__, ret); goto efereg; -- cgit v1.2.3-59-g8ed1b From 44b0c738c7b6cdd7d1121da87aeea1b226487efb Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 5 Apr 2015 09:06:24 -0300 Subject: [media] radio: fix error return code Return a negative error code on failure. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ identifier ret; expression e1,e2; @@ ( if (\(ret < 0\|ret != 0\)) { ... return ret; } | ret = 0 ) ... when != ret = e1 when != &ret *if(...) { ... when != ret = e2 when forall return ret; } // Signed-off-by: Julia Lawall Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-timb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-timb.c b/drivers/media/radio/radio-timb.c index e6b55edc8f8d..04baafe5e901 100644 --- a/drivers/media/radio/radio-timb.c +++ b/drivers/media/radio/radio-timb.c @@ -138,8 +138,10 @@ static int timbradio_probe(struct platform_device *pdev) i2c_get_adapter(pdata->i2c_adapter), pdata->tuner, NULL); tr->sd_dsp = v4l2_i2c_new_subdev_board(&tr->v4l2_dev, i2c_get_adapter(pdata->i2c_adapter), pdata->dsp, NULL); - if (tr->sd_tuner == NULL || tr->sd_dsp == NULL) + if (tr->sd_tuner == NULL || tr->sd_dsp == NULL) { + err = -ENODEV; goto err_video_req; + } tr->v4l2_dev.ctrl_handler = tr->sd_dsp->ctrl_handler; -- cgit v1.2.3-59-g8ed1b From 5380baaf15a64575e2398810c4ed49fd0c9b6647 Mon Sep 17 00:00:00 2001 From: "jean-michel.hautbois@vodalys.com" Date: Thu, 9 Apr 2015 05:25:46 -0300 Subject: [media] media: adv7604: Fix masks used for querying timings in ADV7611 All masks for timings are different between ADV7604 and ADV7611. Most of the values have 1 precision bit more in the latter. Fix this by adding new fields to the chip_info structure. Signed-off-by: Jean-Michel Hautbois Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7604.c | 69 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 13 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 60ffcf098bef..c1be0f721727 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -124,6 +124,20 @@ struct adv76xx_chip_info { unsigned int num_recommended_settings[2]; unsigned long page_mask; + + /* Masks for timings */ + unsigned int linewidth_mask; + unsigned int field0_height_mask; + unsigned int field1_height_mask; + unsigned int hfrontporch_mask; + unsigned int hsync_mask; + unsigned int hbackporch_mask; + unsigned int field0_vfrontporch_mask; + unsigned int field1_vfrontporch_mask; + unsigned int field0_vsync_mask; + unsigned int field1_vsync_mask; + unsigned int field0_vbackporch_mask; + unsigned int field1_vbackporch_mask; }; /* @@ -1504,23 +1518,28 @@ static int adv76xx_query_dv_timings(struct v4l2_subdev *sd, if (is_digital_input(sd)) { timings->type = V4L2_DV_BT_656_1120; - /* FIXME: All masks are incorrect for ADV7611 */ - bt->width = hdmi_read16(sd, 0x07, 0xfff); - bt->height = hdmi_read16(sd, 0x09, 0xfff); + bt->width = hdmi_read16(sd, 0x07, info->linewidth_mask); + bt->height = hdmi_read16(sd, 0x09, info->field0_height_mask); bt->pixelclock = info->read_hdmi_pixelclock(sd); - bt->hfrontporch = hdmi_read16(sd, 0x20, 0x3ff); - bt->hsync = hdmi_read16(sd, 0x22, 0x3ff); - bt->hbackporch = hdmi_read16(sd, 0x24, 0x3ff); - bt->vfrontporch = hdmi_read16(sd, 0x2a, 0x1fff) / 2; - bt->vsync = hdmi_read16(sd, 0x2e, 0x1fff) / 2; - bt->vbackporch = hdmi_read16(sd, 0x32, 0x1fff) / 2; + bt->hfrontporch = hdmi_read16(sd, 0x20, info->hfrontporch_mask); + bt->hsync = hdmi_read16(sd, 0x22, info->hsync_mask); + bt->hbackporch = hdmi_read16(sd, 0x24, info->hbackporch_mask); + bt->vfrontporch = hdmi_read16(sd, 0x2a, + info->field0_vfrontporch_mask) / 2; + bt->vsync = hdmi_read16(sd, 0x2e, info->field0_vsync_mask) / 2; + bt->vbackporch = hdmi_read16(sd, 0x32, + info->field0_vbackporch_mask) / 2; bt->polarities = ((hdmi_read(sd, 0x05) & 0x10) ? V4L2_DV_VSYNC_POS_POL : 0) | ((hdmi_read(sd, 0x05) & 0x20) ? V4L2_DV_HSYNC_POS_POL : 0); if (bt->interlaced == V4L2_DV_INTERLACED) { - bt->height += hdmi_read16(sd, 0x0b, 0xfff); - bt->il_vfrontporch = hdmi_read16(sd, 0x2c, 0x1fff) / 2; - bt->il_vsync = hdmi_read16(sd, 0x30, 0x1fff) / 2; - bt->il_vbackporch = hdmi_read16(sd, 0x34, 0x1fff) / 2; + bt->height += hdmi_read16(sd, 0x0b, + info->field1_height_mask); + bt->il_vfrontporch = hdmi_read16(sd, 0x2c, + info->field1_vfrontporch_mask) / 2; + bt->il_vsync = hdmi_read16(sd, 0x30, + info->field1_vsync_mask) / 2; + bt->il_vbackporch = hdmi_read16(sd, 0x34, + info->field1_vbackporch_mask) / 2; } adv76xx_fill_optional_dv_timings_fields(sd, timings); } else { @@ -2567,6 +2586,18 @@ static const struct adv76xx_chip_info adv76xx_chip_info[] = { BIT(ADV76XX_PAGE_EDID) | BIT(ADV76XX_PAGE_HDMI) | BIT(ADV76XX_PAGE_TEST) | BIT(ADV76XX_PAGE_CP) | BIT(ADV7604_PAGE_VDP), + .linewidth_mask = 0xfff, + .field0_height_mask = 0xfff, + .field1_height_mask = 0xfff, + .hfrontporch_mask = 0x3ff, + .hsync_mask = 0x3ff, + .hbackporch_mask = 0x3ff, + .field0_vfrontporch_mask = 0x1fff, + .field0_vsync_mask = 0x1fff, + .field0_vbackporch_mask = 0x1fff, + .field1_vfrontporch_mask = 0x1fff, + .field1_vsync_mask = 0x1fff, + .field1_vbackporch_mask = 0x1fff, }, [ADV7611] = { .type = ADV7611, @@ -2596,6 +2627,18 @@ static const struct adv76xx_chip_info adv76xx_chip_info[] = { BIT(ADV76XX_PAGE_INFOFRAME) | BIT(ADV76XX_PAGE_AFE) | BIT(ADV76XX_PAGE_REP) | BIT(ADV76XX_PAGE_EDID) | BIT(ADV76XX_PAGE_HDMI) | BIT(ADV76XX_PAGE_CP), + .linewidth_mask = 0x1fff, + .field0_height_mask = 0x1fff, + .field1_height_mask = 0x1fff, + .hfrontporch_mask = 0x1fff, + .hsync_mask = 0x1fff, + .hbackporch_mask = 0x1fff, + .field0_vfrontporch_mask = 0x3fff, + .field0_vsync_mask = 0x3fff, + .field0_vbackporch_mask = 0x3fff, + .field1_vfrontporch_mask = 0x3fff, + .field1_vsync_mask = 0x3fff, + .field1_vbackporch_mask = 0x3fff, }, }; -- cgit v1.2.3-59-g8ed1b From 69bb7ab687164e1683b4f1d590b5940eb5a90921 Mon Sep 17 00:00:00 2001 From: Cheolhyun Park Date: Mon, 13 Apr 2015 11:29:09 -0300 Subject: [media] drx-j: Misspelled comment corrected Fix several typos inside the driver's comments. Signed-off-by: Cheolhyun Park Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/drx39xyj/drxj.c | 38 ++++++++++++++--------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c index 2bfa7a435974..61f76038442a 100644 --- a/drivers/media/dvb-frontends/drx39xyj/drxj.c +++ b/drivers/media/dvb-frontends/drx39xyj/drxj.c @@ -210,7 +210,7 @@ DEFINES /** * \def DRXJ_DEF_I2C_ADDR -* \brief Default I2C addres of a demodulator instance. +* \brief Default I2C address of a demodulator instance. */ #define DRXJ_DEF_I2C_ADDR (0x52) @@ -336,7 +336,7 @@ DEFINES * MICROCODE RELATED DEFINES */ -/* Magic word for checking correct Endianess of microcode data */ +/* Magic word for checking correct Endianness of microcode data */ #define DRX_UCODE_MAGIC_WORD ((((u16)'H')<<8)+((u16)'L')) /* CRC flag in ucode header, flags field. */ @@ -847,9 +847,9 @@ static struct drx_common_attr drxj_default_comm_attr_g = { static clockrate is selected */ DRX_MPEG_STR_WIDTH_1 /* MPEG Start width in clock cycles */ }, - /* Initilisations below can be ommited, they require no user input and + /* Initilisations below can be omitted, they require no user input and are initialy 0, NULL or false. The compiler will initialize them to these - values when ommited. */ + values when omitted. */ false, /* is_opened */ /* SCAN */ @@ -1175,7 +1175,7 @@ static u32 log1_times100(u32 x) Now x has binary point between bit[scale] and bit[scale-1] and 1.0 <= x < 2.0 */ - /* correction for divison: log(x) = log(x/y)+log(y) */ + /* correction for division: log(x) = log(x/y)+log(y) */ y = k * ((((u32) 1) << scale) * 200); /* remove integer part */ @@ -1653,7 +1653,7 @@ static int drxdap_fasi_write_block(struct i2c_device_addr *dev_addr, sequense will be visible: (1) write address {i2c addr, 4 bytes chip address} (2) write data {i2c addr, 4 bytes data } (3) write address (4) write data etc... - Addres must be rewriten because HI is reset after data transport and + Address must be rewriten because HI is reset after data transport and expects an address. */ todo = (block_size < datasize ? block_size : datasize); @@ -2971,7 +2971,7 @@ ctrl_set_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_o } /* ext_attr->standard */ } - if (cfg_data->enable_parallel == true) { /* MPEG data output is paralel -> clear ipr_mode[0] */ + if (cfg_data->enable_parallel == true) { /* MPEG data output is parallel -> clear ipr_mode[0] */ fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M)); } else { /* MPEG data output is serial -> set ipr_mode[0] */ fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M; @@ -3157,7 +3157,7 @@ ctrl_set_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_o pr_err("error %d\n", rc); goto rw_error; } - if (cfg_data->enable_parallel == true) { /* MPEG data output is paralel -> set MD1 to MD7 to output mode */ + if (cfg_data->enable_parallel == true) { /* MPEG data output is parallel -> set MD1 to MD7 to output mode */ sio_pdr_md_cfg = MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH << SIO_PDR_MD0_CFG_DRIVE__B | 0x03 << @@ -4320,7 +4320,7 @@ static int adc_synchronization(struct drx_demod_instance *demod) } if (count == 1) { - /* Try sampling on a diffrent edge */ + /* Try sampling on a different edge */ u16 clk_neg = 0; rc = drxj_dap_read_reg16(dev_addr, IQM_AF_CLKNEG__A, &clk_neg, 0); @@ -6461,7 +6461,7 @@ set_qam_measurement(struct drx_demod_instance *demod, enum drx_modulation constellation, u32 symbol_rate) { struct i2c_device_addr *dev_addr = NULL; /* device address for I2C writes */ - struct drxj_data *ext_attr = NULL; /* Global data container for DRXJ specif data */ + struct drxj_data *ext_attr = NULL; /* Global data container for DRXJ specific data */ int rc; u32 fec_bits_desired = 0; /* BER accounting period */ u16 fec_rs_plen = 0; /* defines RS BER measurement period */ @@ -8864,7 +8864,7 @@ qam64auto(struct drx_demod_instance *demod, u32 timeout_ofs = 0; u16 data = 0; - /* external attributes for storing aquired channel constellation */ + /* external attributes for storing acquired channel constellation */ *lock_status = DRX_NOT_LOCKED; start_time = jiffies_to_msecs(jiffies); lck_state = NO_LOCK; @@ -9011,7 +9011,7 @@ qam256auto(struct drx_demod_instance *demod, u32 d_locked_time = 0; u32 timeout_ofs = DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; - /* external attributes for storing aquired channel constellation */ + /* external attributes for storing acquired channel constellation */ *lock_status = DRX_NOT_LOCKED; start_time = jiffies_to_msecs(jiffies); lck_state = NO_LOCK; @@ -9087,7 +9087,7 @@ set_qam_channel(struct drx_demod_instance *demod, enum drx_lock_status lock_status = DRX_NOT_LOCKED; bool auto_flag = false; - /* external attributes for storing aquired channel constellation */ + /* external attributes for storing acquired channel constellation */ ext_attr = (struct drxj_data *) demod->my_ext_attr; /* set QAM channel constellation */ @@ -9431,7 +9431,7 @@ rw_error: /** * \fn int ctrl_get_qam_sig_quality() -* \brief Retreive QAM signal quality from device. +* \brief Retrieve QAM signal quality from device. * \param devmod Pointer to demodulator instance. * \param sig_quality Pointer to signal quality data. * \return int. @@ -10647,7 +10647,7 @@ rw_error: /** * \fn int ctrl_sig_quality() -* \brief Retreive signal quality form device. +* \brief Retrieve signal quality form device. * \param devmod Pointer to demodulator instance. * \param sig_quality Pointer to signal quality data. * \return int. @@ -10763,7 +10763,7 @@ rw_error: /** * \fn int ctrl_lock_status() -* \brief Retreive lock status . +* \brief Retrieve lock status . * \param dev_addr Pointer to demodulator device address. * \param lock_stat Pointer to lock status structure. * \return int. @@ -10815,7 +10815,7 @@ ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_st return -EIO; } - /* define the SCU command paramters and execute the command */ + /* define the SCU command parameters and execute the command */ cmd_scu.parameter_len = 0; cmd_scu.result_len = 2; cmd_scu.parameter = NULL; @@ -11489,7 +11489,7 @@ static int drxj_open(struct drx_demod_instance *demod) } /* Stamp driver version number in SCU data RAM in BCD code - Done to enable field application engineers to retreive drxdriver version + Done to enable field application engineers to retrieve drxdriver version via I2C from SCU RAM */ driver_version = (VERSION_MAJOR / 100) % 10; @@ -11892,7 +11892,7 @@ release: return rc; } -/* caller is expeced to check if lna is supported before enabling */ +/* caller is expected to check if lna is supported before enabling */ static int drxj_set_lna_state(struct drx_demod_instance *demod, bool state) { struct drxuio_cfg uio_cfg; -- cgit v1.2.3-59-g8ed1b From bf7096c664ecb60c80845e1ce3a412a9a619ce36 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 23 Apr 2015 15:09:05 -0300 Subject: [media] v4l: xilinx: VIDEO_XILINX should depend on HAS_DMA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If NO_DMA=y: warning: (VIDEO_XILINX && VIDEO_DM365_VPFE && VIDEO_DT3155 && VIDEO_OMAP4) selects VIDEOBUF2_DMA_CONTIG which has unmet direct dependencies (MEDIA_SUPPORT && HAS_DMA) media/v4l2-core/videobuf2-dma-contig.c: In function ‘vb2_dc_mmap’: media/v4l2-core/videobuf2-dma-contig.c:207: error: implicit declaration of function ‘dma_mmap_coherent’ media/v4l2-core/videobuf2-dma-contig.c: In function ‘vb2_dc_get_base_sgt’: media/v4l2-core/videobuf2-dma-contig.c:390: error: implicit declaration of function ‘dma_get_sgtable’ VIDEO_XILINX selects VIDEOBUF2_DMA_CONTIG, which bypasses its dependency on HAS_DMA. Make VIDEO_XILINX depend on HAS_DMA to fix this. Signed-off-by: Geert Uytterhoeven Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/xilinx/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/xilinx/Kconfig b/drivers/media/platform/xilinx/Kconfig index d7324c726fc2..84bae795b70d 100644 --- a/drivers/media/platform/xilinx/Kconfig +++ b/drivers/media/platform/xilinx/Kconfig @@ -1,6 +1,6 @@ config VIDEO_XILINX tristate "Xilinx Video IP (EXPERIMENTAL)" - depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF + depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && HAS_DMA select VIDEOBUF2_DMA_CONTIG ---help--- Driver for Xilinx Video IP Pipelines -- cgit v1.2.3-59-g8ed1b From 5d9b709a1724f27fbb17add0e287134b7039e0aa Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 23 Apr 2015 15:09:06 -0300 Subject: [media] v4l: VIDEOBUF2_DMA_SG should depend on HAS_DMA If NO_DMA=y: ERROR: "dma_unmap_sg" [drivers/media/v4l2-core/videobuf2-dma-sg.ko] undefined! ERROR: "dma_map_sg" [drivers/media/v4l2-core/videobuf2-dma-sg.ko] undefined! ERROR: "dma_sync_sg_for_cpu" [drivers/media/v4l2-core/videobuf2-dma-sg.ko] undefined! VIDEOBUF2_DMA_SG cannot be enabled manually by the user, it's always selected automatically by drivers that need it. Several of those drivers already have an explicit dependency on HAS_DMA. Make VIDEOBUF2_DMA_SG depend on HAS_DMA. This makes it easier to find drivers that select VIDEOBUF2_DMA_SG without depending on HAS_DMA, as Kconfig will give a warning. Signed-off-by: Geert Uytterhoeven Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig index ba7e21a73023..f7a01a72eb9e 100644 --- a/drivers/media/v4l2-core/Kconfig +++ b/drivers/media/v4l2-core/Kconfig @@ -89,7 +89,7 @@ config VIDEOBUF2_VMALLOC config VIDEOBUF2_DMA_SG tristate - #depends on HAS_DMA + depends on HAS_DMA select VIDEOBUF2_CORE select VIDEOBUF2_MEMOPS -- cgit v1.2.3-59-g8ed1b From f67476589afc9a4a48bc342f1b5f505b508bd1ff Mon Sep 17 00:00:00 2001 From: Prashant Laddha Date: Wed, 22 Apr 2015 14:32:34 -0300 Subject: [media] v4l2-dv-timings: fix rounding error in vsync_bp calculation Changed the rounding offsets used in vsync_bp calculation in cvt and gtf timings. The results for vsync_bp should now match with results from timing generator spreadsheets for cvt and gtf standards. In the vsync_bp calculation for cvt, always round down the value of (CVT_MIN_VSYNC_BP / h_period_est) and then add 1. It thus, reflects the equation used in timing generator spreadsheet. Using 1999999 as rounding offset, could pontentially lead to bumping up the vsync_bp value by extra 1. In the vsync_bp calculations for gtf, instead of round up or round down, round the (CVT_MIN_VSYNC_BP / h_period_est) to the nearest integer. Thanks to Martin Bugge for validating with standards and suggestions on equations. Cc: Martin Bugge Signed-off-by: Prashant Laddha Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-dv-timings.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c index c0e96382feba..32aa25fa560b 100644 --- a/drivers/media/v4l2-core/v4l2-dv-timings.c +++ b/drivers/media/v4l2-core/v4l2-dv-timings.c @@ -368,14 +368,14 @@ bool v4l2_detect_cvt(unsigned frame_height, unsigned hfreq, unsigned vsync, /* Vertical */ if (reduced_blanking) { v_fp = CVT_RB_V_FPORCH; - v_bp = (CVT_RB_MIN_V_BLANK * hfreq + 1999999) / 1000000; + v_bp = (CVT_RB_MIN_V_BLANK * hfreq) / 1000000 + 1; v_bp -= vsync + v_fp; if (v_bp < CVT_RB_MIN_V_BPORCH) v_bp = CVT_RB_MIN_V_BPORCH; } else { v_fp = CVT_MIN_V_PORCH_RND; - v_bp = (CVT_MIN_VSYNC_BP * hfreq + 1999999) / 1000000 - vsync; + v_bp = (CVT_MIN_VSYNC_BP * hfreq) / 1000000 + 1 - vsync; if (v_bp < CVT_MIN_V_BPORCH) v_bp = CVT_MIN_V_BPORCH; @@ -529,7 +529,8 @@ bool v4l2_detect_gtf(unsigned frame_height, /* Vertical */ v_fp = GTF_V_FP; - v_bp = (GTF_MIN_VSYNC_BP * hfreq + 999999) / 1000000 - vsync; + + v_bp = (GTF_MIN_VSYNC_BP * hfreq + 500000) / 1000000 - vsync; image_height = (frame_height - v_fp - vsync - v_bp + 1) & ~0x1; if (aspect.numerator == 0 || aspect.denominator == 0) { -- cgit v1.2.3-59-g8ed1b From d7ed5a3ddaec19d866ffc05ed2733179fbe4da9e Mon Sep 17 00:00:00 2001 From: Prashant Laddha Date: Wed, 22 Apr 2015 14:32:35 -0300 Subject: [media] v4l2-dv-timings: fix rounding in hblank and hsync calculation Changed the rounding calculation for hblank and hsync to match it to equations in cvt and gtf standards. In cvt calculation, hsync needs to be rounded down. In gtf calculations, hblank needs to be rounded to nearest multiple of twice the cell granularity and hsync needs to be rounded to the nearest multiple of cell granularity. Cc: Martin Bugge Signed-off-by: Prashant Laddha Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-dv-timings.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c index 32aa25fa560b..16c8ac5b5e0b 100644 --- a/drivers/media/v4l2-core/v4l2-dv-timings.c +++ b/drivers/media/v4l2-core/v4l2-dv-timings.c @@ -436,8 +436,8 @@ bool v4l2_detect_cvt(unsigned frame_height, unsigned hfreq, unsigned vsync, h_bp = h_blank / 2; frame_width = image_width + h_blank; - hsync = (frame_width * 8 + 50) / 100; - hsync = hsync - hsync % CVT_CELL_GRAN; + hsync = frame_width * 8 / 100; + hsync = (hsync / CVT_CELL_GRAN) * CVT_CELL_GRAN; h_fp = h_blank - hsync - h_bp; } @@ -552,14 +552,15 @@ bool v4l2_detect_gtf(unsigned frame_height, (hfreq * (100 - GTF_S_C_PRIME) + GTF_S_M_PRIME * 1000) / 2) / (hfreq * (100 - GTF_S_C_PRIME) + GTF_S_M_PRIME * 1000); - h_blank = h_blank - h_blank % (2 * GTF_CELL_GRAN); + h_blank = ((h_blank + GTF_CELL_GRAN) / (2 * GTF_CELL_GRAN)) * + (2 * GTF_CELL_GRAN); frame_width = image_width + h_blank; pix_clk = (image_width + h_blank) * hfreq; pix_clk = pix_clk / GTF_PXL_CLK_GRAN * GTF_PXL_CLK_GRAN; hsync = (frame_width * 8 + 50) / 100; - hsync = hsync - hsync % GTF_CELL_GRAN; + hsync = ((hsync + GTF_CELL_GRAN / 2) / GTF_CELL_GRAN) * GTF_CELL_GRAN; h_fp = h_blank / 2 - hsync; -- cgit v1.2.3-59-g8ed1b From 947ed99e5d1b1595312a320fb9db4f52965ceeae Mon Sep 17 00:00:00 2001 From: Prashant Laddha Date: Wed, 22 Apr 2015 14:32:36 -0300 Subject: [media] v4l2-dv-timings: add sanity checks in cvt,gtf calculations Wrong values of hfreq and image height can lead to strange timings. Avoid timing calculations for such values. Suggested By: Martin Bugge Cc: Martin Bugge Signed-off-by: Prashant Laddha Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-dv-timings.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c index 16c8ac5b5e0b..4e09792038ed 100644 --- a/drivers/media/v4l2-core/v4l2-dv-timings.c +++ b/drivers/media/v4l2-core/v4l2-dv-timings.c @@ -365,6 +365,9 @@ bool v4l2_detect_cvt(unsigned frame_height, unsigned hfreq, unsigned vsync, else return false; + if (hfreq == 0) + return false; + /* Vertical */ if (reduced_blanking) { v_fp = CVT_RB_V_FPORCH; @@ -382,6 +385,9 @@ bool v4l2_detect_cvt(unsigned frame_height, unsigned hfreq, unsigned vsync, } image_height = (frame_height - v_fp - vsync - v_bp + 1) & ~0x1; + if (image_height < 0) + return false; + /* Aspect ratio based on vsync */ switch (vsync) { case 4: @@ -527,12 +533,18 @@ bool v4l2_detect_gtf(unsigned frame_height, else return false; + if (hfreq == 0) + return false; + /* Vertical */ v_fp = GTF_V_FP; v_bp = (GTF_MIN_VSYNC_BP * hfreq + 500000) / 1000000 - vsync; image_height = (frame_height - v_fp - vsync - v_bp + 1) & ~0x1; + if (image_height < 0) + return false; + if (aspect.numerator == 0 || aspect.denominator == 0) { aspect.numerator = 16; aspect.denominator = 9; -- cgit v1.2.3-59-g8ed1b From 9c3f205252f8ae2af9794d68bcbfc49fb0812ccf Mon Sep 17 00:00:00 2001 From: Prashant Laddha Date: Wed, 22 Apr 2015 14:32:37 -0300 Subject: [media] v4l2-dv-timings: replace hsync magic number with a macro This change will not change timing calculation. In CVT generator spreadsheet the nominal value of hsync (as a percentage of line) is 8 percent. Cc: Martin Bugge Signed-off-by: Prashant Laddha Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-dv-timings.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c index 4e09792038ed..37f0d6f89878 100644 --- a/drivers/media/v4l2-core/v4l2-dv-timings.c +++ b/drivers/media/v4l2-core/v4l2-dv-timings.c @@ -313,6 +313,7 @@ EXPORT_SYMBOL_GPL(v4l2_print_dv_timings); #define CVT_MIN_V_BPORCH 7 /* lines */ #define CVT_MIN_V_PORCH_RND 3 /* lines */ #define CVT_MIN_VSYNC_BP 550 /* min time of vsync + back porch (us) */ +#define CVT_HSYNC_PERCENT 8 /* nominal hsync as percentage of line */ /* Normal blanking for CVT uses GTF to calculate horizontal blanking */ #define CVT_CELL_GRAN 8 /* character cell granularity */ @@ -442,7 +443,7 @@ bool v4l2_detect_cvt(unsigned frame_height, unsigned hfreq, unsigned vsync, h_bp = h_blank / 2; frame_width = image_width + h_blank; - hsync = frame_width * 8 / 100; + hsync = frame_width * CVT_HSYNC_PERCENT / 100; hsync = (hsync / CVT_CELL_GRAN) * CVT_CELL_GRAN; h_fp = h_blank - hsync - h_bp; } -- cgit v1.2.3-59-g8ed1b From 48b25a3a713b90988b6882d318f7c0a6bed9aabc Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 17 Mar 2015 08:56:31 -0300 Subject: [media] vb2: Push mmap_sem down to memops Currently vb2 core acquires mmap_sem just around call to __qbuf_userptr(). However since commit f035eb4e976ef5 (videobuf2: fix lockdep warning) it isn't necessary to acquire it so early as we no longer have to drop queue mutex before acquiring mmap_sem. So push acquisition of mmap_sem down into .get_userptr and .put_userptr memops so that the semaphore is acquired for a shorter time and it is clearer what it is needed for. Signed-off-by: Jan Kara Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-core.c | 2 -- drivers/media/v4l2-core/videobuf2-dma-contig.c | 7 +++++++ drivers/media/v4l2-core/videobuf2-dma-sg.c | 6 ++++++ drivers/media/v4l2-core/videobuf2-vmalloc.c | 6 +++++- 4 files changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 66ada01c796c..20cdbc0900ea 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -1657,9 +1657,7 @@ static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b) ret = __qbuf_mmap(vb, b); break; case V4L2_MEMORY_USERPTR: - down_read(¤t->mm->mmap_sem); ret = __qbuf_userptr(vb, b); - up_read(¤t->mm->mmap_sem); break; case V4L2_MEMORY_DMABUF: ret = __qbuf_dmabuf(vb, b); diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 644dec73d220..620c4aa78881 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -532,7 +532,9 @@ static void vb2_dc_put_userptr(void *buf_priv) sg_free_table(sgt); kfree(sgt); } + down_read(¤t->mm->mmap_sem); vb2_put_vma(buf->vma); + up_read(¤t->mm->mmap_sem); kfree(buf); } @@ -616,6 +618,7 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, goto fail_buf; } + down_read(¤t->mm->mmap_sem); /* current->mm->mmap_sem is taken by videobuf2 core */ vma = find_vma(current->mm, vaddr); if (!vma) { @@ -642,6 +645,7 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, if (ret) { unsigned long pfn; if (vb2_dc_get_user_pfn(start, n_pages, vma, &pfn) == 0) { + up_read(¤t->mm->mmap_sem); buf->dma_addr = vb2_dc_pfn_to_dma(buf->dev, pfn); buf->size = size; kfree(pages); @@ -651,6 +655,7 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, pr_err("failed to get user pages\n"); goto fail_vma; } + up_read(¤t->mm->mmap_sem); sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); if (!sgt) { @@ -713,10 +718,12 @@ fail_get_user_pages: while (n_pages) put_page(pages[--n_pages]); + down_read(¤t->mm->mmap_sem); fail_vma: vb2_put_vma(buf->vma); fail_pages: + up_read(¤t->mm->mmap_sem); kfree(pages); /* kfree is NULL-proof */ fail_buf: diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c index 45c708e463b9..afd4b514affc 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c @@ -263,6 +263,7 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr, if (!buf->pages) goto userptr_fail_alloc_pages; + down_read(¤t->mm->mmap_sem); vma = find_vma(current->mm, vaddr); if (!vma) { dprintk(1, "no vma for address %lu\n", vaddr); @@ -301,6 +302,7 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr, 1, /* force */ buf->pages, NULL); + up_read(¤t->mm->mmap_sem); if (num_pages_from_user != buf->num_pages) goto userptr_fail_get_user_pages; @@ -328,8 +330,10 @@ userptr_fail_get_user_pages: if (!vma_is_io(buf->vma)) while (--num_pages_from_user >= 0) put_page(buf->pages[num_pages_from_user]); + down_read(¤t->mm->mmap_sem); vb2_put_vma(buf->vma); userptr_fail_find_vma: + up_read(¤t->mm->mmap_sem); kfree(buf->pages); userptr_fail_alloc_pages: kfree(buf); @@ -362,7 +366,9 @@ static void vb2_dma_sg_put_userptr(void *buf_priv) put_page(buf->pages[i]); } kfree(buf->pages); + down_read(¤t->mm->mmap_sem); vb2_put_vma(buf->vma); + up_read(¤t->mm->mmap_sem); kfree(buf); } diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c b/drivers/media/v4l2-core/videobuf2-vmalloc.c index 657ab302a5cf..0ba40be21ebd 100644 --- a/drivers/media/v4l2-core/videobuf2-vmalloc.c +++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c @@ -89,7 +89,7 @@ static void *vb2_vmalloc_get_userptr(void *alloc_ctx, unsigned long vaddr, offset = vaddr & ~PAGE_MASK; buf->size = size; - + down_read(¤t->mm->mmap_sem); vma = find_vma(current->mm, vaddr); if (vma && (vma->vm_flags & VM_PFNMAP) && (vma->vm_pgoff)) { if (vb2_get_contig_userptr(vaddr, size, &vma, &physp)) @@ -121,6 +121,7 @@ static void *vb2_vmalloc_get_userptr(void *alloc_ctx, unsigned long vaddr, if (!buf->vaddr) goto fail_get_user_pages; } + up_read(¤t->mm->mmap_sem); buf->vaddr += offset; return buf; @@ -133,6 +134,7 @@ fail_get_user_pages: kfree(buf->pages); fail_pages_array_alloc: + up_read(¤t->mm->mmap_sem); kfree(buf); return NULL; @@ -144,6 +146,7 @@ static void vb2_vmalloc_put_userptr(void *buf_priv) unsigned long vaddr = (unsigned long)buf->vaddr & PAGE_MASK; unsigned int i; + down_read(¤t->mm->mmap_sem); if (buf->pages) { if (vaddr) vm_unmap_ram((void *)vaddr, buf->n_pages); @@ -157,6 +160,7 @@ static void vb2_vmalloc_put_userptr(void *buf_priv) vb2_put_vma(buf->vma); iounmap((__force void __iomem *)buf->vaddr); } + up_read(¤t->mm->mmap_sem); kfree(buf); } -- cgit v1.2.3-59-g8ed1b From 5f5859d1c158b42343d343f5d1aa6de8643b8cf6 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 15 Apr 2015 16:12:18 -0300 Subject: [media] i2c: ov2659: signedness bug inov2659_set_fmt() This needs to be signed or there is a risk of hitting a forever loop. Fixes: c4c0283ab3cd ('[media] media: i2c: add support for omnivision's ov2659 sensor') Signed-off-by: Dan Carpenter Acked-by: Lad, Prabhakar Acked-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov2659.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c index edebd114279d..d700a1d0a6f2 100644 --- a/drivers/media/i2c/ov2659.c +++ b/drivers/media/i2c/ov2659.c @@ -1102,7 +1102,7 @@ static int ov2659_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_format *fmt) { struct i2c_client *client = v4l2_get_subdevdata(sd); - unsigned int index = ARRAY_SIZE(ov2659_formats); + int index = ARRAY_SIZE(ov2659_formats); struct v4l2_mbus_framefmt *mf = &fmt->format; const struct ov2659_framesize *size = NULL; struct ov2659 *ov2659 = to_ov2659(sd); -- cgit v1.2.3-59-g8ed1b From 5f954b5be4bf42e85e0a204518499bda8ee2f419 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 23 Mar 2015 15:37:32 -0300 Subject: [media] saa7164: I2C improvements for upcoming HVR2255/2205 boards SI2168/SI2157 issue single byte address reads. Add support for these. Signed-off-by: Steven Toth Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7164/saa7164-i2c.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7164/saa7164-i2c.c b/drivers/media/pci/saa7164/saa7164-i2c.c index 4f7e3b42263f..3b37c96d2a7c 100644 --- a/drivers/media/pci/saa7164/saa7164-i2c.c +++ b/drivers/media/pci/saa7164/saa7164-i2c.c @@ -39,9 +39,10 @@ static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) dprintk(DBGLVL_I2C, "%s(num = %d) addr = 0x%02x len = 0x%x\n", __func__, num, msgs[i].addr, msgs[i].len); if (msgs[i].flags & I2C_M_RD) { - /* Unsupported - Yet*/ - printk(KERN_ERR "%s() Unsupported - Yet\n", __func__); - continue; + retval = saa7164_api_i2c_read(bus, + msgs[i].addr, + 0 /* reglen */, + 0 /* reg */, msgs[i].len, msgs[i].buf); } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) && msgs[i].addr == msgs[i + 1].addr) { /* write then read from same address */ -- cgit v1.2.3-59-g8ed1b From 8ed5e4e89c321cd7eab936517dc7e3a249299e24 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 23 Mar 2015 15:41:03 -0300 Subject: [media] saa7164: Adding additional I2C debug Assists with debugging difficult I2C devices. Signed-off-by: Steven Toth Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7164/saa7164-api.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7164/saa7164-api.c b/drivers/media/pci/saa7164/saa7164-api.c index 4f3b1dd18ba4..97bbd0a13d62 100644 --- a/drivers/media/pci/saa7164/saa7164-api.c +++ b/drivers/media/pci/saa7164/saa7164-api.c @@ -1373,7 +1373,8 @@ int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg, u8 buf[256]; int ret; - dprintk(DBGLVL_API, "%s()\n", __func__); + dprintk(DBGLVL_API, "%s() addr=%x reglen=%d datalen=%d\n", + __func__, addr, reglen, datalen); if (reglen > 4) return -EIO; @@ -1434,7 +1435,8 @@ int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen, u8 buf[256]; int ret; - dprintk(DBGLVL_API, "%s()\n", __func__); + dprintk(DBGLVL_API, "%s() addr=0x%2x len=0x%x\n", + __func__, addr, datalen); if ((datalen == 0) || (datalen > 232)) return -EIO; @@ -1464,7 +1466,7 @@ int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen, return -EIO; } - dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len); + dprintk(DBGLVL_API, "%s() len = %d bytes unitid=0x%x\n", __func__, len, unitid); /* Prepare the send buffer */ /* Bytes 00-03 dest register length -- cgit v1.2.3-59-g8ed1b From ad90b6b0f10566d4a5546e27fe455ce3b5e6b6c7 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 23 Mar 2015 15:42:53 -0300 Subject: [media] saa7164: Improvements for I2C handling Workaround oddball I2C issues caused by using newer SILABS devices. Signed-off-by: Steven Toth Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7164/saa7164-api.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7164/saa7164-api.c b/drivers/media/pci/saa7164/saa7164-api.c index 97bbd0a13d62..d9e21e736d1f 100644 --- a/drivers/media/pci/saa7164/saa7164-api.c +++ b/drivers/media/pci/saa7164/saa7164-api.c @@ -1385,7 +1385,8 @@ int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg, * 08... register address */ memset(buf, 0, sizeof(buf)); - memcpy((buf + 2 * sizeof(u32) + 0), reg, reglen); + if (reg) + memcpy((buf + 2 * sizeof(u32) + 0), reg, reglen); *((u32 *)(buf + 0 * sizeof(u32))) = reglen; *((u32 *)(buf + 1 * sizeof(u32))) = datalen; @@ -1473,6 +1474,14 @@ int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen, * 04-07 dest bytes to write * 08... register address */ + if (datalen == 1) { + /* Workaround for issues with i2c components + * that issue writes with no data. IE: SI2168/2157 + * Increase reglen by 1, strobe out an additional byte, + * ignored by SI2168/2157. + */ + datalen++; + } *((u32 *)(buf + 0 * sizeof(u32))) = reglen; *((u32 *)(buf + 1 * sizeof(u32))) = datalen - reglen; memcpy((buf + 2 * sizeof(u32)), data, datalen); -- cgit v1.2.3-59-g8ed1b From 504b29cbb0cc0fb7169c276054a72110b57660c0 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 23 Mar 2015 15:45:48 -0300 Subject: [media] saa7164: Add Digital TV support for the HVR2255 and HVR2205 Adding support for the Hauppauge HVR2255 and Hauppauge HVR2205 PCIe cards. Digital TV for DVB-T and ATSC/US-Cable is known to work. Support for analog RF tuners does not work due to a lack of analog support in the upstream SI2157 driver. Signed-off-by: Steven Toth Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7164/saa7164-cards.c | 186 ++++++++++++++++++++++++ drivers/media/pci/saa7164/saa7164-dvb.c | 230 ++++++++++++++++++++++++++++-- drivers/media/pci/saa7164/saa7164.h | 5 + 3 files changed, 407 insertions(+), 14 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7164/saa7164-cards.c b/drivers/media/pci/saa7164/saa7164-cards.c index 5b72da5ce418..2ca5e5d5580d 100644 --- a/drivers/media/pci/saa7164/saa7164-cards.c +++ b/drivers/media/pci/saa7164/saa7164-cards.c @@ -30,6 +30,7 @@ * attached I2C devices, so we can simplify the virtual i2c mechansms * and keep the -i2c.c implementation clean. */ +#define REGLEN_0bit 0 #define REGLEN_8bit 1 #define REGLEN_16bit 2 @@ -499,6 +500,144 @@ struct saa7164_board saa7164_boards[] = { .i2c_reg_len = REGLEN_8bit, } }, }, + [SAA7164_BOARD_HAUPPAUGE_HVR2255proto] = { + .name = "Hauppauge WinTV-HVR2255(proto)", + .porta = SAA7164_MPEG_DVB, + .portb = SAA7164_MPEG_DVB, + .portc = SAA7164_MPEG_ENCODER, + .portd = SAA7164_MPEG_ENCODER, + .porte = SAA7164_MPEG_VBI, + .portf = SAA7164_MPEG_VBI, + .chiprev = SAA7164_CHIP_REV3, + .unit = {{ + .id = 0x27, + .type = SAA7164_UNIT_EEPROM, + .name = "4K EEPROM", + .i2c_bus_nr = SAA7164_I2C_BUS_0, + .i2c_bus_addr = 0xa0 >> 1, + .i2c_reg_len = REGLEN_8bit, + }, { + .id = 0x04, + .type = SAA7164_UNIT_TUNER, + .name = "SI2157-1", + .i2c_bus_nr = SAA7164_I2C_BUS_0, + .i2c_bus_addr = 0xc0 >> 1, + .i2c_reg_len = REGLEN_0bit, + }, { + .id = 0x06, + .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, + .name = "LGDT3306", + .i2c_bus_nr = SAA7164_I2C_BUS_2, + .i2c_bus_addr = 0xb2 >> 1, + .i2c_reg_len = REGLEN_8bit, + }, { + .id = 0x24, + .type = SAA7164_UNIT_TUNER, + .name = "SI2157-2", + .i2c_bus_nr = SAA7164_I2C_BUS_1, + .i2c_bus_addr = 0xc0 >> 1, + .i2c_reg_len = REGLEN_0bit, + }, { + .id = 0x26, + .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, + .name = "LGDT3306-2", + .i2c_bus_nr = SAA7164_I2C_BUS_2, + .i2c_bus_addr = 0x1c >> 1, + .i2c_reg_len = REGLEN_8bit, + } }, + }, + [SAA7164_BOARD_HAUPPAUGE_HVR2255] = { + .name = "Hauppauge WinTV-HVR2255", + .porta = SAA7164_MPEG_DVB, + .portb = SAA7164_MPEG_DVB, + .portc = SAA7164_MPEG_ENCODER, + .portd = SAA7164_MPEG_ENCODER, + .porte = SAA7164_MPEG_VBI, + .portf = SAA7164_MPEG_VBI, + .chiprev = SAA7164_CHIP_REV3, + .unit = {{ + .id = 0x28, + .type = SAA7164_UNIT_EEPROM, + .name = "4K EEPROM", + .i2c_bus_nr = SAA7164_I2C_BUS_0, + .i2c_bus_addr = 0xa0 >> 1, + .i2c_reg_len = REGLEN_8bit, + }, { + .id = 0x04, + .type = SAA7164_UNIT_TUNER, + .name = "SI2157-1", + .i2c_bus_nr = SAA7164_I2C_BUS_0, + .i2c_bus_addr = 0xc0 >> 1, + .i2c_reg_len = REGLEN_0bit, + }, { + .id = 0x06, + .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, + .name = "LGDT3306-1", + .i2c_bus_nr = SAA7164_I2C_BUS_2, + .i2c_bus_addr = 0xb2 >> 1, + .i2c_reg_len = REGLEN_8bit, + }, { + .id = 0x25, + .type = SAA7164_UNIT_TUNER, + .name = "SI2157-2", + .i2c_bus_nr = SAA7164_I2C_BUS_1, + .i2c_bus_addr = 0xc0 >> 1, + .i2c_reg_len = REGLEN_0bit, + }, { + .id = 0x27, + .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, + .name = "LGDT3306-2", + .i2c_bus_nr = SAA7164_I2C_BUS_2, + .i2c_bus_addr = 0x1c >> 1, + .i2c_reg_len = REGLEN_8bit, + } }, + }, + [SAA7164_BOARD_HAUPPAUGE_HVR2205] = { + .name = "Hauppauge WinTV-HVR2205", + .porta = SAA7164_MPEG_DVB, + .portb = SAA7164_MPEG_DVB, + .portc = SAA7164_MPEG_ENCODER, + .portd = SAA7164_MPEG_ENCODER, + .porte = SAA7164_MPEG_VBI, + .portf = SAA7164_MPEG_VBI, + .chiprev = SAA7164_CHIP_REV3, + .unit = {{ + .id = 0x28, + .type = SAA7164_UNIT_EEPROM, + .name = "4K EEPROM", + .i2c_bus_nr = SAA7164_I2C_BUS_0, + .i2c_bus_addr = 0xa0 >> 1, + .i2c_reg_len = REGLEN_8bit, + }, { + .id = 0x04, + .type = SAA7164_UNIT_TUNER, + .name = "SI2157-1", + .i2c_bus_nr = SAA7164_I2C_BUS_0, + .i2c_bus_addr = 0xc0 >> 1, + .i2c_reg_len = REGLEN_0bit, + }, { + .id = 0x06, + .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, + .name = "SI2168-1", + .i2c_bus_nr = SAA7164_I2C_BUS_2, + .i2c_bus_addr = 0xc8 >> 1, + .i2c_reg_len = REGLEN_8bit, + }, { + .id = 0x25, + .type = SAA7164_UNIT_TUNER, + .name = "SI2157-2", + .i2c_bus_nr = SAA7164_I2C_BUS_1, + .i2c_bus_addr = 0xc0 >> 1, + .i2c_reg_len = REGLEN_0bit, + }, { + .id = 0x27, + .type = SAA7164_UNIT_DIGITAL_DEMODULATOR, + .name = "SI2168-2", + .i2c_bus_nr = SAA7164_I2C_BUS_2, + .i2c_bus_addr = 0xcc >> 1, + .i2c_reg_len = REGLEN_8bit, + } }, + }, }; const unsigned int saa7164_bcount = ARRAY_SIZE(saa7164_boards); @@ -546,6 +685,21 @@ struct saa7164_subid saa7164_subids[] = { .subvendor = 0x0070, .subdevice = 0x8953, .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_5, + }, { + .subvendor = 0x0070, + .subdevice = 0xf111, + .card = SAA7164_BOARD_HAUPPAUGE_HVR2255, + /* Prototype card left here for documenation purposes. + .card = SAA7164_BOARD_HAUPPAUGE_HVR2255proto, + */ + }, { + .subvendor = 0x0070, + .subdevice = 0xf123, + .card = SAA7164_BOARD_HAUPPAUGE_HVR2205, + }, { + .subvendor = 0x0070, + .subdevice = 0xf120, + .card = SAA7164_BOARD_HAUPPAUGE_HVR2205, }, }; const unsigned int saa7164_idcount = ARRAY_SIZE(saa7164_subids); @@ -594,12 +748,26 @@ void saa7164_gpio_setup(struct saa7164_dev *dev) case SAA7164_BOARD_HAUPPAUGE_HVR2250: case SAA7164_BOARD_HAUPPAUGE_HVR2250_2: case SAA7164_BOARD_HAUPPAUGE_HVR2250_3: + case SAA7164_BOARD_HAUPPAUGE_HVR2255proto: + case SAA7164_BOARD_HAUPPAUGE_HVR2255: + case SAA7164_BOARD_HAUPPAUGE_HVR2205: /* + HVR2200 / HVR2250 GPIO 2: s5h1411 / tda10048-1 demod reset GPIO 3: s5h1411 / tda10048-2 demod reset GPIO 7: IRBlaster Zilog reset */ + /* HVR2255 + * GPIO 2: lgdg3306-1 demod reset + * GPIO 3: lgdt3306-2 demod reset + */ + + /* HVR2205 + * GPIO 2: si2168-1 demod reset + * GPIO 3: si2168-2 demod reset + */ + /* Reset parts by going in and out of reset */ saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 2); saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 3); @@ -647,6 +815,21 @@ static void hauppauge_eeprom(struct saa7164_dev *dev, u8 *eeprom_data) /* WinTV-HVR2200 (PCIe, Retail, half-height) * DVB-T (TDA18271/TDA10048) and basic analog, no IR */ break; + case 151009: + /* First production board rev B2I6 */ + /* WinTV-HVR2205 (PCIe, Retail, full-height bracket) + * DVB-T/T2/C (SI2157/SI2168) and basic analog, FM */ + break; + case 151609: + /* First production board rev B2I6 */ + /* WinTV-HVR2205 (PCIe, Retail, half-height bracket) + * DVB-T/T2/C (SI2157/SI2168) and basic analog, FM */ + break; + case 151061: + /* First production board rev B1I6 */ + /* WinTV-HVR2255 (PCIe, Retail, full-height bracket) + * ATSC/QAM (SI2157/LGDT3306) and basic analog, FM */ + break; default: printk(KERN_ERR "%s: Warning: Unknown Hauppauge model #%d\n", dev->name, tv.model); @@ -676,6 +859,9 @@ void saa7164_card_setup(struct saa7164_dev *dev) case SAA7164_BOARD_HAUPPAUGE_HVR2250: case SAA7164_BOARD_HAUPPAUGE_HVR2250_2: case SAA7164_BOARD_HAUPPAUGE_HVR2250_3: + case SAA7164_BOARD_HAUPPAUGE_HVR2255proto: + case SAA7164_BOARD_HAUPPAUGE_HVR2255: + case SAA7164_BOARD_HAUPPAUGE_HVR2205: hauppauge_eeprom(dev, &eeprom[0]); break; } diff --git a/drivers/media/pci/saa7164/saa7164-dvb.c b/drivers/media/pci/saa7164/saa7164-dvb.c index 16ae71592e8c..89fa2999633f 100644 --- a/drivers/media/pci/saa7164/saa7164-dvb.c +++ b/drivers/media/pci/saa7164/saa7164-dvb.c @@ -24,6 +24,9 @@ #include "tda10048.h" #include "tda18271.h" #include "s5h1411.h" +#include "si2157.h" +#include "si2168.h" +#include "lgdt3306a.h" #define DRIVER_NAME "saa7164" @@ -82,6 +85,64 @@ static struct s5h1411_config hauppauge_s5h1411_config = { .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, }; +static struct lgdt3306a_config hauppauge_hvr2255a_config = { + .i2c_addr = 0xb2 >> 1, + .qam_if_khz = 4000, + .vsb_if_khz = 3250, + .deny_i2c_rptr = 1, /* Disabled */ + .spectral_inversion = 0, /* Disabled */ + .mpeg_mode = LGDT3306A_MPEG_SERIAL, + .tpclk_edge = LGDT3306A_TPCLK_RISING_EDGE, + .tpvalid_polarity = LGDT3306A_TP_VALID_HIGH, + .xtalMHz = 25, /* 24 or 25 */ +}; + +static struct lgdt3306a_config hauppauge_hvr2255b_config = { + .i2c_addr = 0x1c >> 1, + .qam_if_khz = 4000, + .vsb_if_khz = 3250, + .deny_i2c_rptr = 1, /* Disabled */ + .spectral_inversion = 0, /* Disabled */ + .mpeg_mode = LGDT3306A_MPEG_SERIAL, + .tpclk_edge = LGDT3306A_TPCLK_RISING_EDGE, + .tpvalid_polarity = LGDT3306A_TP_VALID_HIGH, + .xtalMHz = 25, /* 24 or 25 */ +}; + +static struct si2157_config hauppauge_hvr2255_tuner_config = { + .inversion = 0, +}; + +static int si2157_attach(struct saa7164_port *port, struct i2c_adapter *adapter, + struct dvb_frontend *fe, u8 addr8bit, struct si2157_config *cfg) +{ + struct i2c_board_info bi; + struct i2c_client *tuner; + + cfg->fe = fe; + + memset(&bi, 0, sizeof(bi)); + + strlcpy(bi.type, "si2157", I2C_NAME_SIZE); + bi.platform_data = cfg; + bi.addr = addr8bit >> 1; + + request_module(bi.type); + + tuner = i2c_new_device(adapter, &bi); + if (tuner == NULL || tuner->dev.driver == NULL) + return -ENODEV; + + if (!try_module_get(tuner->dev.driver->owner)) { + i2c_unregister_device(tuner); + return -ENODEV; + } + + port->i2c_client_tuner = tuner; + + return 0; +} + static int saa7164_dvb_stop_port(struct saa7164_port *port) { struct saa7164_dev *dev = port->dev; @@ -242,14 +303,16 @@ static int saa7164_dvb_start_feed(struct dvb_demux_feed *feed) if (!demux->dmx.frontend) return -EINVAL; - mutex_lock(&dvb->lock); - if (dvb->feeding++ == 0) { - /* Start transport */ - ret = saa7164_dvb_start_port(port); + if (dvb) { + mutex_lock(&dvb->lock); + if (dvb->feeding++ == 0) { + /* Start transport */ + ret = saa7164_dvb_start_port(port); + } + mutex_unlock(&dvb->lock); + dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n", + __func__, port->nr, dvb->feeding); } - mutex_unlock(&dvb->lock); - dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n", - __func__, port->nr, dvb->feeding); return ret; } @@ -264,14 +327,16 @@ static int saa7164_dvb_stop_feed(struct dvb_demux_feed *feed) dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); - mutex_lock(&dvb->lock); - if (--dvb->feeding == 0) { - /* Stop transport */ - ret = saa7164_dvb_stop_streaming(port); + if (dvb) { + mutex_lock(&dvb->lock); + if (--dvb->feeding == 0) { + /* Stop transport */ + ret = saa7164_dvb_stop_streaming(port); + } + mutex_unlock(&dvb->lock); + dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n", + __func__, port->nr, dvb->feeding); } - mutex_unlock(&dvb->lock); - dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n", - __func__, port->nr, dvb->feeding); return ret; } @@ -425,6 +490,7 @@ int saa7164_dvb_unregister(struct saa7164_port *port) struct saa7164_dev *dev = port->dev; struct saa7164_buffer *b; struct list_head *c, *n; + struct i2c_client *client; dprintk(DBGLVL_DVB, "%s()\n", __func__); @@ -443,6 +509,20 @@ int saa7164_dvb_unregister(struct saa7164_port *port) if (dvb->frontend == NULL) return 0; + /* remove I2C client for tuner */ + client = port->i2c_client_tuner; + if (client) { + module_put(client->dev.driver->owner); + i2c_unregister_device(client); + } + + /* remove I2C client for demodulator */ + client = port->i2c_client_demod; + if (client) { + module_put(client->dev.driver->owner); + i2c_unregister_device(client); + } + dvb_net_release(&dvb->net); dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); @@ -462,6 +542,12 @@ int saa7164_dvb_register(struct saa7164_port *port) struct saa7164_dev *dev = port->dev; struct saa7164_dvb *dvb = &port->dvb; struct saa7164_i2c *i2c_bus = NULL; + struct si2168_config si2168_config; + struct si2157_config si2157_config; + struct i2c_adapter *adapter; + struct i2c_board_info info; + struct i2c_client *client_demod; + struct i2c_client *client_tuner; int ret; dprintk(DBGLVL_DVB, "%s()\n", __func__); @@ -527,6 +613,118 @@ int saa7164_dvb_register(struct saa7164_port *port) } } + break; + case SAA7164_BOARD_HAUPPAUGE_HVR2255proto: + case SAA7164_BOARD_HAUPPAUGE_HVR2255: + i2c_bus = &dev->i2c_bus[2]; + + if (port->nr == 0) { + port->dvb.frontend = dvb_attach(lgdt3306a_attach, + &hauppauge_hvr2255a_config, &i2c_bus->i2c_adap); + } else { + port->dvb.frontend = dvb_attach(lgdt3306a_attach, + &hauppauge_hvr2255b_config, &i2c_bus->i2c_adap); + } + + if (port->dvb.frontend != NULL) { + + if (port->nr == 0) { + si2157_attach(port, &dev->i2c_bus[0].i2c_adap, port->dvb.frontend, + 0xc0, &hauppauge_hvr2255_tuner_config); + } else { + si2157_attach(port, &dev->i2c_bus[1].i2c_adap, port->dvb.frontend, + 0xc0, &hauppauge_hvr2255_tuner_config); + } + } + break; + case SAA7164_BOARD_HAUPPAUGE_HVR2205: + + if (port->nr == 0) { + /* attach frontend */ + memset(&si2168_config, 0, sizeof(si2168_config)); + si2168_config.i2c_adapter = &adapter; + si2168_config.fe = &port->dvb.frontend; + si2168_config.ts_mode = SI2168_TS_SERIAL; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2168", I2C_NAME_SIZE); + info.addr = 0xc8 >> 1; + info.platform_data = &si2168_config; + request_module(info.type); + client_demod = i2c_new_device(&dev->i2c_bus[2].i2c_adap, &info); + if (client_demod == NULL || client_demod->dev.driver == NULL) { + goto frontend_detach; + } + if (!try_module_get(client_demod->dev.driver->owner)) { + i2c_unregister_device(client_demod); + goto frontend_detach; + } + port->i2c_client_demod = client_demod; + + /* attach tuner */ + memset(&si2157_config, 0, sizeof(si2157_config)); + si2157_config.fe = port->dvb.frontend; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2157", I2C_NAME_SIZE); + info.addr = 0xc0 >> 1; + info.platform_data = &si2157_config; + request_module(info.type); + client_tuner = i2c_new_device(&dev->i2c_bus[0].i2c_adap, &info); + if (client_tuner == NULL || client_tuner->dev.driver == NULL) { + module_put(client_demod->dev.driver->owner); + i2c_unregister_device(client_demod); + goto frontend_detach; + } + if (!try_module_get(client_tuner->dev.driver->owner)) { + i2c_unregister_device(client_tuner); + module_put(client_demod->dev.driver->owner); + i2c_unregister_device(client_demod); + goto frontend_detach; + } + port->i2c_client_tuner = client_tuner; + } else { + /* attach frontend */ + memset(&si2168_config, 0, sizeof(si2168_config)); + si2168_config.i2c_adapter = &adapter; + si2168_config.fe = &port->dvb.frontend; + si2168_config.ts_mode = SI2168_TS_SERIAL; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2168", I2C_NAME_SIZE); + info.addr = 0xcc >> 1; + info.platform_data = &si2168_config; + request_module(info.type); + client_demod = i2c_new_device(&dev->i2c_bus[2].i2c_adap, &info); + if (client_demod == NULL || client_demod->dev.driver == NULL) { + goto frontend_detach; + } + if (!try_module_get(client_demod->dev.driver->owner)) { + i2c_unregister_device(client_demod); + goto frontend_detach; + } + port->i2c_client_demod = client_demod; + + /* attach tuner */ + memset(&si2157_config, 0, sizeof(si2157_config)); + si2157_config.fe = port->dvb.frontend; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2157", I2C_NAME_SIZE); + info.addr = 0xc0 >> 1; + info.platform_data = &si2157_config; + request_module(info.type); + client_tuner = i2c_new_device(&dev->i2c_bus[1].i2c_adap, &info); + if (client_tuner == NULL || client_tuner->dev.driver == NULL) { + module_put(client_demod->dev.driver->owner); + i2c_unregister_device(client_demod); + goto frontend_detach; + } + if (!try_module_get(client_tuner->dev.driver->owner)) { + i2c_unregister_device(client_tuner); + module_put(client_demod->dev.driver->owner); + i2c_unregister_device(client_demod); + goto frontend_detach; + } + port->i2c_client_tuner = client_tuner; + } + break; default: printk(KERN_ERR "%s: The frontend isn't supported\n", @@ -548,5 +746,9 @@ int saa7164_dvb_register(struct saa7164_port *port) } return 0; + +frontend_detach: + printk(KERN_ERR "%s() Frontend/I2C initialization failed\n", __func__); + return -1; } diff --git a/drivers/media/pci/saa7164/saa7164.h b/drivers/media/pci/saa7164/saa7164.h index cd1a07ce27cb..33e30b3c5088 100644 --- a/drivers/media/pci/saa7164/saa7164.h +++ b/drivers/media/pci/saa7164/saa7164.h @@ -83,6 +83,9 @@ #define SAA7164_BOARD_HAUPPAUGE_HVR2250_3 8 #define SAA7164_BOARD_HAUPPAUGE_HVR2200_4 9 #define SAA7164_BOARD_HAUPPAUGE_HVR2200_5 10 +#define SAA7164_BOARD_HAUPPAUGE_HVR2255proto 11 +#define SAA7164_BOARD_HAUPPAUGE_HVR2255 12 +#define SAA7164_BOARD_HAUPPAUGE_HVR2205 13 #define SAA7164_MAX_UNITS 8 #define SAA7164_TS_NUMBER_OF_LINES 312 @@ -371,6 +374,8 @@ struct saa7164_port { /* --- DVB Transport Specific --- */ struct saa7164_dvb dvb; + struct i2c_client *i2c_client_demod; + struct i2c_client *i2c_client_tuner; /* --- Encoder/V4L related attributes --- */ /* Encoder */ -- cgit v1.2.3-59-g8ed1b From 63a412ec36ce90daec425ed0ab127e1af7e061fb Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 23 Mar 2015 16:08:15 -0300 Subject: [media] saa7164: Copyright update Updates the copyright notes at the saa7164 driver. Signed-off-by: Steven Toth Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7164/saa7164-api.c | 2 +- drivers/media/pci/saa7164/saa7164-buffer.c | 2 +- drivers/media/pci/saa7164/saa7164-bus.c | 2 +- drivers/media/pci/saa7164/saa7164-cards.c | 2 +- drivers/media/pci/saa7164/saa7164-cmd.c | 2 +- drivers/media/pci/saa7164/saa7164-core.c | 2 +- drivers/media/pci/saa7164/saa7164-dvb.c | 2 +- drivers/media/pci/saa7164/saa7164-encoder.c | 2 +- drivers/media/pci/saa7164/saa7164-fw.c | 2 +- drivers/media/pci/saa7164/saa7164-i2c.c | 2 +- drivers/media/pci/saa7164/saa7164-reg.h | 2 +- drivers/media/pci/saa7164/saa7164-types.h | 2 +- drivers/media/pci/saa7164/saa7164-vbi.c | 2 +- drivers/media/pci/saa7164/saa7164.h | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7164/saa7164-api.c b/drivers/media/pci/saa7164/saa7164-api.c index d9e21e736d1f..a992af6e43a4 100644 --- a/drivers/media/pci/saa7164/saa7164-api.c +++ b/drivers/media/pci/saa7164/saa7164-api.c @@ -1,7 +1,7 @@ /* * Driver for the NXP SAA7164 PCIe bridge * - * Copyright (c) 2010 Steven Toth + * Copyright (c) 2010-2015 Steven Toth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/pci/saa7164/saa7164-buffer.c b/drivers/media/pci/saa7164/saa7164-buffer.c index 9bd1f73f82da..f30758e24f5d 100644 --- a/drivers/media/pci/saa7164/saa7164-buffer.c +++ b/drivers/media/pci/saa7164/saa7164-buffer.c @@ -1,7 +1,7 @@ /* * Driver for the NXP SAA7164 PCIe bridge * - * Copyright (c) 2010 Steven Toth + * Copyright (c) 2010-2015 Steven Toth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/pci/saa7164/saa7164-bus.c b/drivers/media/pci/saa7164/saa7164-bus.c index 6c73f5b155f6..a18fe5d47238 100644 --- a/drivers/media/pci/saa7164/saa7164-bus.c +++ b/drivers/media/pci/saa7164/saa7164-bus.c @@ -1,7 +1,7 @@ /* * Driver for the NXP SAA7164 PCIe bridge * - * Copyright (c) 2010 Steven Toth + * Copyright (c) 2010-2015 Steven Toth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/pci/saa7164/saa7164-cards.c b/drivers/media/pci/saa7164/saa7164-cards.c index 2ca5e5d5580d..8a6455d282c3 100644 --- a/drivers/media/pci/saa7164/saa7164-cards.c +++ b/drivers/media/pci/saa7164/saa7164-cards.c @@ -1,7 +1,7 @@ /* * Driver for the NXP SAA7164 PCIe bridge * - * Copyright (c) 2010 Steven Toth + * Copyright (c) 2010-2015 Steven Toth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/pci/saa7164/saa7164-cmd.c b/drivers/media/pci/saa7164/saa7164-cmd.c index cfabcbacc33d..3285c37b4583 100644 --- a/drivers/media/pci/saa7164/saa7164-cmd.c +++ b/drivers/media/pci/saa7164/saa7164-cmd.c @@ -1,7 +1,7 @@ /* * Driver for the NXP SAA7164 PCIe bridge * - * Copyright (c) 2010 Steven Toth + * Copyright (c) 2010-2015 Steven Toth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index 072dcc8f13d9..90de80726f0a 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -1,7 +1,7 @@ /* * Driver for the NXP SAA7164 PCIe bridge * - * Copyright (c) 2010 Steven Toth + * Copyright (c) 2010-2015 Steven Toth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/pci/saa7164/saa7164-dvb.c b/drivers/media/pci/saa7164/saa7164-dvb.c index 89fa2999633f..3954f0afbbae 100644 --- a/drivers/media/pci/saa7164/saa7164-dvb.c +++ b/drivers/media/pci/saa7164/saa7164-dvb.c @@ -1,7 +1,7 @@ /* * Driver for the NXP SAA7164 PCIe bridge * - * Copyright (c) 2010 Steven Toth + * Copyright (c) 2010-2015 Steven Toth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/pci/saa7164/saa7164-encoder.c b/drivers/media/pci/saa7164/saa7164-encoder.c index 9266965412c3..1ceed0cdced0 100644 --- a/drivers/media/pci/saa7164/saa7164-encoder.c +++ b/drivers/media/pci/saa7164/saa7164-encoder.c @@ -1,7 +1,7 @@ /* * Driver for the NXP SAA7164 PCIe bridge * - * Copyright (c) 2010 Steven Toth + * Copyright (c) 2010-2015 Steven Toth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/pci/saa7164/saa7164-fw.c b/drivers/media/pci/saa7164/saa7164-fw.c index add06ab5124d..269e0782c7b6 100644 --- a/drivers/media/pci/saa7164/saa7164-fw.c +++ b/drivers/media/pci/saa7164/saa7164-fw.c @@ -1,7 +1,7 @@ /* * Driver for the NXP SAA7164 PCIe bridge * - * Copyright (c) 2010 Steven Toth + * Copyright (c) 2010-2015 Steven Toth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/pci/saa7164/saa7164-i2c.c b/drivers/media/pci/saa7164/saa7164-i2c.c index 3b37c96d2a7c..6ea9d4f9ef2e 100644 --- a/drivers/media/pci/saa7164/saa7164-i2c.c +++ b/drivers/media/pci/saa7164/saa7164-i2c.c @@ -1,7 +1,7 @@ /* * Driver for the NXP SAA7164 PCIe bridge * - * Copyright (c) 2010 Steven Toth + * Copyright (c) 2010-2015 Steven Toth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/pci/saa7164/saa7164-reg.h b/drivers/media/pci/saa7164/saa7164-reg.h index 2bbf81583d33..37521a2ee504 100644 --- a/drivers/media/pci/saa7164/saa7164-reg.h +++ b/drivers/media/pci/saa7164/saa7164-reg.h @@ -1,7 +1,7 @@ /* * Driver for the NXP SAA7164 PCIe bridge * - * Copyright (c) 2010 Steven Toth + * Copyright (c) 2010-2015 Steven Toth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/pci/saa7164/saa7164-types.h b/drivers/media/pci/saa7164/saa7164-types.h index f48ba978f835..1efba6c64ebf 100644 --- a/drivers/media/pci/saa7164/saa7164-types.h +++ b/drivers/media/pci/saa7164/saa7164-types.h @@ -1,7 +1,7 @@ /* * Driver for the NXP SAA7164 PCIe bridge * - * Copyright (c) 2010 Steven Toth + * Copyright (c) 2010-2015 Steven Toth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/pci/saa7164/saa7164-vbi.c b/drivers/media/pci/saa7164/saa7164-vbi.c index 6e025fea2542..56b33fd65328 100644 --- a/drivers/media/pci/saa7164/saa7164-vbi.c +++ b/drivers/media/pci/saa7164/saa7164-vbi.c @@ -1,7 +1,7 @@ /* * Driver for the NXP SAA7164 PCIe bridge * - * Copyright (c) 2010 Steven Toth + * Copyright (c) 2010-2015 Steven Toth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/pci/saa7164/saa7164.h b/drivers/media/pci/saa7164/saa7164.h index 33e30b3c5088..138f7f93ee7d 100644 --- a/drivers/media/pci/saa7164/saa7164.h +++ b/drivers/media/pci/saa7164/saa7164.h @@ -1,7 +1,7 @@ /* * Driver for the NXP SAA7164 PCIe bridge * - * Copyright (c) 2010 Steven Toth + * Copyright (c) 2010-2015 Steven Toth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by -- cgit v1.2.3-59-g8ed1b From fb6bcec3cec6acedaebc92aef7f4203e2502e318 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Sat, 28 Mar 2015 09:07:47 -0300 Subject: [media] saa7164: fix HVR2255 ATSC inversion issue QAM mode in the LGDT3306 auto detects inversion. VSB does not. Forgot to include tis fact in the original patch set. Tested with QAM and VSB after this patch, working fine. Signed-off-by: Steven Toth Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7164/saa7164-dvb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7164/saa7164-dvb.c b/drivers/media/pci/saa7164/saa7164-dvb.c index 3954f0afbbae..0fdc9447a0fe 100644 --- a/drivers/media/pci/saa7164/saa7164-dvb.c +++ b/drivers/media/pci/saa7164/saa7164-dvb.c @@ -110,7 +110,7 @@ static struct lgdt3306a_config hauppauge_hvr2255b_config = { }; static struct si2157_config hauppauge_hvr2255_tuner_config = { - .inversion = 0, + .inversion = 1, }; static int si2157_attach(struct saa7164_port *port, struct i2c_adapter *adapter, -- cgit v1.2.3-59-g8ed1b From 534bc3e2ee93835badca753bedce8073c67caa92 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 27 Mar 2015 15:17:56 -0300 Subject: [media] saa7164: fix querycap warning Fix the VIDIOC_QUERYCAP warning due to the missing device_caps. Don't fill in the version field, the V4L2 core will do that for you. Signed-off-by: Hans Verkuil Cc: # for v3.19 and up Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7164/saa7164-encoder.c | 11 ++++++----- drivers/media/pci/saa7164/saa7164-vbi.c | 11 ++++++----- 2 files changed, 12 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7164/saa7164-encoder.c b/drivers/media/pci/saa7164/saa7164-encoder.c index 1ceed0cdced0..4434e0f28c26 100644 --- a/drivers/media/pci/saa7164/saa7164-encoder.c +++ b/drivers/media/pci/saa7164/saa7164-encoder.c @@ -721,13 +721,14 @@ static int vidioc_querycap(struct file *file, void *priv, sizeof(cap->card)); sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); - cap->capabilities = + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_READWRITE | - 0; + V4L2_CAP_READWRITE | + V4L2_CAP_TUNER; - cap->capabilities |= V4L2_CAP_TUNER; - cap->version = 0; + cap->capabilities = cap->device_caps | + V4L2_CAP_VBI_CAPTURE | + V4L2_CAP_DEVICE_CAPS; return 0; } diff --git a/drivers/media/pci/saa7164/saa7164-vbi.c b/drivers/media/pci/saa7164/saa7164-vbi.c index 56b33fd65328..859fd03d82f9 100644 --- a/drivers/media/pci/saa7164/saa7164-vbi.c +++ b/drivers/media/pci/saa7164/saa7164-vbi.c @@ -660,13 +660,14 @@ static int vidioc_querycap(struct file *file, void *priv, sizeof(cap->card)); sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); - cap->capabilities = + cap->device_caps = V4L2_CAP_VBI_CAPTURE | - V4L2_CAP_READWRITE | - 0; + V4L2_CAP_READWRITE | + V4L2_CAP_TUNER; - cap->capabilities |= V4L2_CAP_TUNER; - cap->version = 0; + cap->capabilities = cap->device_caps | + V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_DEVICE_CAPS; return 0; } -- cgit v1.2.3-59-g8ed1b From 3600433f19f59410010770d61ead509d785b8a6e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 1 May 2015 07:30:40 -0300 Subject: saa7164: Fix CodingStyle issues added on previous patches The patches that added support for HVR2255 and HVR2205 added some CodingStyle issues. Better to fix it sooner than latter. Cc: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7164/saa7164-api.c | 3 ++- drivers/media/pci/saa7164/saa7164-dvb.c | 34 +++++++++++++++++++-------------- 2 files changed, 22 insertions(+), 15 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7164/saa7164-api.c b/drivers/media/pci/saa7164/saa7164-api.c index a992af6e43a4..e8077037fb5c 100644 --- a/drivers/media/pci/saa7164/saa7164-api.c +++ b/drivers/media/pci/saa7164/saa7164-api.c @@ -1467,7 +1467,8 @@ int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen, return -EIO; } - dprintk(DBGLVL_API, "%s() len = %d bytes unitid=0x%x\n", __func__, len, unitid); + dprintk(DBGLVL_API, "%s() len = %d bytes unitid=0x%x\n", __func__, + len, unitid); /* Prepare the send buffer */ /* Bytes 00-03 dest register length diff --git a/drivers/media/pci/saa7164/saa7164-dvb.c b/drivers/media/pci/saa7164/saa7164-dvb.c index 0fdc9447a0fe..c68ce2631e8f 100644 --- a/drivers/media/pci/saa7164/saa7164-dvb.c +++ b/drivers/media/pci/saa7164/saa7164-dvb.c @@ -629,11 +629,13 @@ int saa7164_dvb_register(struct saa7164_port *port) if (port->dvb.frontend != NULL) { if (port->nr == 0) { - si2157_attach(port, &dev->i2c_bus[0].i2c_adap, port->dvb.frontend, - 0xc0, &hauppauge_hvr2255_tuner_config); + si2157_attach(port, &dev->i2c_bus[0].i2c_adap, + port->dvb.frontend, 0xc0, + &hauppauge_hvr2255_tuner_config); } else { - si2157_attach(port, &dev->i2c_bus[1].i2c_adap, port->dvb.frontend, - 0xc0, &hauppauge_hvr2255_tuner_config); + si2157_attach(port, &dev->i2c_bus[1].i2c_adap, + port->dvb.frontend, 0xc0, + &hauppauge_hvr2255_tuner_config); } } break; @@ -650,10 +652,11 @@ int saa7164_dvb_register(struct saa7164_port *port) info.addr = 0xc8 >> 1; info.platform_data = &si2168_config; request_module(info.type); - client_demod = i2c_new_device(&dev->i2c_bus[2].i2c_adap, &info); - if (client_demod == NULL || client_demod->dev.driver == NULL) { + client_demod = i2c_new_device(&dev->i2c_bus[2].i2c_adap, + &info); + if (!client_demod || !client_demod->dev.driver) goto frontend_detach; - } + if (!try_module_get(client_demod->dev.driver->owner)) { i2c_unregister_device(client_demod); goto frontend_detach; @@ -668,8 +671,9 @@ int saa7164_dvb_register(struct saa7164_port *port) info.addr = 0xc0 >> 1; info.platform_data = &si2157_config; request_module(info.type); - client_tuner = i2c_new_device(&dev->i2c_bus[0].i2c_adap, &info); - if (client_tuner == NULL || client_tuner->dev.driver == NULL) { + client_tuner = i2c_new_device(&dev->i2c_bus[0].i2c_adap, + &info); + if (!client_tuner || !client_tuner->dev.driver) { module_put(client_demod->dev.driver->owner); i2c_unregister_device(client_demod); goto frontend_detach; @@ -692,10 +696,11 @@ int saa7164_dvb_register(struct saa7164_port *port) info.addr = 0xcc >> 1; info.platform_data = &si2168_config; request_module(info.type); - client_demod = i2c_new_device(&dev->i2c_bus[2].i2c_adap, &info); - if (client_demod == NULL || client_demod->dev.driver == NULL) { + client_demod = i2c_new_device(&dev->i2c_bus[2].i2c_adap, + &info); + if (!client_tuner || !client_tuner->dev.driver) goto frontend_detach; - } + if (!try_module_get(client_demod->dev.driver->owner)) { i2c_unregister_device(client_demod); goto frontend_detach; @@ -710,8 +715,9 @@ int saa7164_dvb_register(struct saa7164_port *port) info.addr = 0xc0 >> 1; info.platform_data = &si2157_config; request_module(info.type); - client_tuner = i2c_new_device(&dev->i2c_bus[1].i2c_adap, &info); - if (client_tuner == NULL || client_tuner->dev.driver == NULL) { + client_tuner = i2c_new_device(&dev->i2c_bus[1].i2c_adap, + &info); + if (!client_tuner || !client_tuner->dev.driver) { module_put(client_demod->dev.driver->owner); i2c_unregister_device(client_demod); goto frontend_detach; -- cgit v1.2.3-59-g8ed1b From 2b4fd3ede3bab65ef5b97387b90899d11e4d3202 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 24 Apr 2015 03:55:07 -0300 Subject: [media] cx18: add missing caps for the PCM video device The cx18 PCM video device didn't have any capabilities set, which caused a warnings in the v4l2 core: [ 6.229393] ------------[ cut here ]------------ [ 6.229414] WARNING: CPU: 1 PID: 593 at drivers/media/v4l2-core/v4l2-ioctl.c:1025 v4l_querycap+0x41/0x70 [videodev]() [ 6.229415] Modules linked in: cx18_alsa mxl5005s s5h1409 tuner_simple tuner_types cs5345 tuner intel_rapl iosf_mbi x86_pkg_temp_thermal coretemp raid1 snd_hda_codec_realtek kvm_intel snd_hda_codec_generic snd_hda_codec_hdmi kvm snd_oxygen(+) snd_hda_intel snd_oxygen_lib snd_hda_controller snd_hda_codec snd_mpu401_uart iTCO_wdt snd_rawmidi iTCO_vendor_support snd_hwdep crct10dif_pclmul crc32_pclmul crc32c_intel snd_seq cx18 snd_seq_device ghash_clmulni_intel videobuf_vmalloc tveeprom cx2341x snd_pcm serio_raw videobuf_core vfat dvb_core fat v4l2_common snd_timer videodev snd lpc_ich i2c_i801 joydev mfd_core mei_me media soundcore tpm_infineon soc_button_array tpm_tis mei shpchp tpm nfsd auth_rpcgss nfs_acl lockd grace sunrpc binfmt_misc i915 nouveau mxm_wmi wmi e1000e ttm i2c_algo_bit drm_kms_helper [ 6.229444] drm ptp pps_core video [ 6.229446] CPU: 1 PID: 593 Comm: v4l_id Not tainted 3.19.3-200.fc21.x86_64 #1 [ 6.229447] Hardware name: Gigabyte Technology Co., Ltd. Z87-D3HP/Z87-D3HP-CF, BIOS F6 01/20/2014 [ 6.229448] 0000000000000000 00000000d12b1131 ffff88042dacfc28 ffffffff8176e215 [ 6.229449] 0000000000000000 0000000000000000 ffff88042dacfc68 ffffffff8109bc1a [ 6.229451] ffffffffa0594000 ffff88042dacfd90 0000000000000000 ffffffffa04e2140 [ 6.229452] Call Trace: [ 6.229466] [] dump_stack+0x45/0x57 [ 6.229469] [] warn_slowpath_common+0x8a/0xc0 [ 6.229472] [] warn_slowpath_null+0x1a/0x20 [ 6.229474] [] v4l_querycap+0x41/0x70 [videodev] [ 6.229477] [] __video_do_ioctl+0x29c/0x320 [videodev] [ 6.229479] [] ? do_last+0x2f1/0x1210 [ 6.229491] [] video_usercopy+0x366/0x5d0 [videodev] [ 6.229494] [] ? v4l_querycap+0x70/0x70 [videodev] [ 6.229497] [] video_ioctl2+0x15/0x20 [videodev] [ 6.229499] [] v4l2_ioctl+0x164/0x180 [videodev] [ 6.229501] [] do_vfs_ioctl+0x2f8/0x500 [ 6.229502] [] SyS_ioctl+0x81/0xa0 [ 6.229505] [] system_call_fastpath+0x12/0x17 [ 6.229506] ---[ end trace dacd80d4b19277ea ]--- Added the necessary capabilities to stop this warning. Signed-off-by: Hans Verkuil Reported-by: Laura Abbott Cc: # for v3.19 and up Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx18/cx18-streams.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/pci/cx18/cx18-streams.c b/drivers/media/pci/cx18/cx18-streams.c index c82d25d53341..c9860845264f 100644 --- a/drivers/media/pci/cx18/cx18-streams.c +++ b/drivers/media/pci/cx18/cx18-streams.c @@ -90,6 +90,7 @@ static struct { "encoder PCM audio", VFL_TYPE_GRABBER, CX18_V4L2_ENC_PCM_OFFSET, PCI_DMA_FROMDEVICE, + V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, }, { /* CX18_ENC_STREAM_TYPE_IDX */ "encoder IDX", -- cgit v1.2.3-59-g8ed1b From a988410ad141b5087f483ae32e4bd9b922be5ab8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 24 Apr 2015 04:26:01 -0300 Subject: [media] usbtv: fix v4l2-compliance issues Running v4l2-compliance on my usbtv stick revealed two failures: 1) Correct handling of CREATE_BUFS in usbtv_queue_setup was missing. Added this. 2) The sequence counter wasn't reset to 0 when starting streaming. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/usbtv/usbtv-video.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/usbtv/usbtv-video.c b/drivers/media/usb/usbtv/usbtv-video.c index 9d3525f659f0..08fb0f2da64d 100644 --- a/drivers/media/usb/usbtv/usbtv-video.c +++ b/drivers/media/usb/usbtv/usbtv-video.c @@ -599,15 +599,18 @@ static struct v4l2_file_operations usbtv_fops = { }; static int usbtv_queue_setup(struct vb2_queue *vq, - const struct v4l2_format *v4l_fmt, unsigned int *nbuffers, + const struct v4l2_format *fmt, unsigned int *nbuffers, unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[]) { struct usbtv *usbtv = vb2_get_drv_priv(vq); + unsigned size = USBTV_CHUNK * usbtv->n_chunks * 2 * sizeof(u32); - if (*nbuffers < 2) - *nbuffers = 2; + if (vq->num_buffers + *nbuffers < 2) + *nbuffers = 2 - vq->num_buffers; *nplanes = 1; - sizes[0] = USBTV_CHUNK * usbtv->n_chunks * 2 * sizeof(u32); + if (fmt && fmt->fmt.pix.sizeimage < size) + return -EINVAL; + sizes[0] = fmt ? fmt->fmt.pix.sizeimage : size; return 0; } @@ -635,6 +638,7 @@ static int usbtv_start_streaming(struct vb2_queue *vq, unsigned int count) if (usbtv->udev == NULL) return -ENODEV; + usbtv->sequence = 0; return usbtv_start(usbtv); } -- cgit v1.2.3-59-g8ed1b From 17d3675a8ae464954f604f6be518a0d2af1debda Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 3 Mar 2015 15:07:27 -0300 Subject: [media] marvell-ccic: fix vb2 warning We must set timestamp_flags in vb2_queue otherwise vb2 will complain loudly about it. Signed-off-by: Hans Verkuil Acked-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/marvell-ccic/mcam-core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index 9c64b5d01c6a..bf160dd0a329 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -1246,6 +1246,7 @@ static int mcam_setup_vb2(struct mcam_camera *cam) vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; vq->drv_priv = cam; vq->lock = &cam->s_mutex; + vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; INIT_LIST_HEAD(&cam->buffers); switch (cam->buffer_mode) { case B_DMA_contig: -- cgit v1.2.3-59-g8ed1b From b7b683938a262a63b793f629d0f006e40029604f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 5 Mar 2015 04:57:32 -0300 Subject: [media] marvell-ccic: fill in bus_info The bus_info field of struct v4l2_querycap wasn't filled in and v4l2-compliance complained about that. Fix this. Signed-off-by: Hans Verkuil Acked-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/marvell-ccic/cafe-driver.c | 1 + drivers/media/platform/marvell-ccic/mcam-core.c | 3 +++ drivers/media/platform/marvell-ccic/mcam-core.h | 2 ++ drivers/media/platform/marvell-ccic/mmp-driver.c | 1 + 4 files changed, 7 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/platform/marvell-ccic/cafe-driver.c b/drivers/media/platform/marvell-ccic/cafe-driver.c index 562845361246..e857405b46fd 100644 --- a/drivers/media/platform/marvell-ccic/cafe-driver.c +++ b/drivers/media/platform/marvell-ccic/cafe-driver.c @@ -476,6 +476,7 @@ static int cafe_pci_probe(struct pci_dev *pdev, mcam->plat_power_up = cafe_ctlr_power_up; mcam->plat_power_down = cafe_ctlr_power_down; mcam->dev = &pdev->dev; + snprintf(mcam->bus_info, sizeof(mcam->bus_info), "PCI:%s", pci_name(pdev)); /* * Set the clock speed for the XO 1; I don't believe this * driver has ever run anywhere else. diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index bf160dd0a329..e83ca1fd6148 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -1388,8 +1388,11 @@ static int mcam_vidioc_dqbuf(struct file *filp, void *priv, static int mcam_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { + struct mcam_camera *cam = priv; + strcpy(cap->driver, "marvell_ccic"); strcpy(cap->card, "marvell_ccic"); + strlcpy(cap->bus_info, cam->bus_info, sizeof(cap->bus_info)); cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; diff --git a/drivers/media/platform/marvell-ccic/mcam-core.h b/drivers/media/platform/marvell-ccic/mcam-core.h index aa0c6eac254a..46bc7151a200 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.h +++ b/drivers/media/platform/marvell-ccic/mcam-core.h @@ -163,6 +163,8 @@ struct mcam_camera { unsigned int nbufs; /* How many are alloc'd */ int next_buf; /* Next to consume (dev_lock) */ + char bus_info[32]; /* querycap bus_info */ + /* DMA buffers - vmalloc mode */ #ifdef MCAM_MODE_VMALLOC unsigned int dma_buf_size; /* allocated size */ diff --git a/drivers/media/platform/marvell-ccic/mmp-driver.c b/drivers/media/platform/marvell-ccic/mmp-driver.c index 0ed9b3adfcdf..b5f165a68566 100644 --- a/drivers/media/platform/marvell-ccic/mmp-driver.c +++ b/drivers/media/platform/marvell-ccic/mmp-driver.c @@ -371,6 +371,7 @@ static int mmpcam_probe(struct platform_device *pdev) mcam->lane = pdata->lane; mcam->chip_id = MCAM_ARMADA610; mcam->buffer_mode = B_DMA_sg; + strlcpy(mcam->bus_info, "platform:mmp-camera", sizeof(mcam->bus_info)); spin_lock_init(&mcam->dev_lock); /* * Get our I/O memory. -- cgit v1.2.3-59-g8ed1b From 5a878f97fd8487b24f1328b75cfda069dc28f99b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 5 Mar 2015 05:01:28 -0300 Subject: [media] marvell-ccic: webcam drivers shouldn't support g/s_std TV standards make no sense for webcam drivers, so drop these dummy functions. This stops v4l2-compliance from complaining about this. Signed-off-by: Hans Verkuil Acked-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/marvell-ccic/mcam-core.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index e83ca1fd6148..76357cf1234a 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -1508,7 +1508,6 @@ static int mcam_vidioc_enum_input(struct file *filp, void *priv, return -EINVAL; input->type = V4L2_INPUT_TYPE_CAMERA; - input->std = V4L2_STD_ALL; /* Not sure what should go here */ strcpy(input->name, "Camera"); return 0; } @@ -1526,18 +1525,6 @@ static int mcam_vidioc_s_input(struct file *filp, void *priv, unsigned int i) return 0; } -/* from vivi.c */ -static int mcam_vidioc_s_std(struct file *filp, void *priv, v4l2_std_id a) -{ - return 0; -} - -static int mcam_vidioc_g_std(struct file *filp, void *priv, v4l2_std_id *a) -{ - *a = V4L2_STD_NTSC_M; - return 0; -} - /* * G/S_PARM. Most of this is done by the sensor, but we are * the level which controls the number of read buffers. @@ -1666,8 +1653,6 @@ static const struct v4l2_ioctl_ops mcam_v4l_ioctl_ops = { .vidioc_enum_input = mcam_vidioc_enum_input, .vidioc_g_input = mcam_vidioc_g_input, .vidioc_s_input = mcam_vidioc_s_input, - .vidioc_s_std = mcam_vidioc_s_std, - .vidioc_g_std = mcam_vidioc_g_std, .vidioc_reqbufs = mcam_vidioc_reqbufs, .vidioc_querybuf = mcam_vidioc_querybuf, .vidioc_qbuf = mcam_vidioc_qbuf, -- cgit v1.2.3-59-g8ed1b From b8cc79fd83b09fb3137fe3721bc4e161cec54ead Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 5 Mar 2015 05:15:30 -0300 Subject: [media] ov7670: check for valid width/height in ov7670_enum_frame_interval The width and height should be checked in the enum_frame_interval op. This fixes a v4l2-compliance failure. Signed-off-by: Hans Verkuil Acked-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov7670.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c index f2fe20aad274..d16bd81e669d 100644 --- a/drivers/media/i2c/ov7670.c +++ b/drivers/media/i2c/ov7670.c @@ -1073,10 +1073,33 @@ static int ov7670_enum_frame_interval(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_frame_interval_enum *fie) { + struct ov7670_info *info = to_state(sd); + unsigned int n_win_sizes = info->devtype->n_win_sizes; + int i; + if (fie->pad) return -EINVAL; if (fie->index >= ARRAY_SIZE(ov7670_frame_rates)) return -EINVAL; + + /* + * Check if the width/height is valid. + * + * If a minimum width/height was requested, filter out the capture + * windows that fall outside that. + */ + for (i = 0; i < n_win_sizes; i++) { + struct ov7670_win_size *win = &info->devtype->win_sizes[i]; + + if (info->min_width && win->width < info->min_width) + continue; + if (info->min_height && win->height < info->min_height) + continue; + if (fie->width == win->width && fie->height == win->height) + break; + } + if (i == n_win_sizes) + return -EINVAL; fie->interval.numerator = 1; fie->interval.denominator = ov7670_frame_rates[fie->index]; return 0; -- cgit v1.2.3-59-g8ed1b From 2e6e609530a1f4306b8fb3e2c4d6abff9d9be30e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 5 Mar 2015 05:19:23 -0300 Subject: [media] marvell-ccic: fill in colorspace The colorspace field wasn't filled in properly. This fixes a v4l2-compliance failure. Signed-off-by: Hans Verkuil Acked-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/marvell-ccic/mcam-core.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index 76357cf1234a..7e54cef09d54 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -188,6 +188,7 @@ static const struct v4l2_pix_format mcam_def_pix_format = { .field = V4L2_FIELD_NONE, .bytesperline = VGA_WIDTH*2, .sizeimage = VGA_WIDTH*VGA_HEIGHT*2, + .colorspace = V4L2_COLORSPACE_SRGB, }; static const u32 mcam_def_mbus_code = MEDIA_BUS_FMT_YUYV8_2X8; @@ -1437,6 +1438,7 @@ static int mcam_vidioc_try_fmt_vid_cap(struct file *filp, void *priv, break; } pix->sizeimage = pix->height * pix->bytesperline; + pix->colorspace = V4L2_COLORSPACE_SRGB; return ret; } -- cgit v1.2.3-59-g8ed1b From 1e4cbe677f596563060709b3af92480f873a0a6e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 5 Mar 2015 12:00:11 -0300 Subject: [media] marvell-ccic: control handler fixes No controls were reported, even though the ov7670 does have controls. Two reasons for this: the v4l2_ctrl_handler_init() call must come before the ov7670 is loaded (otherwise the ov7670 won't know that its controls should be added to the bridge driver), and the v4l2_ctrl_handler_free() call at the end should only be called if the ret value is non-zero (otherwise you would just free all the controls that were just added). Signed-off-by: Hans Verkuil Acked-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/marvell-ccic/mcam-core.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index 7e54cef09d54..51c9c8c69d03 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -1918,6 +1918,14 @@ int mccic_register(struct mcam_camera *cam) INIT_LIST_HEAD(&cam->buffers); mcam_ctlr_init(cam); + /* + * Get the v4l2 setup done. + */ + ret = v4l2_ctrl_handler_init(&cam->ctrl_handler, 10); + if (ret) + goto out_unregister; + cam->v4l2_dev.ctrl_handler = &cam->ctrl_handler; + /* * Try to find the sensor. */ @@ -1934,13 +1942,6 @@ int mccic_register(struct mcam_camera *cam) ret = mcam_cam_init(cam); if (ret) goto out_unregister; - /* - * Get the v4l2 setup done. - */ - ret = v4l2_ctrl_handler_init(&cam->ctrl_handler, 10); - if (ret) - goto out_unregister; - cam->v4l2_dev.ctrl_handler = &cam->ctrl_handler; mutex_lock(&cam->s_mutex); cam->vdev = mcam_v4l_template; @@ -1960,10 +1961,12 @@ int mccic_register(struct mcam_camera *cam) } out: - v4l2_ctrl_handler_free(&cam->ctrl_handler); + if (ret) + v4l2_ctrl_handler_free(&cam->ctrl_handler); mutex_unlock(&cam->s_mutex); return ret; out_unregister: + v4l2_ctrl_handler_free(&cam->ctrl_handler); v4l2_device_unregister(&cam->v4l2_dev); return ret; } -- cgit v1.2.3-59-g8ed1b From 44fbcb10cf35e3ede61b385733ad496d40c5b979 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 5 Mar 2015 13:03:18 -0300 Subject: [media] marvell-ccic: switch to struct v4l2_fh Use struct v4l2_fh to represent a filehandle. This fixes the missing g/s_priority handling of this driver that v4l2-compliance complained about. Signed-off-by: Hans Verkuil Acked-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/marvell-ccic/mcam-core.c | 48 +++++++++++++------------ 1 file changed, 26 insertions(+), 22 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index 51c9c8c69d03..8456017043d4 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -1314,7 +1314,7 @@ static void mcam_cleanup_vb2(struct mcam_camera *cam) static int mcam_vidioc_streamon(struct file *filp, void *priv, enum v4l2_buf_type type) { - struct mcam_camera *cam = filp->private_data; + struct mcam_camera *cam = video_drvdata(filp); int ret; mutex_lock(&cam->s_mutex); @@ -1327,7 +1327,7 @@ static int mcam_vidioc_streamon(struct file *filp, void *priv, static int mcam_vidioc_streamoff(struct file *filp, void *priv, enum v4l2_buf_type type) { - struct mcam_camera *cam = filp->private_data; + struct mcam_camera *cam = video_drvdata(filp); int ret; mutex_lock(&cam->s_mutex); @@ -1340,7 +1340,7 @@ static int mcam_vidioc_streamoff(struct file *filp, void *priv, static int mcam_vidioc_reqbufs(struct file *filp, void *priv, struct v4l2_requestbuffers *req) { - struct mcam_camera *cam = filp->private_data; + struct mcam_camera *cam = video_drvdata(filp); int ret; mutex_lock(&cam->s_mutex); @@ -1353,7 +1353,7 @@ static int mcam_vidioc_reqbufs(struct file *filp, void *priv, static int mcam_vidioc_querybuf(struct file *filp, void *priv, struct v4l2_buffer *buf) { - struct mcam_camera *cam = filp->private_data; + struct mcam_camera *cam = video_drvdata(filp); int ret; mutex_lock(&cam->s_mutex); @@ -1365,7 +1365,7 @@ static int mcam_vidioc_querybuf(struct file *filp, void *priv, static int mcam_vidioc_qbuf(struct file *filp, void *priv, struct v4l2_buffer *buf) { - struct mcam_camera *cam = filp->private_data; + struct mcam_camera *cam = video_drvdata(filp); int ret; mutex_lock(&cam->s_mutex); @@ -1377,7 +1377,7 @@ static int mcam_vidioc_qbuf(struct file *filp, void *priv, static int mcam_vidioc_dqbuf(struct file *filp, void *priv, struct v4l2_buffer *buf) { - struct mcam_camera *cam = filp->private_data; + struct mcam_camera *cam = video_drvdata(filp); int ret; mutex_lock(&cam->s_mutex); @@ -1389,7 +1389,7 @@ static int mcam_vidioc_dqbuf(struct file *filp, void *priv, static int mcam_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - struct mcam_camera *cam = priv; + struct mcam_camera *cam = video_drvdata(file); strcpy(cap->driver, "marvell_ccic"); strcpy(cap->card, "marvell_ccic"); @@ -1415,7 +1415,7 @@ static int mcam_vidioc_enum_fmt_vid_cap(struct file *filp, static int mcam_vidioc_try_fmt_vid_cap(struct file *filp, void *priv, struct v4l2_format *fmt) { - struct mcam_camera *cam = priv; + struct mcam_camera *cam = video_drvdata(filp); struct mcam_format_struct *f; struct v4l2_pix_format *pix = &fmt->fmt.pix; struct v4l2_mbus_framefmt mbus_fmt; @@ -1445,7 +1445,7 @@ static int mcam_vidioc_try_fmt_vid_cap(struct file *filp, void *priv, static int mcam_vidioc_s_fmt_vid_cap(struct file *filp, void *priv, struct v4l2_format *fmt) { - struct mcam_camera *cam = priv; + struct mcam_camera *cam = video_drvdata(filp); struct mcam_format_struct *f; int ret; @@ -1494,7 +1494,7 @@ out: static int mcam_vidioc_g_fmt_vid_cap(struct file *filp, void *priv, struct v4l2_format *f) { - struct mcam_camera *cam = priv; + struct mcam_camera *cam = video_drvdata(filp); f->fmt.pix = cam->pix_format; return 0; @@ -1534,7 +1534,7 @@ static int mcam_vidioc_s_input(struct file *filp, void *priv, unsigned int i) static int mcam_vidioc_g_parm(struct file *filp, void *priv, struct v4l2_streamparm *parms) { - struct mcam_camera *cam = priv; + struct mcam_camera *cam = video_drvdata(filp); int ret; mutex_lock(&cam->s_mutex); @@ -1547,7 +1547,7 @@ static int mcam_vidioc_g_parm(struct file *filp, void *priv, static int mcam_vidioc_s_parm(struct file *filp, void *priv, struct v4l2_streamparm *parms) { - struct mcam_camera *cam = priv; + struct mcam_camera *cam = video_drvdata(filp); int ret; mutex_lock(&cam->s_mutex); @@ -1560,7 +1560,7 @@ static int mcam_vidioc_s_parm(struct file *filp, void *priv, static int mcam_vidioc_enum_framesizes(struct file *filp, void *priv, struct v4l2_frmsizeenum *sizes) { - struct mcam_camera *cam = priv; + struct mcam_camera *cam = video_drvdata(filp); struct mcam_format_struct *f; struct v4l2_subdev_frame_size_enum fse = { .index = sizes->index, @@ -1597,7 +1597,7 @@ static int mcam_vidioc_enum_framesizes(struct file *filp, void *priv, static int mcam_vidioc_enum_frameintervals(struct file *filp, void *priv, struct v4l2_frmivalenum *interval) { - struct mcam_camera *cam = priv; + struct mcam_camera *cam = video_drvdata(filp); struct mcam_format_struct *f; struct v4l2_subdev_frame_interval_enum fie = { .index = interval->index, @@ -1625,7 +1625,7 @@ static int mcam_vidioc_enum_frameintervals(struct file *filp, void *priv, static int mcam_vidioc_g_register(struct file *file, void *priv, struct v4l2_dbg_register *reg) { - struct mcam_camera *cam = priv; + struct mcam_camera *cam = video_drvdata(file); if (reg->reg > cam->regs_size - 4) return -EINVAL; @@ -1637,7 +1637,7 @@ static int mcam_vidioc_g_register(struct file *file, void *priv, static int mcam_vidioc_s_register(struct file *file, void *priv, const struct v4l2_dbg_register *reg) { - struct mcam_camera *cam = priv; + struct mcam_camera *cam = video_drvdata(file); if (reg->reg > cam->regs_size - 4) return -EINVAL; @@ -1678,9 +1678,10 @@ static const struct v4l2_ioctl_ops mcam_v4l_ioctl_ops = { static int mcam_v4l_open(struct file *filp) { struct mcam_camera *cam = video_drvdata(filp); - int ret = 0; + int ret = v4l2_fh_open(filp); - filp->private_data = cam; + if (ret) + return ret; cam->frame_state.frames = 0; cam->frame_state.singles = 0; @@ -1699,13 +1700,15 @@ static int mcam_v4l_open(struct file *filp) (cam->users)++; out: mutex_unlock(&cam->s_mutex); + if (ret) + v4l2_fh_release(filp); return ret; } static int mcam_v4l_release(struct file *filp) { - struct mcam_camera *cam = filp->private_data; + struct mcam_camera *cam = video_drvdata(filp); cam_dbg(cam, "Release, %d frames, %d singles, %d delivered\n", cam->frame_state.frames, cam->frame_state.singles, @@ -1722,13 +1725,14 @@ static int mcam_v4l_release(struct file *filp) } mutex_unlock(&cam->s_mutex); + v4l2_fh_release(filp); return 0; } static ssize_t mcam_v4l_read(struct file *filp, char __user *buffer, size_t len, loff_t *pos) { - struct mcam_camera *cam = filp->private_data; + struct mcam_camera *cam = video_drvdata(filp); int ret; mutex_lock(&cam->s_mutex); @@ -1743,7 +1747,7 @@ static ssize_t mcam_v4l_read(struct file *filp, static unsigned int mcam_v4l_poll(struct file *filp, struct poll_table_struct *pt) { - struct mcam_camera *cam = filp->private_data; + struct mcam_camera *cam = video_drvdata(filp); int ret; mutex_lock(&cam->s_mutex); @@ -1755,7 +1759,7 @@ static unsigned int mcam_v4l_poll(struct file *filp, static int mcam_v4l_mmap(struct file *filp, struct vm_area_struct *vma) { - struct mcam_camera *cam = filp->private_data; + struct mcam_camera *cam = video_drvdata(filp); int ret; mutex_lock(&cam->s_mutex); -- cgit v1.2.3-59-g8ed1b From 87d184300d6c50050b88d2d8a3aaab11eaa0c872 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 5 Mar 2015 13:05:24 -0300 Subject: [media] marvell-ccic: implement control events Now that this driver uses v4l2_fh, it is trivial to add support for control events. Again, this fixes a v4l2-compliance failure. Signed-off-by: Hans Verkuil Acked-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/marvell-ccic/mcam-core.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index 8456017043d4..4d501823ede1 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -1665,6 +1666,8 @@ static const struct v4l2_ioctl_ops mcam_v4l_ioctl_ops = { .vidioc_s_parm = mcam_vidioc_s_parm, .vidioc_enum_framesizes = mcam_vidioc_enum_framesizes, .vidioc_enum_frameintervals = mcam_vidioc_enum_frameintervals, + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, #ifdef CONFIG_VIDEO_ADV_DEBUG .vidioc_g_register = mcam_vidioc_g_register, .vidioc_s_register = mcam_vidioc_s_register, -- cgit v1.2.3-59-g8ed1b From 949bd4081ffe953af98b6ac7ebe0a8d59996fce9 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 5 Mar 2015 17:33:17 -0300 Subject: [media] marvell-ccic: use vb2 helpers and core locking Use the V4L2 core locking system instead of rolling your own. Switch to the vb2 fop and ioctl helpers to get rid of a lot of code. This also made it easy to add VB2_READ to the DMA modes, since you get read() for free with vb2 and these helpers. Finally remove the users field: this information is also available from the core framework, no need to keep track of it in the driver. Signed-off-by: Hans Verkuil Acked-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/marvell-ccic/mcam-core.c | 218 +++++------------------- drivers/media/platform/marvell-ccic/mcam-core.h | 1 - 2 files changed, 43 insertions(+), 176 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index 4d501823ede1..b6b838fd0af8 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -971,7 +971,6 @@ static int mcam_cam_init(struct mcam_camera *cam) { int ret; - mutex_lock(&cam->s_mutex); if (cam->state != S_NOTREADY) cam_warn(cam, "Cam init with device in funky state %d", cam->state); @@ -979,7 +978,6 @@ static int mcam_cam_init(struct mcam_camera *cam) /* Get/set parameters? */ cam->state = S_IDLE; mcam_ctlr_power_down(cam); - mutex_unlock(&cam->s_mutex); return ret; } @@ -1116,6 +1114,9 @@ static int mcam_vb_start_streaming(struct vb2_queue *vq, unsigned int count) INIT_LIST_HEAD(&cam->buffers); return -EINVAL; } + cam->frame_state.frames = 0; + cam->frame_state.singles = 0; + cam->frame_state.delivered = 0; cam->sequence = 0; /* * Videobuf2 sneakily hoards all the buffers and won't @@ -1144,6 +1145,9 @@ static void mcam_vb_stop_streaming(struct vb2_queue *vq) struct mcam_camera *cam = vb2_get_drv_priv(vq); unsigned long flags; + cam_dbg(cam, "stop_streaming: %d frames, %d singles, %d delivered\n", + cam->frame_state.frames, cam->frame_state.singles, + cam->frame_state.delivered); if (cam->state == S_BUFWAIT) { /* They never gave us buffers */ cam->state = S_IDLE; @@ -1256,7 +1260,7 @@ static int mcam_setup_vb2(struct mcam_camera *cam) vq->ops = &mcam_vb2_ops; vq->mem_ops = &vb2_dma_contig_memops; vq->buf_struct_size = sizeof(struct mcam_vb_buffer); - vq->io_modes = VB2_MMAP | VB2_USERPTR; + vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; cam->dma_setup = mcam_ctlr_dma_contig; cam->frame_complete = mcam_dma_contig_done; cam->vb_alloc_ctx = vb2_dma_contig_init_ctx(cam->dev); @@ -1269,7 +1273,7 @@ static int mcam_setup_vb2(struct mcam_camera *cam) vq->ops = &mcam_vb2_sg_ops; vq->mem_ops = &vb2_dma_sg_memops; vq->buf_struct_size = sizeof(struct mcam_vb_buffer); - vq->io_modes = VB2_MMAP | VB2_USERPTR; + vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; cam->dma_setup = mcam_ctlr_dma_sg; cam->frame_complete = mcam_dma_sg_done; cam->vb_alloc_ctx_sg = vb2_dma_sg_init_ctx(cam->dev); @@ -1284,7 +1288,7 @@ static int mcam_setup_vb2(struct mcam_camera *cam) vq->ops = &mcam_vb2_ops; vq->mem_ops = &vb2_vmalloc_memops; vq->buf_struct_size = sizeof(struct mcam_vb_buffer); - vq->io_modes = VB2_MMAP; + vq->io_modes = VB2_MMAP | VB2_READ; cam->dma_setup = mcam_ctlr_dma_vmalloc; cam->frame_complete = mcam_vmalloc_done; #endif @@ -1295,7 +1299,6 @@ static int mcam_setup_vb2(struct mcam_camera *cam) static void mcam_cleanup_vb2(struct mcam_camera *cam) { - vb2_queue_release(&cam->vb_queue); #ifdef MCAM_MODE_DMA_CONTIG if (cam->buffer_mode == B_DMA_contig) vb2_dma_contig_cleanup_ctx(cam->vb_alloc_ctx); @@ -1312,81 +1315,6 @@ static void mcam_cleanup_vb2(struct mcam_camera *cam) * The long list of V4L2 ioctl() operations. */ -static int mcam_vidioc_streamon(struct file *filp, void *priv, - enum v4l2_buf_type type) -{ - struct mcam_camera *cam = video_drvdata(filp); - int ret; - - mutex_lock(&cam->s_mutex); - ret = vb2_streamon(&cam->vb_queue, type); - mutex_unlock(&cam->s_mutex); - return ret; -} - - -static int mcam_vidioc_streamoff(struct file *filp, void *priv, - enum v4l2_buf_type type) -{ - struct mcam_camera *cam = video_drvdata(filp); - int ret; - - mutex_lock(&cam->s_mutex); - ret = vb2_streamoff(&cam->vb_queue, type); - mutex_unlock(&cam->s_mutex); - return ret; -} - - -static int mcam_vidioc_reqbufs(struct file *filp, void *priv, - struct v4l2_requestbuffers *req) -{ - struct mcam_camera *cam = video_drvdata(filp); - int ret; - - mutex_lock(&cam->s_mutex); - ret = vb2_reqbufs(&cam->vb_queue, req); - mutex_unlock(&cam->s_mutex); - return ret; -} - - -static int mcam_vidioc_querybuf(struct file *filp, void *priv, - struct v4l2_buffer *buf) -{ - struct mcam_camera *cam = video_drvdata(filp); - int ret; - - mutex_lock(&cam->s_mutex); - ret = vb2_querybuf(&cam->vb_queue, buf); - mutex_unlock(&cam->s_mutex); - return ret; -} - -static int mcam_vidioc_qbuf(struct file *filp, void *priv, - struct v4l2_buffer *buf) -{ - struct mcam_camera *cam = video_drvdata(filp); - int ret; - - mutex_lock(&cam->s_mutex); - ret = vb2_qbuf(&cam->vb_queue, buf); - mutex_unlock(&cam->s_mutex); - return ret; -} - -static int mcam_vidioc_dqbuf(struct file *filp, void *priv, - struct v4l2_buffer *buf) -{ - struct mcam_camera *cam = video_drvdata(filp); - int ret; - - mutex_lock(&cam->s_mutex); - ret = vb2_dqbuf(&cam->vb_queue, buf, filp->f_flags & O_NONBLOCK); - mutex_unlock(&cam->s_mutex); - return ret; -} - static int mcam_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { @@ -1425,9 +1353,7 @@ static int mcam_vidioc_try_fmt_vid_cap(struct file *filp, void *priv, f = mcam_find_format(pix->pixelformat); pix->pixelformat = f->pixelformat; v4l2_fill_mbus_format(&mbus_fmt, pix, f->mbus_code); - mutex_lock(&cam->s_mutex); ret = sensor_call(cam, video, try_mbus_fmt, &mbus_fmt); - mutex_unlock(&cam->s_mutex); v4l2_fill_pix_format(pix, &mbus_fmt); switch (f->pixelformat) { case V4L2_PIX_FMT_YUV420: @@ -1469,7 +1395,6 @@ static int mcam_vidioc_s_fmt_vid_cap(struct file *filp, void *priv, * Now we start to change things for real, so let's do it * under lock. */ - mutex_lock(&cam->s_mutex); cam->pix_format = fmt->fmt.pix; cam->mbus_code = f->mbus_code; @@ -1483,7 +1408,6 @@ static int mcam_vidioc_s_fmt_vid_cap(struct file *filp, void *priv, } mcam_set_config_needed(cam, 1); out: - mutex_unlock(&cam->s_mutex); return ret; } @@ -1538,9 +1462,7 @@ static int mcam_vidioc_g_parm(struct file *filp, void *priv, struct mcam_camera *cam = video_drvdata(filp); int ret; - mutex_lock(&cam->s_mutex); ret = sensor_call(cam, video, g_parm, parms); - mutex_unlock(&cam->s_mutex); parms->parm.capture.readbuffers = n_dma_bufs; return ret; } @@ -1551,9 +1473,7 @@ static int mcam_vidioc_s_parm(struct file *filp, void *priv, struct mcam_camera *cam = video_drvdata(filp); int ret; - mutex_lock(&cam->s_mutex); ret = sensor_call(cam, video, s_parm, parms); - mutex_unlock(&cam->s_mutex); parms->parm.capture.readbuffers = n_dma_bufs; return ret; } @@ -1573,9 +1493,7 @@ static int mcam_vidioc_enum_framesizes(struct file *filp, void *priv, if (f->pixelformat != sizes->pixel_format) return -EINVAL; fse.code = f->mbus_code; - mutex_lock(&cam->s_mutex); ret = sensor_call(cam, pad, enum_frame_size, NULL, &fse); - mutex_unlock(&cam->s_mutex); if (ret) return ret; if (fse.min_width == fse.max_width && @@ -1612,9 +1530,7 @@ static int mcam_vidioc_enum_frameintervals(struct file *filp, void *priv, if (f->pixelformat != interval->pixel_format) return -EINVAL; fie.code = f->mbus_code; - mutex_lock(&cam->s_mutex); ret = sensor_call(cam, pad, enum_frame_interval, NULL, &fie); - mutex_unlock(&cam->s_mutex); if (ret) return ret; interval->type = V4L2_FRMIVAL_TYPE_DISCRETE; @@ -1656,12 +1572,12 @@ static const struct v4l2_ioctl_ops mcam_v4l_ioctl_ops = { .vidioc_enum_input = mcam_vidioc_enum_input, .vidioc_g_input = mcam_vidioc_g_input, .vidioc_s_input = mcam_vidioc_s_input, - .vidioc_reqbufs = mcam_vidioc_reqbufs, - .vidioc_querybuf = mcam_vidioc_querybuf, - .vidioc_qbuf = mcam_vidioc_qbuf, - .vidioc_dqbuf = mcam_vidioc_dqbuf, - .vidioc_streamon = mcam_vidioc_streamon, - .vidioc_streamoff = mcam_vidioc_streamoff, + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_qbuf = vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, + .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, .vidioc_g_parm = mcam_vidioc_g_parm, .vidioc_s_parm = mcam_vidioc_s_parm, .vidioc_enum_framesizes = mcam_vidioc_enum_framesizes, @@ -1681,26 +1597,19 @@ static const struct v4l2_ioctl_ops mcam_v4l_ioctl_ops = { static int mcam_v4l_open(struct file *filp) { struct mcam_camera *cam = video_drvdata(filp); - int ret = v4l2_fh_open(filp); - - if (ret) - return ret; + int ret; - cam->frame_state.frames = 0; - cam->frame_state.singles = 0; - cam->frame_state.delivered = 0; mutex_lock(&cam->s_mutex); - if (cam->users == 0) { - ret = mcam_setup_vb2(cam); - if (ret) - goto out; + ret = v4l2_fh_open(filp); + if (ret) + goto out; + if (v4l2_fh_is_singular_file(filp)) { ret = mcam_ctlr_power_up(cam); if (ret) goto out; __mcam_cam_reset(cam); mcam_set_config_needed(cam, 1); } - (cam->users)++; out: mutex_unlock(&cam->s_mutex); if (ret) @@ -1712,15 +1621,12 @@ out: static int mcam_v4l_release(struct file *filp) { struct mcam_camera *cam = video_drvdata(filp); + bool last_open; - cam_dbg(cam, "Release, %d frames, %d singles, %d delivered\n", - cam->frame_state.frames, cam->frame_state.singles, - cam->frame_state.delivered); mutex_lock(&cam->s_mutex); - (cam->users)--; - if (cam->users == 0) { - mcam_ctlr_stop_dma(cam); - mcam_cleanup_vb2(cam); + last_open = v4l2_fh_is_singular_file(filp); + _vb2_fop_release(filp, NULL); + if (last_open) { mcam_disable_mipi(cam); mcam_ctlr_power_down(cam); if (cam->buffer_mode == B_vmalloc && alloc_bufs_at_read) @@ -1728,58 +1634,16 @@ static int mcam_v4l_release(struct file *filp) } mutex_unlock(&cam->s_mutex); - v4l2_fh_release(filp); return 0; } -static ssize_t mcam_v4l_read(struct file *filp, - char __user *buffer, size_t len, loff_t *pos) -{ - struct mcam_camera *cam = video_drvdata(filp); - int ret; - - mutex_lock(&cam->s_mutex); - ret = vb2_read(&cam->vb_queue, buffer, len, pos, - filp->f_flags & O_NONBLOCK); - mutex_unlock(&cam->s_mutex); - return ret; -} - - - -static unsigned int mcam_v4l_poll(struct file *filp, - struct poll_table_struct *pt) -{ - struct mcam_camera *cam = video_drvdata(filp); - int ret; - - mutex_lock(&cam->s_mutex); - ret = vb2_poll(&cam->vb_queue, filp, pt); - mutex_unlock(&cam->s_mutex); - return ret; -} - - -static int mcam_v4l_mmap(struct file *filp, struct vm_area_struct *vma) -{ - struct mcam_camera *cam = video_drvdata(filp); - int ret; - - mutex_lock(&cam->s_mutex); - ret = vb2_mmap(&cam->vb_queue, vma); - mutex_unlock(&cam->s_mutex); - return ret; -} - - - static const struct v4l2_file_operations mcam_v4l_fops = { .owner = THIS_MODULE, .open = mcam_v4l_open, .release = mcam_v4l_release, - .read = mcam_v4l_read, - .poll = mcam_v4l_poll, - .mmap = mcam_v4l_mmap, + .read = vb2_fop_read, + .poll = vb2_fop_poll, + .mmap = vb2_fop_mmap, .unlocked_ioctl = video_ioctl2, }; @@ -1790,8 +1654,6 @@ static const struct v4l2_file_operations mcam_v4l_fops = { */ static struct video_device mcam_v4l_template = { .name = "mcam", - .tvnorms = V4L2_STD_NTSC_M, - .fops = &mcam_v4l_fops, .ioctl_ops = &mcam_v4l_ioctl_ops, .release = video_device_release_empty, @@ -1950,13 +1812,21 @@ int mccic_register(struct mcam_camera *cam) if (ret) goto out_unregister; + ret = mcam_setup_vb2(cam); + if (ret) + goto out_unregister; + mutex_lock(&cam->s_mutex); cam->vdev = mcam_v4l_template; cam->vdev.v4l2_dev = &cam->v4l2_dev; + cam->vdev.lock = &cam->s_mutex; + cam->vdev.queue = &cam->vb_queue; video_set_drvdata(&cam->vdev, cam); ret = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1); - if (ret) - goto out; + if (ret) { + mutex_unlock(&cam->s_mutex); + goto out_unregister; + } /* * If so requested, try to get our DMA buffers now. @@ -1967,11 +1837,9 @@ int mccic_register(struct mcam_camera *cam) " will try again later."); } -out: - if (ret) - v4l2_ctrl_handler_free(&cam->ctrl_handler); mutex_unlock(&cam->s_mutex); - return ret; + return 0; + out_unregister: v4l2_ctrl_handler_free(&cam->ctrl_handler); v4l2_device_unregister(&cam->v4l2_dev); @@ -1987,11 +1855,11 @@ void mccic_shutdown(struct mcam_camera *cam) * take it down again will wedge the machine, which is frowned * upon. */ - if (cam->users > 0) { + if (!list_empty(&cam->vdev.fh_list)) { cam_warn(cam, "Removing a device with users!\n"); mcam_ctlr_power_down(cam); } - vb2_queue_release(&cam->vb_queue); + mcam_cleanup_vb2(cam); if (cam->buffer_mode == B_vmalloc) mcam_free_dma_bufs(cam); video_unregister_device(&cam->vdev); @@ -2007,7 +1875,7 @@ void mccic_shutdown(struct mcam_camera *cam) void mccic_suspend(struct mcam_camera *cam) { mutex_lock(&cam->s_mutex); - if (cam->users > 0) { + if (!list_empty(&cam->vdev.fh_list)) { enum mcam_state cstate = cam->state; mcam_ctlr_stop_dma(cam); @@ -2022,7 +1890,7 @@ int mccic_resume(struct mcam_camera *cam) int ret = 0; mutex_lock(&cam->s_mutex); - if (cam->users > 0) { + if (!list_empty(&cam->vdev.fh_list)) { ret = mcam_ctlr_power_up(cam); if (ret) { mutex_unlock(&cam->s_mutex); diff --git a/drivers/media/platform/marvell-ccic/mcam-core.h b/drivers/media/platform/marvell-ccic/mcam-core.h index 46bc7151a200..2847e06c5fc8 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.h +++ b/drivers/media/platform/marvell-ccic/mcam-core.h @@ -146,7 +146,6 @@ struct mcam_camera { struct v4l2_ctrl_handler ctrl_handler; enum mcam_state state; unsigned long flags; /* Buffer status, mainly (dev_lock) */ - int users; /* How many open FDs */ struct mcam_frame_state frame_state; /* Frame state counter */ /* -- cgit v1.2.3-59-g8ed1b From e198d0ff25a7b86ca74a12645e4f55d20be6811e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 5 Mar 2015 17:37:51 -0300 Subject: [media] marvell-ccic: add create_bufs support This fixes the final v4l2-compliance warning. Signed-off-by: Hans Verkuil Acked-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/marvell-ccic/mcam-core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index b6b838fd0af8..51b72917373d 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -1073,7 +1073,9 @@ static int mcam_vb_queue_setup(struct vb2_queue *vq, struct mcam_camera *cam = vb2_get_drv_priv(vq); int minbufs = (cam->buffer_mode == B_DMA_contig) ? 3 : 2; - sizes[0] = cam->pix_format.sizeimage; + if (fmt && fmt->fmt.pix.sizeimage < cam->pix_format.sizeimage) + return -EINVAL; + sizes[0] = fmt ? fmt->fmt.pix.sizeimage : cam->pix_format.sizeimage; *num_planes = 1; /* Someday we have to support planar formats... */ if (*nbufs < minbufs) *nbufs = minbufs; @@ -1380,7 +1382,7 @@ static int mcam_vidioc_s_fmt_vid_cap(struct file *filp, void *priv, * Can't do anything if the device is not idle * Also can't if there are streaming buffers in place. */ - if (cam->state != S_IDLE || cam->vb_queue.num_buffers > 0) + if (cam->state != S_IDLE || vb2_is_busy(&cam->vb_queue)) return -EBUSY; f = mcam_find_format(fmt->fmt.pix.pixelformat); @@ -1573,6 +1575,7 @@ static const struct v4l2_ioctl_ops mcam_v4l_ioctl_ops = { .vidioc_g_input = mcam_vidioc_g_input, .vidioc_s_input = mcam_vidioc_s_input, .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_create_bufs = vb2_ioctl_create_bufs, .vidioc_querybuf = vb2_ioctl_querybuf, .vidioc_qbuf = vb2_ioctl_qbuf, .vidioc_dqbuf = vb2_ioctl_dqbuf, -- cgit v1.2.3-59-g8ed1b From ca16a64bfc7c9898566ebd907078e830e6e2836b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 9 Mar 2015 18:02:23 -0300 Subject: [media] marvell-ccic: add DMABUF support for all three DMA modes Add VB2_DMABUF and VIDIOC_EXPBUF support. Also add VB2_USERPTR support for the vmalloc DMA mode which was missing for no good reason. Signed-off-by: Hans Verkuil Acked-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/marvell-ccic/mcam-core.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index 51b72917373d..a1312a5dd294 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -1255,14 +1255,14 @@ static int mcam_setup_vb2(struct mcam_camera *cam) vq->drv_priv = cam; vq->lock = &cam->s_mutex; vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ; + vq->buf_struct_size = sizeof(struct mcam_vb_buffer); INIT_LIST_HEAD(&cam->buffers); switch (cam->buffer_mode) { case B_DMA_contig: #ifdef MCAM_MODE_DMA_CONTIG vq->ops = &mcam_vb2_ops; vq->mem_ops = &vb2_dma_contig_memops; - vq->buf_struct_size = sizeof(struct mcam_vb_buffer); - vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; cam->dma_setup = mcam_ctlr_dma_contig; cam->frame_complete = mcam_dma_contig_done; cam->vb_alloc_ctx = vb2_dma_contig_init_ctx(cam->dev); @@ -1274,8 +1274,6 @@ static int mcam_setup_vb2(struct mcam_camera *cam) #ifdef MCAM_MODE_DMA_SG vq->ops = &mcam_vb2_sg_ops; vq->mem_ops = &vb2_dma_sg_memops; - vq->buf_struct_size = sizeof(struct mcam_vb_buffer); - vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; cam->dma_setup = mcam_ctlr_dma_sg; cam->frame_complete = mcam_dma_sg_done; cam->vb_alloc_ctx_sg = vb2_dma_sg_init_ctx(cam->dev); @@ -1289,8 +1287,6 @@ static int mcam_setup_vb2(struct mcam_camera *cam) (unsigned long) cam); vq->ops = &mcam_vb2_ops; vq->mem_ops = &vb2_vmalloc_memops; - vq->buf_struct_size = sizeof(struct mcam_vb_buffer); - vq->io_modes = VB2_MMAP | VB2_READ; cam->dma_setup = mcam_ctlr_dma_vmalloc; cam->frame_complete = mcam_vmalloc_done; #endif @@ -1579,6 +1575,7 @@ static const struct v4l2_ioctl_ops mcam_v4l_ioctl_ops = { .vidioc_querybuf = vb2_ioctl_querybuf, .vidioc_qbuf = vb2_ioctl_qbuf, .vidioc_dqbuf = vb2_ioctl_dqbuf, + .vidioc_expbuf = vb2_ioctl_expbuf, .vidioc_streamon = vb2_ioctl_streamon, .vidioc_streamoff = vb2_ioctl_streamoff, .vidioc_g_parm = mcam_vidioc_g_parm, -- cgit v1.2.3-59-g8ed1b From 534234299867abb1db534a10c63cd155c7c6fb8e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 5 Mar 2015 17:48:39 -0300 Subject: [media] marvell-ccic: fix streaming issues - fill in timestamp - fill in field - start the sequence counter at 0, not 1 Signed-off-by: Hans Verkuil Acked-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/marvell-ccic/mcam-core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index a1312a5dd294..6b7b38bd5baf 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -239,6 +239,8 @@ static void mcam_buffer_done(struct mcam_camera *cam, int frame, { vbuf->v4l2_buf.bytesused = cam->pix_format.sizeimage; vbuf->v4l2_buf.sequence = cam->buf_seq[frame]; + vbuf->v4l2_buf.field = V4L2_FIELD_NONE; + v4l2_get_timestamp(&vbuf->v4l2_buf.timestamp); vb2_set_plane_payload(vbuf, 0, cam->pix_format.sizeimage); vb2_buffer_done(vbuf, VB2_BUF_STATE_DONE); } @@ -1671,7 +1673,7 @@ static void mcam_frame_complete(struct mcam_camera *cam, int frame) set_bit(frame, &cam->flags); clear_bit(CF_DMA_ACTIVE, &cam->flags); cam->next_buf = frame; - cam->buf_seq[frame] = ++(cam->sequence); + cam->buf_seq[frame] = cam->sequence++; cam->frame_state.frames++; /* * "This should never happen" -- cgit v1.2.3-59-g8ed1b From ca657b28fd63f0f0971247e12727d286043b1d15 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 5 Mar 2015 18:00:07 -0300 Subject: [media] marvell-ccic: correctly requeue buffers If start_streaming fails or stop_streaming is called, then all queued buffers need to be given back to vb2. This prevents vb2 from calling WARN_ON when it detects that this is not done correctly. Signed-off-by: Hans Verkuil Acked-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/marvell-ccic/mcam-core.c | 39 ++++++++++++++++++++----- 1 file changed, 32 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index 6b7b38bd5baf..0d9469663eec 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -607,6 +607,7 @@ static void mcam_dma_contig_done(struct mcam_camera *cam, int frame) if (!test_bit(CF_SINGLE_BUFFER, &cam->flags)) { cam->frame_state.delivered++; + cam->vb_bufs[frame] = NULL; mcam_buffer_done(cam, frame, &buf->vb_buf); } mcam_set_contig_buffer(cam, frame); @@ -1106,6 +1107,30 @@ static void mcam_vb_buf_queue(struct vb2_buffer *vb) mcam_read_setup(cam); } +static void mcam_vb_requeue_bufs(struct vb2_queue *vq, + enum vb2_buffer_state state) +{ + struct mcam_camera *cam = vb2_get_drv_priv(vq); + struct mcam_vb_buffer *buf, *node; + unsigned long flags; + unsigned i; + + spin_lock_irqsave(&cam->dev_lock, flags); + list_for_each_entry_safe(buf, node, &cam->buffers, queue) { + vb2_buffer_done(&buf->vb_buf, state); + list_del(&buf->queue); + } + for (i = 0; i < MAX_DMA_BUFS; i++) { + buf = cam->vb_bufs[i]; + + if (buf) { + vb2_buffer_done(&buf->vb_buf, state); + cam->vb_bufs[i] = NULL; + } + } + spin_unlock_irqrestore(&cam->dev_lock, flags); +} + /* * These need to be called with the mutex held from vb2 */ @@ -1113,9 +1138,10 @@ static int mcam_vb_start_streaming(struct vb2_queue *vq, unsigned int count) { struct mcam_camera *cam = vb2_get_drv_priv(vq); unsigned int frame; + int ret; if (cam->state != S_IDLE) { - INIT_LIST_HEAD(&cam->buffers); + mcam_vb_requeue_bufs(vq, VB2_BUF_STATE_QUEUED); return -EINVAL; } cam->frame_state.frames = 0; @@ -1141,13 +1167,15 @@ static int mcam_vb_start_streaming(struct vb2_queue *vq, unsigned int count) for (frame = 0; frame < cam->nbufs; frame++) clear_bit(CF_FRAME_SOF0 + frame, &cam->flags); - return mcam_read_setup(cam); + ret = mcam_read_setup(cam); + if (ret) + mcam_vb_requeue_bufs(vq, VB2_BUF_STATE_QUEUED); + return ret; } static void mcam_vb_stop_streaming(struct vb2_queue *vq) { struct mcam_camera *cam = vb2_get_drv_priv(vq); - unsigned long flags; cam_dbg(cam, "stop_streaming: %d frames, %d singles, %d delivered\n", cam->frame_state.frames, cam->frame_state.singles, @@ -1170,9 +1198,7 @@ static void mcam_vb_stop_streaming(struct vb2_queue *vq) * VB2 reclaims the buffers, so we need to forget * about them. */ - spin_lock_irqsave(&cam->dev_lock, flags); - INIT_LIST_HEAD(&cam->buffers); - spin_unlock_irqrestore(&cam->dev_lock, flags); + mcam_vb_requeue_bufs(vq, VB2_BUF_STATE_ERROR); } @@ -1786,7 +1812,6 @@ int mccic_register(struct mcam_camera *cam) mcam_set_config_needed(cam, 1); cam->pix_format = mcam_def_pix_format; cam->mbus_code = mcam_def_mbus_code; - INIT_LIST_HEAD(&cam->buffers); mcam_ctlr_init(cam); /* -- cgit v1.2.3-59-g8ed1b From 6eb40d594b886fbd9d45cffd7a7a1f989d8389b1 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 9 Mar 2015 16:59:59 -0300 Subject: [media] marvell-ccic: add planar support to dma-vmalloc The dma-vmalloc implementation didn't support planar formats, but with a little bit of refactoring that is easy to fix. Signed-off-by: Hans Verkuil Acked-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/marvell-ccic/mcam-core.c | 94 ++++++++++++------------- 1 file changed, 46 insertions(+), 48 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index 0d9469663eec..2495ab662698 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -206,12 +206,6 @@ struct mcam_dma_desc { u32 segment_len; }; -struct yuv_pointer_t { - dma_addr_t y; - dma_addr_t u; - dma_addr_t v; -}; - /* * Our buffer type for working with videobuf2. Note that the vb2 * developers have decreed that struct vb2_buffer must be at the @@ -223,7 +217,6 @@ struct mcam_vb_buffer { struct mcam_dma_desc *dma_desc; /* Descriptor virtual address */ dma_addr_t dma_desc_pa; /* Descriptor physical address */ int dma_desc_nent; /* Number of mapped descriptors */ - struct yuv_pointer_t yuv_p; }; static inline struct mcam_vb_buffer *vb_to_mvb(struct vb2_buffer *vb) @@ -341,6 +334,47 @@ static void mcam_disable_mipi(struct mcam_camera *mcam) mcam->mipi_enabled = false; } +static bool mcam_fmt_is_planar(__u32 pfmt) +{ + struct mcam_format_struct *f; + + f = mcam_find_format(pfmt); + return f->planar; +} + +static void mcam_write_yuv_bases(struct mcam_camera *cam, + unsigned frame, dma_addr_t base) +{ + struct v4l2_pix_format *fmt = &cam->pix_format; + u32 pixel_count = fmt->width * fmt->height; + dma_addr_t y, u = 0, v = 0; + + y = base; + + switch (fmt->pixelformat) { + case V4L2_PIX_FMT_YUV422P: + u = y + pixel_count; + v = u + pixel_count / 2; + break; + case V4L2_PIX_FMT_YUV420: + u = y + pixel_count; + v = u + pixel_count / 4; + break; + case V4L2_PIX_FMT_YVU420: + v = y + pixel_count; + u = v + pixel_count / 4; + break; + default: + break; + } + + mcam_reg_write(cam, REG_Y0BAR + frame * 4, y); + if (mcam_fmt_is_planar(fmt->pixelformat)) { + mcam_reg_write(cam, REG_U0BAR + frame * 4, u); + mcam_reg_write(cam, REG_V0BAR + frame * 4, v); + } +} + /* ------------------------------------------------------------------- */ #ifdef MCAM_MODE_VMALLOC @@ -411,15 +445,14 @@ static void mcam_free_dma_bufs(struct mcam_camera *cam) static void mcam_ctlr_dma_vmalloc(struct mcam_camera *cam) { /* - * Store the first two Y buffers (we aren't supporting - * planar formats for now, so no UV bufs). Then either + * Store the first two YUV buffers. Then either * set the third if it exists, or tell the controller * to just use two. */ - mcam_reg_write(cam, REG_Y0BAR, cam->dma_handles[0]); - mcam_reg_write(cam, REG_Y1BAR, cam->dma_handles[1]); + mcam_write_yuv_bases(cam, 0, cam->dma_handles[0]); + mcam_write_yuv_bases(cam, 1, cam->dma_handles[1]); if (cam->nbufs > 2) { - mcam_reg_write(cam, REG_Y2BAR, cam->dma_handles[2]); + mcam_write_yuv_bases(cam, 2, cam->dma_handles[2]); mcam_reg_clear_bit(cam, REG_CTRL1, C1_TWOBUFS); } else mcam_reg_set_bit(cam, REG_CTRL1, C1_TWOBUFS); @@ -514,14 +547,6 @@ static inline int mcam_check_dma_buffers(struct mcam_camera *cam) * DMA-contiguous code. */ -static bool mcam_fmt_is_planar(__u32 pfmt) -{ - struct mcam_format_struct *f; - - f = mcam_find_format(pfmt); - return f->planar; -} - /* * Set up a contiguous buffer for the given frame. Here also is where * the underrun strategy is set: if there is no buffer available, reuse @@ -533,9 +558,7 @@ static bool mcam_fmt_is_planar(__u32 pfmt) static void mcam_set_contig_buffer(struct mcam_camera *cam, int frame) { struct mcam_vb_buffer *buf; - struct v4l2_pix_format *fmt = &cam->pix_format; dma_addr_t dma_handle; - u32 pixel_count = fmt->width * fmt->height; struct vb2_buffer *vb; /* @@ -559,32 +582,7 @@ static void mcam_set_contig_buffer(struct mcam_camera *cam, int frame) vb = &buf->vb_buf; dma_handle = vb2_dma_contig_plane_dma_addr(vb, 0); - buf->yuv_p.y = dma_handle; - - switch (cam->pix_format.pixelformat) { - case V4L2_PIX_FMT_YUV422P: - buf->yuv_p.u = buf->yuv_p.y + pixel_count; - buf->yuv_p.v = buf->yuv_p.u + pixel_count / 2; - break; - case V4L2_PIX_FMT_YUV420: - buf->yuv_p.u = buf->yuv_p.y + pixel_count; - buf->yuv_p.v = buf->yuv_p.u + pixel_count / 4; - break; - case V4L2_PIX_FMT_YVU420: - buf->yuv_p.v = buf->yuv_p.y + pixel_count; - buf->yuv_p.u = buf->yuv_p.v + pixel_count / 4; - break; - default: - break; - } - - mcam_reg_write(cam, frame == 0 ? REG_Y0BAR : REG_Y1BAR, buf->yuv_p.y); - if (mcam_fmt_is_planar(fmt->pixelformat)) { - mcam_reg_write(cam, frame == 0 ? - REG_U0BAR : REG_U1BAR, buf->yuv_p.u); - mcam_reg_write(cam, frame == 0 ? - REG_V0BAR : REG_V1BAR, buf->yuv_p.v); - } + mcam_write_yuv_bases(cam, frame, dma_handle); } /* -- cgit v1.2.3-59-g8ed1b From 989b784750278c0b3514d1da9227ec8b42838693 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 9 Mar 2015 17:02:41 -0300 Subject: [media] marvell-ccic: drop V4L2_PIX_FMT_JPEG dead code This driver appeared to support the JPEG format when in reality that was just dead code. Remove it. Signed-off-by: Hans Verkuil Acked-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/marvell-ccic/mcam-core.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index 2495ab662698..1a326102791f 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -755,11 +755,6 @@ static void mcam_ctlr_image(struct mcam_camera *cam) widthy = fmt->width * 2; widthuv = 0; break; - case V4L2_PIX_FMT_JPEG: - imgsz_h = (fmt->sizeimage / fmt->bytesperline) << IMGSZ_V_SHIFT; - widthy = fmt->bytesperline; - widthuv = 0; - break; case V4L2_PIX_FMT_YUV422P: case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YVU420: @@ -797,10 +792,6 @@ static void mcam_ctlr_image(struct mcam_camera *cam) mcam_reg_write_mask(cam, REG_CTRL0, C0_DF_YUV | C0_YUV_PACKED | C0_YUVE_YUYV, C0_DF_MASK); break; - case V4L2_PIX_FMT_JPEG: - mcam_reg_write_mask(cam, REG_CTRL0, - C0_DF_YUV | C0_YUV_PACKED | C0_YUVE_YUYV, C0_DF_MASK); - break; case V4L2_PIX_FMT_RGB444: mcam_reg_write_mask(cam, REG_CTRL0, C0_DF_RGB | C0_RGBF_444 | C0_RGB4_XRGB, C0_DF_MASK); -- cgit v1.2.3-59-g8ed1b From 75eb984714cf5fb779c9827a0f696a31cbbced6d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 9 Mar 2015 17:04:12 -0300 Subject: [media] ov7670: use colorspace SRGB instead of JPEG Even though the format is Y'CbCr, the colorspace used by the sensor is almost certainly SRGB. The sensor is also not generating JPEG data, so it makes no sense to use V4L2_COLORSPACE_JPEG here. Signed-off-by: Hans Verkuil Acked-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov7670.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c index d16bd81e669d..394f416b3543 100644 --- a/drivers/media/i2c/ov7670.c +++ b/drivers/media/i2c/ov7670.c @@ -639,7 +639,7 @@ static struct ov7670_format_struct { } ov7670_formats[] = { { .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, - .colorspace = V4L2_COLORSPACE_JPEG, + .colorspace = V4L2_COLORSPACE_SRGB, .regs = ov7670_fmt_yuv422, .cmatrix = { 128, -128, 0, -34, -94, 128 }, }, -- cgit v1.2.3-59-g8ed1b From 47ba7dbab6338a9f3f4df23ec6e26cc2e0937144 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 9 Mar 2015 17:14:36 -0300 Subject: [media] marvell-ccic: fix the bytesperline and sizeimage calculations These were calculated incorrectly for the planar formats. Signed-off-by: Hans Verkuil Acked-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/marvell-ccic/mcam-core.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index 1a326102791f..9343051c984f 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -127,21 +127,21 @@ static struct mcam_format_struct { .desc = "YUV 4:2:2 PLANAR", .pixelformat = V4L2_PIX_FMT_YUV422P, .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, - .bpp = 2, + .bpp = 1, .planar = true, }, { .desc = "YUV 4:2:0 PLANAR", .pixelformat = V4L2_PIX_FMT_YUV420, .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, - .bpp = 2, + .bpp = 1, .planar = true, }, { .desc = "YVU 4:2:0 PLANAR", .pixelformat = V4L2_PIX_FMT_YVU420, .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, - .bpp = 2, + .bpp = 1, .planar = true, }, { @@ -764,6 +764,7 @@ static void mcam_ctlr_image(struct mcam_camera *cam) default: widthy = fmt->bytesperline; widthuv = 0; + break; } mcam_reg_write_mask(cam, REG_IMGPITCH, widthuv << 16 | widthy, @@ -1370,16 +1371,19 @@ static int mcam_vidioc_try_fmt_vid_cap(struct file *filp, void *priv, v4l2_fill_mbus_format(&mbus_fmt, pix, f->mbus_code); ret = sensor_call(cam, video, try_mbus_fmt, &mbus_fmt); v4l2_fill_pix_format(pix, &mbus_fmt); + pix->bytesperline = pix->width * f->bpp; switch (f->pixelformat) { + case V4L2_PIX_FMT_YUV422P: + pix->sizeimage = pix->height * pix->bytesperline * 2; + break; case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YVU420: - pix->bytesperline = pix->width * 3 / 2; + pix->sizeimage = pix->height * pix->bytesperline * 3 / 2; break; default: - pix->bytesperline = pix->width * f->bpp; + pix->sizeimage = pix->height * pix->bytesperline; break; } - pix->sizeimage = pix->height * pix->bytesperline; pix->colorspace = V4L2_COLORSPACE_SRGB; return ret; } -- cgit v1.2.3-59-g8ed1b From 85ad0a3f68f0ae223293282aecc87fb233a2dda5 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 10 Mar 2015 14:30:50 -0300 Subject: [media] marvell-ccic: drop support for PIX_FMT_422P I cannot get this format to work, the colors keep coming out wrong. Since this has never worked I just drop support for this. Signed-off-by: Hans Verkuil Acked-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/marvell-ccic/mcam-core.c | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index 9343051c984f..7af4265e689e 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -123,13 +123,6 @@ static struct mcam_format_struct { .bpp = 2, .planar = false, }, - { - .desc = "YUV 4:2:2 PLANAR", - .pixelformat = V4L2_PIX_FMT_YUV422P, - .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, - .bpp = 1, - .planar = true, - }, { .desc = "YUV 4:2:0 PLANAR", .pixelformat = V4L2_PIX_FMT_YUV420, @@ -352,10 +345,6 @@ static void mcam_write_yuv_bases(struct mcam_camera *cam, y = base; switch (fmt->pixelformat) { - case V4L2_PIX_FMT_YUV422P: - u = y + pixel_count; - v = u + pixel_count / 2; - break; case V4L2_PIX_FMT_YUV420: u = y + pixel_count; v = u + pixel_count / 4; @@ -755,7 +744,6 @@ static void mcam_ctlr_image(struct mcam_camera *cam) widthy = fmt->width * 2; widthuv = 0; break; - case V4L2_PIX_FMT_YUV422P: case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YVU420: widthy = fmt->width; @@ -776,10 +764,6 @@ static void mcam_ctlr_image(struct mcam_camera *cam) * Tell the controller about the image format we are using. */ switch (fmt->pixelformat) { - case V4L2_PIX_FMT_YUV422P: - mcam_reg_write_mask(cam, REG_CTRL0, - C0_DF_YUV | C0_YUV_PLANAR | C0_YUVE_YVYU, C0_DF_MASK); - break; case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YVU420: mcam_reg_write_mask(cam, REG_CTRL0, @@ -1373,9 +1357,6 @@ static int mcam_vidioc_try_fmt_vid_cap(struct file *filp, void *priv, v4l2_fill_pix_format(pix, &mbus_fmt); pix->bytesperline = pix->width * f->bpp; switch (f->pixelformat) { - case V4L2_PIX_FMT_YUV422P: - pix->sizeimage = pix->height * pix->bytesperline * 2; - break; case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YVU420: pix->sizeimage = pix->height * pix->bytesperline * 3 / 2; -- cgit v1.2.3-59-g8ed1b From 8380b7e449d800037330011c4e0ab5caeab91a6b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 14 Mar 2015 08:47:01 -0300 Subject: [media] marvell-ccic: fix V4L2_PIX_FMT_SBGGR8 support The REG_CTRL0 register was never written if this format was selected, instead an error was logged and whatever was last set in that register was used. Surprisingly, that seems to work if YUYV was selected, but we should program this register explicitly. Signed-off-by: Hans Verkuil Acked-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/marvell-ccic/mcam-core.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index 7af4265e689e..42f63974592c 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -786,6 +786,10 @@ static void mcam_ctlr_image(struct mcam_camera *cam) mcam_reg_write_mask(cam, REG_CTRL0, C0_DF_RGB | C0_RGBF_565 | C0_RGB5_BGGR, C0_DF_MASK); break; + case V4L2_PIX_FMT_SBGGR8: + mcam_reg_write_mask(cam, REG_CTRL0, + C0_DF_RGB | C0_RGB5_GRBG, C0_DF_MASK); + break; default: cam_err(cam, "camera: unknown format: %#x\n", fmt->pixelformat); break; -- cgit v1.2.3-59-g8ed1b From 90ca75fd1945d9e51e21cbde0aae1aad68730dc5 Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Fri, 3 Apr 2015 21:16:01 -0300 Subject: [media] marvell-ccic: fix memory leak on failure path in cafe_smbus_setup() If i2c_add_adapter() fails, adap is not deallocated. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov Acked-by: Jonathan Corbet Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/marvell-ccic/cafe-driver.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/marvell-ccic/cafe-driver.c b/drivers/media/platform/marvell-ccic/cafe-driver.c index e857405b46fd..77890bd0deab 100644 --- a/drivers/media/platform/marvell-ccic/cafe-driver.c +++ b/drivers/media/platform/marvell-ccic/cafe-driver.c @@ -339,17 +339,21 @@ static int cafe_smbus_setup(struct cafe_camera *cam) adap = kzalloc(sizeof(*adap), GFP_KERNEL); if (adap == NULL) return -ENOMEM; - cam->mcam.i2c_adapter = adap; - cafe_smbus_enable_irq(cam); adap->owner = THIS_MODULE; adap->algo = &cafe_smbus_algo; strcpy(adap->name, "cafe_ccic"); adap->dev.parent = &cam->pdev->dev; i2c_set_adapdata(adap, cam); ret = i2c_add_adapter(adap); - if (ret) + if (ret) { printk(KERN_ERR "Unable to register cafe i2c adapter\n"); - return ret; + kfree(adap); + return ret; + } + + cam->mcam.i2c_adapter = adap; + cafe_smbus_enable_irq(cam); + return 0; } static void cafe_smbus_shutdown(struct cafe_camera *cam) -- cgit v1.2.3-59-g8ed1b From cc11b140c3f1ad80a9a7c5422748c041cb5fddfb Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 25 Apr 2015 12:36:18 -0300 Subject: [media] dt3155: move out of staging into drivers/media/pci The dt3155 code is now in good shape, so move it out of staging into drivers/media/pci. Mark in MAINTAINERS that I'll do Odd Fixes for this driver. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 8 + drivers/media/pci/Kconfig | 1 + drivers/media/pci/Makefile | 1 + drivers/media/pci/dt3155/Kconfig | 13 + drivers/media/pci/dt3155/Makefile | 1 + drivers/media/pci/dt3155/dt3155.c | 626 ++++++++++++++++++++++++++++ drivers/media/pci/dt3155/dt3155.h | 196 +++++++++ drivers/staging/media/Kconfig | 2 - drivers/staging/media/Makefile | 1 - drivers/staging/media/dt3155v4l/Kconfig | 13 - drivers/staging/media/dt3155v4l/Makefile | 1 - drivers/staging/media/dt3155v4l/dt3155v4l.c | 626 ---------------------------- drivers/staging/media/dt3155v4l/dt3155v4l.h | 196 --------- 13 files changed, 846 insertions(+), 839 deletions(-) create mode 100644 drivers/media/pci/dt3155/Kconfig create mode 100644 drivers/media/pci/dt3155/Makefile create mode 100644 drivers/media/pci/dt3155/dt3155.c create mode 100644 drivers/media/pci/dt3155/dt3155.h delete mode 100644 drivers/staging/media/dt3155v4l/Kconfig delete mode 100644 drivers/staging/media/dt3155v4l/Makefile delete mode 100644 drivers/staging/media/dt3155v4l/dt3155v4l.c delete mode 100644 drivers/staging/media/dt3155v4l/dt3155v4l.h (limited to 'drivers/media') diff --git a/MAINTAINERS b/MAINTAINERS index 2e5bbc0d68b2..ef403f5d5127 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3426,6 +3426,14 @@ L: netdev@vger.kernel.org S: Maintained F: drivers/net/wan/dscc4.c +DT3155 MEDIA DRIVER +M: Hans Verkuil +L: linux-media@vger.kernel.org +T: git git://linuxtv.org/media_tree.git +W: http://linuxtv.org +S: Odd Fixes +F: drivers/media/pci/dt3155/ + DVB_USB_AF9015 MEDIA DRIVER M: Antti Palosaari L: linux-media@vger.kernel.org diff --git a/drivers/media/pci/Kconfig b/drivers/media/pci/Kconfig index 218144a99016..fd359fb15e69 100644 --- a/drivers/media/pci/Kconfig +++ b/drivers/media/pci/Kconfig @@ -21,6 +21,7 @@ source "drivers/media/pci/zoran/Kconfig" source "drivers/media/pci/saa7146/Kconfig" source "drivers/media/pci/solo6x10/Kconfig" source "drivers/media/pci/tw68/Kconfig" +source "drivers/media/pci/dt3155/Kconfig" endif if MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT diff --git a/drivers/media/pci/Makefile b/drivers/media/pci/Makefile index 0baf0d2967ee..3471ab6b9f22 100644 --- a/drivers/media/pci/Makefile +++ b/drivers/media/pci/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_VIDEO_BT848) += bt8xx/ obj-$(CONFIG_VIDEO_SAA7134) += saa7134/ obj-$(CONFIG_VIDEO_SAA7164) += saa7164/ obj-$(CONFIG_VIDEO_TW68) += tw68/ +obj-$(CONFIG_VIDEO_DT3155) += dt3155/ obj-$(CONFIG_VIDEO_MEYE) += meye/ obj-$(CONFIG_STA2X11_VIP) += sta2x11/ obj-$(CONFIG_VIDEO_SOLO6X10) += solo6x10/ diff --git a/drivers/media/pci/dt3155/Kconfig b/drivers/media/pci/dt3155/Kconfig new file mode 100644 index 000000000000..5145e0dfa2aa --- /dev/null +++ b/drivers/media/pci/dt3155/Kconfig @@ -0,0 +1,13 @@ +config VIDEO_DT3155 + tristate "DT3155 frame grabber" + depends on PCI && VIDEO_DEV && VIDEO_V4L2 + depends on HAS_DMA + select VIDEOBUF2_DMA_CONTIG + default n + ---help--- + Enables dt3155 device driver for the DataTranslation DT3155 frame grabber. + Say Y here if you have this hardware. + In doubt, say N. + + To compile this driver as a module, choose M here: the + module will be called dt3155. diff --git a/drivers/media/pci/dt3155/Makefile b/drivers/media/pci/dt3155/Makefile new file mode 100644 index 000000000000..89fa637ec54c --- /dev/null +++ b/drivers/media/pci/dt3155/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_VIDEO_DT3155) += dt3155.o diff --git a/drivers/media/pci/dt3155/dt3155.c b/drivers/media/pci/dt3155/dt3155.c new file mode 100644 index 000000000000..3131c2ee3b85 --- /dev/null +++ b/drivers/media/pci/dt3155/dt3155.c @@ -0,0 +1,626 @@ +/*************************************************************************** + * Copyright (C) 2006-2010 by Marin Mitov * + * mitov@issp.bas.bg * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dt3155.h" + +#define DT3155_DEVICE_ID 0x1223 + +/** + * read_i2c_reg - reads an internal i2c register + * + * @addr: dt3155 mmio base address + * @index: index (internal address) of register to read + * @data: pointer to byte the read data will be placed in + * + * returns: zero on success or error code + * + * This function starts reading the specified (by index) register + * and busy waits for the process to finish. The result is placed + * in a byte pointed by data. + */ +static int read_i2c_reg(void __iomem *addr, u8 index, u8 *data) +{ + u32 tmp = index; + + iowrite32((tmp << 17) | IIC_READ, addr + IIC_CSR2); + mmiowb(); + udelay(45); /* wait at least 43 usec for NEW_CYCLE to clear */ + if (ioread32(addr + IIC_CSR2) & NEW_CYCLE) + return -EIO; /* error: NEW_CYCLE not cleared */ + tmp = ioread32(addr + IIC_CSR1); + if (tmp & DIRECT_ABORT) { + /* reset DIRECT_ABORT bit */ + iowrite32(DIRECT_ABORT, addr + IIC_CSR1); + return -EIO; /* error: DIRECT_ABORT set */ + } + *data = tmp >> 24; + return 0; +} + +/** + * write_i2c_reg - writes to an internal i2c register + * + * @addr: dt3155 mmio base address + * @index: index (internal address) of register to read + * @data: data to be written + * + * returns: zero on success or error code + * + * This function starts writing the specified (by index) register + * and busy waits for the process to finish. + */ +static int write_i2c_reg(void __iomem *addr, u8 index, u8 data) +{ + u32 tmp = index; + + iowrite32((tmp << 17) | IIC_WRITE | data, addr + IIC_CSR2); + mmiowb(); + udelay(65); /* wait at least 63 usec for NEW_CYCLE to clear */ + if (ioread32(addr + IIC_CSR2) & NEW_CYCLE) + return -EIO; /* error: NEW_CYCLE not cleared */ + if (ioread32(addr + IIC_CSR1) & DIRECT_ABORT) { + /* reset DIRECT_ABORT bit */ + iowrite32(DIRECT_ABORT, addr + IIC_CSR1); + return -EIO; /* error: DIRECT_ABORT set */ + } + return 0; +} + +/** + * write_i2c_reg_nowait - writes to an internal i2c register + * + * @addr: dt3155 mmio base address + * @index: index (internal address) of register to read + * @data: data to be written + * + * This function starts writing the specified (by index) register + * and then returns. + */ +static void write_i2c_reg_nowait(void __iomem *addr, u8 index, u8 data) +{ + u32 tmp = index; + + iowrite32((tmp << 17) | IIC_WRITE | data, addr + IIC_CSR2); + mmiowb(); +} + +/** + * wait_i2c_reg - waits the read/write to finish + * + * @addr: dt3155 mmio base address + * + * returns: zero on success or error code + * + * This function waits reading/writing to finish. + */ +static int wait_i2c_reg(void __iomem *addr) +{ + if (ioread32(addr + IIC_CSR2) & NEW_CYCLE) + udelay(65); /* wait at least 63 usec for NEW_CYCLE to clear */ + if (ioread32(addr + IIC_CSR2) & NEW_CYCLE) + return -EIO; /* error: NEW_CYCLE not cleared */ + if (ioread32(addr + IIC_CSR1) & DIRECT_ABORT) { + /* reset DIRECT_ABORT bit */ + iowrite32(DIRECT_ABORT, addr + IIC_CSR1); + return -EIO; /* error: DIRECT_ABORT set */ + } + return 0; +} + +static int +dt3155_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, + unsigned int *nbuffers, unsigned int *num_planes, + unsigned int sizes[], void *alloc_ctxs[]) + +{ + struct dt3155_priv *pd = vb2_get_drv_priv(vq); + unsigned size = pd->width * pd->height; + + if (vq->num_buffers + *nbuffers < 2) + *nbuffers = 2 - vq->num_buffers; + if (fmt && fmt->fmt.pix.sizeimage < size) + return -EINVAL; + *num_planes = 1; + sizes[0] = fmt ? fmt->fmt.pix.sizeimage : size; + alloc_ctxs[0] = pd->alloc_ctx; + return 0; +} + +static int dt3155_buf_prepare(struct vb2_buffer *vb) +{ + struct dt3155_priv *pd = vb2_get_drv_priv(vb->vb2_queue); + + vb2_set_plane_payload(vb, 0, pd->width * pd->height); + return 0; +} + +static int dt3155_start_streaming(struct vb2_queue *q, unsigned count) +{ + struct dt3155_priv *pd = vb2_get_drv_priv(q); + struct vb2_buffer *vb = pd->curr_buf; + dma_addr_t dma_addr; + + pd->sequence = 0; + dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0); + iowrite32(dma_addr, pd->regs + EVEN_DMA_START); + iowrite32(dma_addr + pd->width, pd->regs + ODD_DMA_START); + iowrite32(pd->width, pd->regs + EVEN_DMA_STRIDE); + iowrite32(pd->width, pd->regs + ODD_DMA_STRIDE); + /* enable interrupts, clear all irq flags */ + iowrite32(FLD_START_EN | FLD_END_ODD_EN | FLD_START | + FLD_END_EVEN | FLD_END_ODD, pd->regs + INT_CSR); + iowrite32(FIFO_EN | SRST | FLD_CRPT_ODD | FLD_CRPT_EVEN | + FLD_DN_ODD | FLD_DN_EVEN | CAP_CONT_EVEN | CAP_CONT_ODD, + pd->regs + CSR1); + wait_i2c_reg(pd->regs); + write_i2c_reg(pd->regs, CONFIG, pd->config); + write_i2c_reg(pd->regs, EVEN_CSR, CSR_ERROR | CSR_DONE); + write_i2c_reg(pd->regs, ODD_CSR, CSR_ERROR | CSR_DONE); + + /* start the board */ + write_i2c_reg(pd->regs, CSR2, pd->csr2 | BUSY_EVEN | BUSY_ODD); + return 0; +} + +static void dt3155_stop_streaming(struct vb2_queue *q) +{ + struct dt3155_priv *pd = vb2_get_drv_priv(q); + struct vb2_buffer *vb; + + spin_lock_irq(&pd->lock); + /* stop the board */ + write_i2c_reg_nowait(pd->regs, CSR2, pd->csr2); + iowrite32(FIFO_EN | SRST | FLD_CRPT_ODD | FLD_CRPT_EVEN | + FLD_DN_ODD | FLD_DN_EVEN, pd->regs + CSR1); + /* disable interrupts, clear all irq flags */ + iowrite32(FLD_START | FLD_END_EVEN | FLD_END_ODD, pd->regs + INT_CSR); + spin_unlock_irq(&pd->lock); + + /* + * It is not clear whether the DMA stops at once or whether it + * will finish the current frame or field first. To be on the + * safe side we wait a bit. + */ + msleep(45); + + spin_lock_irq(&pd->lock); + if (pd->curr_buf) { + vb2_buffer_done(pd->curr_buf, VB2_BUF_STATE_ERROR); + pd->curr_buf = NULL; + } + + while (!list_empty(&pd->dmaq)) { + vb = list_first_entry(&pd->dmaq, typeof(*vb), done_entry); + list_del(&vb->done_entry); + vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); + } + spin_unlock_irq(&pd->lock); +} + +static void dt3155_buf_queue(struct vb2_buffer *vb) +{ + struct dt3155_priv *pd = vb2_get_drv_priv(vb->vb2_queue); + + /* pd->vidq.streaming = 1 when dt3155_buf_queue() is invoked */ + spin_lock_irq(&pd->lock); + if (pd->curr_buf) + list_add_tail(&vb->done_entry, &pd->dmaq); + else + pd->curr_buf = vb; + spin_unlock_irq(&pd->lock); +} + +static const struct vb2_ops q_ops = { + .queue_setup = dt3155_queue_setup, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, + .buf_prepare = dt3155_buf_prepare, + .start_streaming = dt3155_start_streaming, + .stop_streaming = dt3155_stop_streaming, + .buf_queue = dt3155_buf_queue, +}; + +static irqreturn_t dt3155_irq_handler_even(int irq, void *dev_id) +{ + struct dt3155_priv *ipd = dev_id; + struct vb2_buffer *ivb; + dma_addr_t dma_addr; + u32 tmp; + + tmp = ioread32(ipd->regs + INT_CSR) & (FLD_START | FLD_END_ODD); + if (!tmp) + return IRQ_NONE; /* not our irq */ + if ((tmp & FLD_START) && !(tmp & FLD_END_ODD)) { + iowrite32(FLD_START_EN | FLD_END_ODD_EN | FLD_START, + ipd->regs + INT_CSR); + return IRQ_HANDLED; /* start of field irq */ + } + tmp = ioread32(ipd->regs + CSR1) & (FLD_CRPT_EVEN | FLD_CRPT_ODD); + if (tmp) { + iowrite32(FIFO_EN | SRST | FLD_CRPT_ODD | FLD_CRPT_EVEN | + FLD_DN_ODD | FLD_DN_EVEN | + CAP_CONT_EVEN | CAP_CONT_ODD, + ipd->regs + CSR1); + mmiowb(); + } + + spin_lock(&ipd->lock); + if (ipd->curr_buf && !list_empty(&ipd->dmaq)) { + v4l2_get_timestamp(&ipd->curr_buf->v4l2_buf.timestamp); + ipd->curr_buf->v4l2_buf.sequence = ipd->sequence++; + ipd->curr_buf->v4l2_buf.field = V4L2_FIELD_NONE; + vb2_buffer_done(ipd->curr_buf, VB2_BUF_STATE_DONE); + + ivb = list_first_entry(&ipd->dmaq, typeof(*ivb), done_entry); + list_del(&ivb->done_entry); + ipd->curr_buf = ivb; + dma_addr = vb2_dma_contig_plane_dma_addr(ivb, 0); + iowrite32(dma_addr, ipd->regs + EVEN_DMA_START); + iowrite32(dma_addr + ipd->width, ipd->regs + ODD_DMA_START); + iowrite32(ipd->width, ipd->regs + EVEN_DMA_STRIDE); + iowrite32(ipd->width, ipd->regs + ODD_DMA_STRIDE); + mmiowb(); + } + + /* enable interrupts, clear all irq flags */ + iowrite32(FLD_START_EN | FLD_END_ODD_EN | FLD_START | + FLD_END_EVEN | FLD_END_ODD, ipd->regs + INT_CSR); + spin_unlock(&ipd->lock); + return IRQ_HANDLED; +} + +static const struct v4l2_file_operations dt3155_fops = { + .owner = THIS_MODULE, + .open = v4l2_fh_open, + .release = vb2_fop_release, + .unlocked_ioctl = video_ioctl2, + .read = vb2_fop_read, + .mmap = vb2_fop_mmap, + .poll = vb2_fop_poll +}; + +static int dt3155_querycap(struct file *filp, void *p, struct v4l2_capability *cap) +{ + struct dt3155_priv *pd = video_drvdata(filp); + + strcpy(cap->driver, DT3155_NAME); + strcpy(cap->card, DT3155_NAME " frame grabber"); + sprintf(cap->bus_info, "PCI:%s", pci_name(pd->pdev)); + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_STREAMING | V4L2_CAP_READWRITE; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; + return 0; +} + +static int dt3155_enum_fmt_vid_cap(struct file *filp, void *p, struct v4l2_fmtdesc *f) +{ + if (f->index) + return -EINVAL; + f->pixelformat = V4L2_PIX_FMT_GREY; + strcpy(f->description, "8-bit Greyscale"); + return 0; +} + +static int dt3155_fmt_vid_cap(struct file *filp, void *p, struct v4l2_format *f) +{ + struct dt3155_priv *pd = video_drvdata(filp); + + f->fmt.pix.width = pd->width; + f->fmt.pix.height = pd->height; + f->fmt.pix.pixelformat = V4L2_PIX_FMT_GREY; + f->fmt.pix.field = V4L2_FIELD_NONE; + f->fmt.pix.bytesperline = f->fmt.pix.width; + f->fmt.pix.sizeimage = f->fmt.pix.width * f->fmt.pix.height; + f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + return 0; +} + +static int dt3155_g_std(struct file *filp, void *p, v4l2_std_id *norm) +{ + struct dt3155_priv *pd = video_drvdata(filp); + + *norm = pd->std; + return 0; +} + +static int dt3155_s_std(struct file *filp, void *p, v4l2_std_id norm) +{ + struct dt3155_priv *pd = video_drvdata(filp); + + if (pd->std == norm) + return 0; + if (vb2_is_busy(&pd->vidq)) + return -EBUSY; + pd->std = norm; + if (pd->std & V4L2_STD_525_60) { + pd->csr2 = VT_60HZ; + pd->width = 640; + pd->height = 480; + } else { + pd->csr2 = VT_50HZ; + pd->width = 768; + pd->height = 576; + } + return 0; +} + +static int dt3155_enum_input(struct file *filp, void *p, struct v4l2_input *input) +{ + if (input->index > 3) + return -EINVAL; + if (input->index) + snprintf(input->name, sizeof(input->name), "VID%d", input->index); + else + strlcpy(input->name, "J2/VID0", sizeof(input->name)); + input->type = V4L2_INPUT_TYPE_CAMERA; + input->std = V4L2_STD_ALL; + input->status = 0; + return 0; +} + +static int dt3155_g_input(struct file *filp, void *p, unsigned int *i) +{ + struct dt3155_priv *pd = video_drvdata(filp); + + *i = pd->input; + return 0; +} + +static int dt3155_s_input(struct file *filp, void *p, unsigned int i) +{ + struct dt3155_priv *pd = video_drvdata(filp); + + if (i > 3) + return -EINVAL; + pd->input = i; + write_i2c_reg(pd->regs, AD_ADDR, AD_CMD_REG); + write_i2c_reg(pd->regs, AD_CMD, (i << 6) | (i << 4) | SYNC_LVL_3); + return 0; +} + +static const struct v4l2_ioctl_ops dt3155_ioctl_ops = { + .vidioc_querycap = dt3155_querycap, + .vidioc_enum_fmt_vid_cap = dt3155_enum_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = dt3155_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = dt3155_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = dt3155_fmt_vid_cap, + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_create_bufs = vb2_ioctl_create_bufs, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_expbuf = vb2_ioctl_expbuf, + .vidioc_qbuf = vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, + .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, + .vidioc_g_std = dt3155_g_std, + .vidioc_s_std = dt3155_s_std, + .vidioc_enum_input = dt3155_enum_input, + .vidioc_g_input = dt3155_g_input, + .vidioc_s_input = dt3155_s_input, +}; + +static int dt3155_init_board(struct dt3155_priv *pd) +{ + struct pci_dev *pdev = pd->pdev; + int i; + u8 tmp = 0; + + pci_set_master(pdev); /* dt3155 needs it */ + + /* resetting the adapter */ + iowrite32(ADDR_ERR_ODD | ADDR_ERR_EVEN | FLD_CRPT_ODD | FLD_CRPT_EVEN | + FLD_DN_ODD | FLD_DN_EVEN, pd->regs + CSR1); + mmiowb(); + msleep(20); + + /* initializing adapter registers */ + iowrite32(FIFO_EN | SRST, pd->regs + CSR1); + mmiowb(); + iowrite32(0xEEEEEE01, pd->regs + EVEN_PIXEL_FMT); + iowrite32(0xEEEEEE01, pd->regs + ODD_PIXEL_FMT); + iowrite32(0x00000020, pd->regs + FIFO_TRIGER); + iowrite32(0x00000103, pd->regs + XFER_MODE); + iowrite32(0, pd->regs + RETRY_WAIT_CNT); + iowrite32(0, pd->regs + INT_CSR); + iowrite32(1, pd->regs + EVEN_FLD_MASK); + iowrite32(1, pd->regs + ODD_FLD_MASK); + iowrite32(0, pd->regs + MASK_LENGTH); + iowrite32(0x0005007C, pd->regs + FIFO_FLAG_CNT); + iowrite32(0x01010101, pd->regs + IIC_CLK_DUR); + mmiowb(); + + /* verifying that we have a DT3155 board (not just a SAA7116 chip) */ + read_i2c_reg(pd->regs, DT_ID, &tmp); + if (tmp != DT3155_ID) + return -ENODEV; + + /* initialize AD LUT */ + write_i2c_reg(pd->regs, AD_ADDR, 0); + for (i = 0; i < 256; i++) + write_i2c_reg(pd->regs, AD_LUT, i); + + /* initialize ADC references */ + /* FIXME: pos_ref & neg_ref depend on VT_50HZ */ + write_i2c_reg(pd->regs, AD_ADDR, AD_CMD_REG); + write_i2c_reg(pd->regs, AD_CMD, VIDEO_CNL_1 | SYNC_CNL_1 | SYNC_LVL_3); + write_i2c_reg(pd->regs, AD_ADDR, AD_POS_REF); + write_i2c_reg(pd->regs, AD_CMD, 34); + write_i2c_reg(pd->regs, AD_ADDR, AD_NEG_REF); + write_i2c_reg(pd->regs, AD_CMD, 0); + + /* initialize PM LUT */ + write_i2c_reg(pd->regs, CONFIG, pd->config | PM_LUT_PGM); + for (i = 0; i < 256; i++) { + write_i2c_reg(pd->regs, PM_LUT_ADDR, i); + write_i2c_reg(pd->regs, PM_LUT_DATA, i); + } + write_i2c_reg(pd->regs, CONFIG, pd->config | PM_LUT_PGM | PM_LUT_SEL); + for (i = 0; i < 256; i++) { + write_i2c_reg(pd->regs, PM_LUT_ADDR, i); + write_i2c_reg(pd->regs, PM_LUT_DATA, i); + } + write_i2c_reg(pd->regs, CONFIG, pd->config); /* ACQ_MODE_EVEN */ + + /* select channel 1 for input and set sync level */ + write_i2c_reg(pd->regs, AD_ADDR, AD_CMD_REG); + write_i2c_reg(pd->regs, AD_CMD, VIDEO_CNL_1 | SYNC_CNL_1 | SYNC_LVL_3); + + /* disable all irqs, clear all irq flags */ + iowrite32(FLD_START | FLD_END_EVEN | FLD_END_ODD, + pd->regs + INT_CSR); + + return 0; +} + +static struct video_device dt3155_vdev = { + .name = DT3155_NAME, + .fops = &dt3155_fops, + .ioctl_ops = &dt3155_ioctl_ops, + .minor = -1, + .release = video_device_release_empty, + .tvnorms = V4L2_STD_ALL, +}; + +static int dt3155_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + int err; + struct dt3155_priv *pd; + + err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + if (err) + return -ENODEV; + pd = devm_kzalloc(&pdev->dev, sizeof(*pd), GFP_KERNEL); + if (!pd) + return -ENOMEM; + + err = v4l2_device_register(&pdev->dev, &pd->v4l2_dev); + if (err) + return err; + pd->vdev = dt3155_vdev; + pd->vdev.v4l2_dev = &pd->v4l2_dev; + video_set_drvdata(&pd->vdev, pd); /* for use in video_fops */ + pd->pdev = pdev; + pd->std = V4L2_STD_625_50; + pd->csr2 = VT_50HZ; + pd->width = 768; + pd->height = 576; + INIT_LIST_HEAD(&pd->dmaq); + mutex_init(&pd->mux); + pd->vdev.lock = &pd->mux; /* for locking v4l2_file_operations */ + pd->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + pd->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + pd->vidq.io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ; + pd->vidq.ops = &q_ops; + pd->vidq.mem_ops = &vb2_dma_contig_memops; + pd->vidq.drv_priv = pd; + pd->vidq.min_buffers_needed = 2; + pd->vidq.lock = &pd->mux; /* for locking v4l2_file_operations */ + pd->vdev.queue = &pd->vidq; + err = vb2_queue_init(&pd->vidq); + if (err < 0) + goto err_v4l2_dev_unreg; + pd->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); + if (IS_ERR(pd->alloc_ctx)) { + dev_err(&pdev->dev, "Can't allocate buffer context"); + err = PTR_ERR(pd->alloc_ctx); + goto err_v4l2_dev_unreg; + } + spin_lock_init(&pd->lock); + pd->config = ACQ_MODE_EVEN; + err = pci_enable_device(pdev); + if (err) + goto err_free_ctx; + err = pci_request_region(pdev, 0, pci_name(pdev)); + if (err) + goto err_pci_disable; + pd->regs = pci_iomap(pdev, 0, pci_resource_len(pd->pdev, 0)); + if (!pd->regs) { + err = -ENOMEM; + goto err_free_reg; + } + err = dt3155_init_board(pd); + if (err) + goto err_iounmap; + err = request_irq(pd->pdev->irq, dt3155_irq_handler_even, + IRQF_SHARED, DT3155_NAME, pd); + if (err) + goto err_iounmap; + err = video_register_device(&pd->vdev, VFL_TYPE_GRABBER, -1); + if (err) + goto err_free_irq; + dev_info(&pdev->dev, "/dev/video%i is ready\n", pd->vdev.minor); + return 0; /* success */ + +err_free_irq: + free_irq(pd->pdev->irq, pd); +err_iounmap: + pci_iounmap(pdev, pd->regs); +err_free_reg: + pci_release_region(pdev, 0); +err_pci_disable: + pci_disable_device(pdev); +err_free_ctx: + vb2_dma_contig_cleanup_ctx(pd->alloc_ctx); +err_v4l2_dev_unreg: + v4l2_device_unregister(&pd->v4l2_dev); + return err; +} + +static void dt3155_remove(struct pci_dev *pdev) +{ + struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev); + struct dt3155_priv *pd = container_of(v4l2_dev, struct dt3155_priv, v4l2_dev); + + video_unregister_device(&pd->vdev); + free_irq(pd->pdev->irq, pd); + vb2_queue_release(&pd->vidq); + v4l2_device_unregister(&pd->v4l2_dev); + pci_iounmap(pdev, pd->regs); + pci_release_region(pdev, 0); + pci_disable_device(pdev); + vb2_dma_contig_cleanup_ctx(pd->alloc_ctx); +} + +static const struct pci_device_id pci_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, DT3155_DEVICE_ID) }, + { 0, /* zero marks the end */ }, +}; +MODULE_DEVICE_TABLE(pci, pci_ids); + +static struct pci_driver pci_driver = { + .name = DT3155_NAME, + .id_table = pci_ids, + .probe = dt3155_probe, + .remove = dt3155_remove, +}; + +module_pci_driver(pci_driver); + +MODULE_DESCRIPTION("video4linux pci-driver for dt3155 frame grabber"); +MODULE_AUTHOR("Marin Mitov "); +MODULE_VERSION(DT3155_VERSION); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/pci/dt3155/dt3155.h b/drivers/media/pci/dt3155/dt3155.h new file mode 100644 index 000000000000..4e1f4d598d57 --- /dev/null +++ b/drivers/media/pci/dt3155/dt3155.h @@ -0,0 +1,196 @@ +/*************************************************************************** + * Copyright (C) 2006-2010 by Marin Mitov * + * mitov@issp.bas.bg * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + ***************************************************************************/ + +/* DT3155 header file */ +#ifndef _DT3155_H_ +#define _DT3155_H_ + +#include +#include +#include +#include + +#define DT3155_NAME "dt3155" +#define DT3155_VER_MAJ 2 +#define DT3155_VER_MIN 0 +#define DT3155_VER_EXT 0 +#define DT3155_VERSION __stringify(DT3155_VER_MAJ) "." \ + __stringify(DT3155_VER_MIN) "." \ + __stringify(DT3155_VER_EXT) + +/* DT3155 Base Register offsets (memory mapped) */ +#define EVEN_DMA_START 0x00 +#define ODD_DMA_START 0x0C +#define EVEN_DMA_STRIDE 0x18 +#define ODD_DMA_STRIDE 0x24 +#define EVEN_PIXEL_FMT 0x30 +#define ODD_PIXEL_FMT 0x34 +#define FIFO_TRIGER 0x38 +#define XFER_MODE 0x3C +#define CSR1 0x40 +#define RETRY_WAIT_CNT 0x44 +#define INT_CSR 0x48 +#define EVEN_FLD_MASK 0x4C +#define ODD_FLD_MASK 0x50 +#define MASK_LENGTH 0x54 +#define FIFO_FLAG_CNT 0x58 +#define IIC_CLK_DUR 0x5C +#define IIC_CSR1 0x60 +#define IIC_CSR2 0x64 + +/* DT3155 Internal Registers indexes (i2c/IIC mapped) */ +#define CSR2 0x10 +#define EVEN_CSR 0x11 +#define ODD_CSR 0x12 +#define CONFIG 0x13 +#define DT_ID 0x1F +#define X_CLIP_START 0x20 +#define Y_CLIP_START 0x22 +#define X_CLIP_END 0x24 +#define Y_CLIP_END 0x26 +#define AD_ADDR 0x30 +#define AD_LUT 0x31 +#define AD_CMD 0x32 +#define DIG_OUT 0x40 +#define PM_LUT_ADDR 0x50 +#define PM_LUT_DATA 0x51 + +/* AD command register values */ +#define AD_CMD_REG 0x00 +#define AD_POS_REF 0x01 +#define AD_NEG_REF 0x02 + +/* CSR1 bit masks */ +#define RANGE_EN 0x00008000 +#define CRPT_DIS 0x00004000 +#define ADDR_ERR_ODD 0x00000800 +#define ADDR_ERR_EVEN 0x00000400 +#define FLD_CRPT_ODD 0x00000200 +#define FLD_CRPT_EVEN 0x00000100 +#define FIFO_EN 0x00000080 +#define SRST 0x00000040 +#define FLD_DN_ODD 0x00000020 +#define FLD_DN_EVEN 0x00000010 +/* These should not be used. + * Use CAP_CONT_ODD/EVEN instead +#define CAP_SNGL_ODD 0x00000008 +#define CAP_SNGL_EVEN 0x00000004 +*/ +#define CAP_CONT_ODD 0x00000002 +#define CAP_CONT_EVEN 0x00000001 + +/* INT_CSR bit masks */ +#define FLD_START_EN 0x00000400 +#define FLD_END_ODD_EN 0x00000200 +#define FLD_END_EVEN_EN 0x00000100 +#define FLD_START 0x00000004 +#define FLD_END_ODD 0x00000002 +#define FLD_END_EVEN 0x00000001 + +/* IIC_CSR1 bit masks */ +#define DIRECT_ABORT 0x00000200 + +/* IIC_CSR2 bit masks */ +#define NEW_CYCLE 0x01000000 +#define DIR_RD 0x00010000 +#define IIC_READ 0x01010000 +#define IIC_WRITE 0x01000000 + +/* CSR2 bit masks */ +#define DISP_PASS 0x40 +#define BUSY_ODD 0x20 +#define BUSY_EVEN 0x10 +#define SYNC_PRESENT 0x08 +#define VT_50HZ 0x04 +#define SYNC_SNTL 0x02 +#define CHROM_FILT 0x01 +#define VT_60HZ 0x00 + +/* CSR_EVEN/ODD bit masks */ +#define CSR_ERROR 0x04 +#define CSR_SNGL 0x02 +#define CSR_DONE 0x01 + +/* CONFIG bit masks */ +#define PM_LUT_PGM 0x80 +#define PM_LUT_SEL 0x40 +#define CLIP_EN 0x20 +#define HSCALE_EN 0x10 +#define EXT_TRIG_UP 0x0C +#define EXT_TRIG_DOWN 0x04 +#define ACQ_MODE_NEXT 0x02 +#define ACQ_MODE_ODD 0x01 +#define ACQ_MODE_EVEN 0x00 + +/* AD_CMD bit masks */ +#define VIDEO_CNL_1 0x00 +#define VIDEO_CNL_2 0x40 +#define VIDEO_CNL_3 0x80 +#define VIDEO_CNL_4 0xC0 +#define SYNC_CNL_1 0x00 +#define SYNC_CNL_2 0x10 +#define SYNC_CNL_3 0x20 +#define SYNC_CNL_4 0x30 +#define SYNC_LVL_1 0x00 +#define SYNC_LVL_2 0x04 +#define SYNC_LVL_3 0x08 +#define SYNC_LVL_4 0x0C + +/* DT3155 identificator */ +#define DT3155_ID 0x20 + +/* per board private data structure */ +/** + * struct dt3155_priv - private data structure + * + * @v4l2_dev: v4l2_device structure + * @vdev: video_device structure + * @pdev: pointer to pci_dev structure + * @vidq: vb2_queue structure + * @alloc_ctx: dma_contig allocation context + * @curr_buf: pointer to curren buffer + * @mux: mutex to protect the instance + * @dmaq: queue for dma buffers + * @lock: spinlock for dma queue + * @std: input standard + * @width: frame width + * @height: frame height + * @input: current input + * @sequence: frame counter + * @stats: statistics structure + * @regs: local copy of mmio base register + * @csr2: local copy of csr2 register + * @config: local copy of config register + */ +struct dt3155_priv { + struct v4l2_device v4l2_dev; + struct video_device vdev; + struct pci_dev *pdev; + struct vb2_queue vidq; + struct vb2_alloc_ctx *alloc_ctx; + struct vb2_buffer *curr_buf; + struct mutex mux; + struct list_head dmaq; + spinlock_t lock; + v4l2_std_id std; + unsigned width, height; + unsigned input; + unsigned int sequence; + void __iomem *regs; + u8 csr2, config; +}; + +#endif /* _DT3155_H_ */ diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig index 96498b7fc20e..14697686eea5 100644 --- a/drivers/staging/media/Kconfig +++ b/drivers/staging/media/Kconfig @@ -25,8 +25,6 @@ source "drivers/staging/media/cxd2099/Kconfig" source "drivers/staging/media/davinci_vpfe/Kconfig" -source "drivers/staging/media/dt3155v4l/Kconfig" - source "drivers/staging/media/mn88472/Kconfig" source "drivers/staging/media/mn88473/Kconfig" diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile index a9006bcb4472..34c557b4c6d6 100644 --- a/drivers/staging/media/Makefile +++ b/drivers/staging/media/Makefile @@ -1,7 +1,6 @@ obj-$(CONFIG_I2C_BCM2048) += bcm2048/ obj-$(CONFIG_DVB_CXD2099) += cxd2099/ obj-$(CONFIG_LIRC_STAGING) += lirc/ -obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/ obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/ obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/ obj-$(CONFIG_DVB_MN88472) += mn88472/ diff --git a/drivers/staging/media/dt3155v4l/Kconfig b/drivers/staging/media/dt3155v4l/Kconfig deleted file mode 100644 index fcbcba6e58d2..000000000000 --- a/drivers/staging/media/dt3155v4l/Kconfig +++ /dev/null @@ -1,13 +0,0 @@ -config VIDEO_DT3155 - tristate "DT3155 frame grabber, Video4Linux interface" - depends on PCI && VIDEO_DEV && VIDEO_V4L2 - depends on HAS_DMA - select VIDEOBUF2_DMA_CONTIG - default n - ---help--- - Enables dt3155 device driver for the DataTranslation DT3155 frame grabber. - Say Y here if you have this hardware. - In doubt, say N. - - To compile this driver as a module, choose M here: the - module will be called dt3155v4l. diff --git a/drivers/staging/media/dt3155v4l/Makefile b/drivers/staging/media/dt3155v4l/Makefile deleted file mode 100644 index ce7a3ec2faf3..000000000000 --- a/drivers/staging/media/dt3155v4l/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l.o diff --git a/drivers/staging/media/dt3155v4l/dt3155v4l.c b/drivers/staging/media/dt3155v4l/dt3155v4l.c deleted file mode 100644 index 43c9e0f97876..000000000000 --- a/drivers/staging/media/dt3155v4l/dt3155v4l.c +++ /dev/null @@ -1,626 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006-2010 by Marin Mitov * - * mitov@issp.bas.bg * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - ***************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dt3155v4l.h" - -#define DT3155_DEVICE_ID 0x1223 - -/** - * read_i2c_reg - reads an internal i2c register - * - * @addr: dt3155 mmio base address - * @index: index (internal address) of register to read - * @data: pointer to byte the read data will be placed in - * - * returns: zero on success or error code - * - * This function starts reading the specified (by index) register - * and busy waits for the process to finish. The result is placed - * in a byte pointed by data. - */ -static int read_i2c_reg(void __iomem *addr, u8 index, u8 *data) -{ - u32 tmp = index; - - iowrite32((tmp << 17) | IIC_READ, addr + IIC_CSR2); - mmiowb(); - udelay(45); /* wait at least 43 usec for NEW_CYCLE to clear */ - if (ioread32(addr + IIC_CSR2) & NEW_CYCLE) - return -EIO; /* error: NEW_CYCLE not cleared */ - tmp = ioread32(addr + IIC_CSR1); - if (tmp & DIRECT_ABORT) { - /* reset DIRECT_ABORT bit */ - iowrite32(DIRECT_ABORT, addr + IIC_CSR1); - return -EIO; /* error: DIRECT_ABORT set */ - } - *data = tmp >> 24; - return 0; -} - -/** - * write_i2c_reg - writes to an internal i2c register - * - * @addr: dt3155 mmio base address - * @index: index (internal address) of register to read - * @data: data to be written - * - * returns: zero on success or error code - * - * This function starts writing the specified (by index) register - * and busy waits for the process to finish. - */ -static int write_i2c_reg(void __iomem *addr, u8 index, u8 data) -{ - u32 tmp = index; - - iowrite32((tmp << 17) | IIC_WRITE | data, addr + IIC_CSR2); - mmiowb(); - udelay(65); /* wait at least 63 usec for NEW_CYCLE to clear */ - if (ioread32(addr + IIC_CSR2) & NEW_CYCLE) - return -EIO; /* error: NEW_CYCLE not cleared */ - if (ioread32(addr + IIC_CSR1) & DIRECT_ABORT) { - /* reset DIRECT_ABORT bit */ - iowrite32(DIRECT_ABORT, addr + IIC_CSR1); - return -EIO; /* error: DIRECT_ABORT set */ - } - return 0; -} - -/** - * write_i2c_reg_nowait - writes to an internal i2c register - * - * @addr: dt3155 mmio base address - * @index: index (internal address) of register to read - * @data: data to be written - * - * This function starts writing the specified (by index) register - * and then returns. - */ -static void write_i2c_reg_nowait(void __iomem *addr, u8 index, u8 data) -{ - u32 tmp = index; - - iowrite32((tmp << 17) | IIC_WRITE | data, addr + IIC_CSR2); - mmiowb(); -} - -/** - * wait_i2c_reg - waits the read/write to finish - * - * @addr: dt3155 mmio base address - * - * returns: zero on success or error code - * - * This function waits reading/writing to finish. - */ -static int wait_i2c_reg(void __iomem *addr) -{ - if (ioread32(addr + IIC_CSR2) & NEW_CYCLE) - udelay(65); /* wait at least 63 usec for NEW_CYCLE to clear */ - if (ioread32(addr + IIC_CSR2) & NEW_CYCLE) - return -EIO; /* error: NEW_CYCLE not cleared */ - if (ioread32(addr + IIC_CSR1) & DIRECT_ABORT) { - /* reset DIRECT_ABORT bit */ - iowrite32(DIRECT_ABORT, addr + IIC_CSR1); - return -EIO; /* error: DIRECT_ABORT set */ - } - return 0; -} - -static int -dt3155_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, - unsigned int *nbuffers, unsigned int *num_planes, - unsigned int sizes[], void *alloc_ctxs[]) - -{ - struct dt3155_priv *pd = vb2_get_drv_priv(vq); - unsigned size = pd->width * pd->height; - - if (vq->num_buffers + *nbuffers < 2) - *nbuffers = 2 - vq->num_buffers; - if (fmt && fmt->fmt.pix.sizeimage < size) - return -EINVAL; - *num_planes = 1; - sizes[0] = fmt ? fmt->fmt.pix.sizeimage : size; - alloc_ctxs[0] = pd->alloc_ctx; - return 0; -} - -static int dt3155_buf_prepare(struct vb2_buffer *vb) -{ - struct dt3155_priv *pd = vb2_get_drv_priv(vb->vb2_queue); - - vb2_set_plane_payload(vb, 0, pd->width * pd->height); - return 0; -} - -static int dt3155_start_streaming(struct vb2_queue *q, unsigned count) -{ - struct dt3155_priv *pd = vb2_get_drv_priv(q); - struct vb2_buffer *vb = pd->curr_buf; - dma_addr_t dma_addr; - - pd->sequence = 0; - dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0); - iowrite32(dma_addr, pd->regs + EVEN_DMA_START); - iowrite32(dma_addr + pd->width, pd->regs + ODD_DMA_START); - iowrite32(pd->width, pd->regs + EVEN_DMA_STRIDE); - iowrite32(pd->width, pd->regs + ODD_DMA_STRIDE); - /* enable interrupts, clear all irq flags */ - iowrite32(FLD_START_EN | FLD_END_ODD_EN | FLD_START | - FLD_END_EVEN | FLD_END_ODD, pd->regs + INT_CSR); - iowrite32(FIFO_EN | SRST | FLD_CRPT_ODD | FLD_CRPT_EVEN | - FLD_DN_ODD | FLD_DN_EVEN | CAP_CONT_EVEN | CAP_CONT_ODD, - pd->regs + CSR1); - wait_i2c_reg(pd->regs); - write_i2c_reg(pd->regs, CONFIG, pd->config); - write_i2c_reg(pd->regs, EVEN_CSR, CSR_ERROR | CSR_DONE); - write_i2c_reg(pd->regs, ODD_CSR, CSR_ERROR | CSR_DONE); - - /* start the board */ - write_i2c_reg(pd->regs, CSR2, pd->csr2 | BUSY_EVEN | BUSY_ODD); - return 0; -} - -static void dt3155_stop_streaming(struct vb2_queue *q) -{ - struct dt3155_priv *pd = vb2_get_drv_priv(q); - struct vb2_buffer *vb; - - spin_lock_irq(&pd->lock); - /* stop the board */ - write_i2c_reg_nowait(pd->regs, CSR2, pd->csr2); - iowrite32(FIFO_EN | SRST | FLD_CRPT_ODD | FLD_CRPT_EVEN | - FLD_DN_ODD | FLD_DN_EVEN, pd->regs + CSR1); - /* disable interrupts, clear all irq flags */ - iowrite32(FLD_START | FLD_END_EVEN | FLD_END_ODD, pd->regs + INT_CSR); - spin_unlock_irq(&pd->lock); - - /* - * It is not clear whether the DMA stops at once or whether it - * will finish the current frame or field first. To be on the - * safe side we wait a bit. - */ - msleep(45); - - spin_lock_irq(&pd->lock); - if (pd->curr_buf) { - vb2_buffer_done(pd->curr_buf, VB2_BUF_STATE_ERROR); - pd->curr_buf = NULL; - } - - while (!list_empty(&pd->dmaq)) { - vb = list_first_entry(&pd->dmaq, typeof(*vb), done_entry); - list_del(&vb->done_entry); - vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); - } - spin_unlock_irq(&pd->lock); -} - -static void dt3155_buf_queue(struct vb2_buffer *vb) -{ - struct dt3155_priv *pd = vb2_get_drv_priv(vb->vb2_queue); - - /* pd->vidq.streaming = 1 when dt3155_buf_queue() is invoked */ - spin_lock_irq(&pd->lock); - if (pd->curr_buf) - list_add_tail(&vb->done_entry, &pd->dmaq); - else - pd->curr_buf = vb; - spin_unlock_irq(&pd->lock); -} - -static const struct vb2_ops q_ops = { - .queue_setup = dt3155_queue_setup, - .wait_prepare = vb2_ops_wait_prepare, - .wait_finish = vb2_ops_wait_finish, - .buf_prepare = dt3155_buf_prepare, - .start_streaming = dt3155_start_streaming, - .stop_streaming = dt3155_stop_streaming, - .buf_queue = dt3155_buf_queue, -}; - -static irqreturn_t dt3155_irq_handler_even(int irq, void *dev_id) -{ - struct dt3155_priv *ipd = dev_id; - struct vb2_buffer *ivb; - dma_addr_t dma_addr; - u32 tmp; - - tmp = ioread32(ipd->regs + INT_CSR) & (FLD_START | FLD_END_ODD); - if (!tmp) - return IRQ_NONE; /* not our irq */ - if ((tmp & FLD_START) && !(tmp & FLD_END_ODD)) { - iowrite32(FLD_START_EN | FLD_END_ODD_EN | FLD_START, - ipd->regs + INT_CSR); - return IRQ_HANDLED; /* start of field irq */ - } - tmp = ioread32(ipd->regs + CSR1) & (FLD_CRPT_EVEN | FLD_CRPT_ODD); - if (tmp) { - iowrite32(FIFO_EN | SRST | FLD_CRPT_ODD | FLD_CRPT_EVEN | - FLD_DN_ODD | FLD_DN_EVEN | - CAP_CONT_EVEN | CAP_CONT_ODD, - ipd->regs + CSR1); - mmiowb(); - } - - spin_lock(&ipd->lock); - if (ipd->curr_buf && !list_empty(&ipd->dmaq)) { - v4l2_get_timestamp(&ipd->curr_buf->v4l2_buf.timestamp); - ipd->curr_buf->v4l2_buf.sequence = ipd->sequence++; - ipd->curr_buf->v4l2_buf.field = V4L2_FIELD_NONE; - vb2_buffer_done(ipd->curr_buf, VB2_BUF_STATE_DONE); - - ivb = list_first_entry(&ipd->dmaq, typeof(*ivb), done_entry); - list_del(&ivb->done_entry); - ipd->curr_buf = ivb; - dma_addr = vb2_dma_contig_plane_dma_addr(ivb, 0); - iowrite32(dma_addr, ipd->regs + EVEN_DMA_START); - iowrite32(dma_addr + ipd->width, ipd->regs + ODD_DMA_START); - iowrite32(ipd->width, ipd->regs + EVEN_DMA_STRIDE); - iowrite32(ipd->width, ipd->regs + ODD_DMA_STRIDE); - mmiowb(); - } - - /* enable interrupts, clear all irq flags */ - iowrite32(FLD_START_EN | FLD_END_ODD_EN | FLD_START | - FLD_END_EVEN | FLD_END_ODD, ipd->regs + INT_CSR); - spin_unlock(&ipd->lock); - return IRQ_HANDLED; -} - -static const struct v4l2_file_operations dt3155_fops = { - .owner = THIS_MODULE, - .open = v4l2_fh_open, - .release = vb2_fop_release, - .unlocked_ioctl = video_ioctl2, - .read = vb2_fop_read, - .mmap = vb2_fop_mmap, - .poll = vb2_fop_poll -}; - -static int dt3155_querycap(struct file *filp, void *p, struct v4l2_capability *cap) -{ - struct dt3155_priv *pd = video_drvdata(filp); - - strcpy(cap->driver, DT3155_NAME); - strcpy(cap->card, DT3155_NAME " frame grabber"); - sprintf(cap->bus_info, "PCI:%s", pci_name(pd->pdev)); - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_STREAMING | V4L2_CAP_READWRITE; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; - return 0; -} - -static int dt3155_enum_fmt_vid_cap(struct file *filp, void *p, struct v4l2_fmtdesc *f) -{ - if (f->index) - return -EINVAL; - f->pixelformat = V4L2_PIX_FMT_GREY; - strcpy(f->description, "8-bit Greyscale"); - return 0; -} - -static int dt3155_fmt_vid_cap(struct file *filp, void *p, struct v4l2_format *f) -{ - struct dt3155_priv *pd = video_drvdata(filp); - - f->fmt.pix.width = pd->width; - f->fmt.pix.height = pd->height; - f->fmt.pix.pixelformat = V4L2_PIX_FMT_GREY; - f->fmt.pix.field = V4L2_FIELD_NONE; - f->fmt.pix.bytesperline = f->fmt.pix.width; - f->fmt.pix.sizeimage = f->fmt.pix.width * f->fmt.pix.height; - f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - return 0; -} - -static int dt3155_g_std(struct file *filp, void *p, v4l2_std_id *norm) -{ - struct dt3155_priv *pd = video_drvdata(filp); - - *norm = pd->std; - return 0; -} - -static int dt3155_s_std(struct file *filp, void *p, v4l2_std_id norm) -{ - struct dt3155_priv *pd = video_drvdata(filp); - - if (pd->std == norm) - return 0; - if (vb2_is_busy(&pd->vidq)) - return -EBUSY; - pd->std = norm; - if (pd->std & V4L2_STD_525_60) { - pd->csr2 = VT_60HZ; - pd->width = 640; - pd->height = 480; - } else { - pd->csr2 = VT_50HZ; - pd->width = 768; - pd->height = 576; - } - return 0; -} - -static int dt3155_enum_input(struct file *filp, void *p, struct v4l2_input *input) -{ - if (input->index > 3) - return -EINVAL; - if (input->index) - snprintf(input->name, sizeof(input->name), "VID%d", input->index); - else - strlcpy(input->name, "J2/VID0", sizeof(input->name)); - input->type = V4L2_INPUT_TYPE_CAMERA; - input->std = V4L2_STD_ALL; - input->status = 0; - return 0; -} - -static int dt3155_g_input(struct file *filp, void *p, unsigned int *i) -{ - struct dt3155_priv *pd = video_drvdata(filp); - - *i = pd->input; - return 0; -} - -static int dt3155_s_input(struct file *filp, void *p, unsigned int i) -{ - struct dt3155_priv *pd = video_drvdata(filp); - - if (i > 3) - return -EINVAL; - pd->input = i; - write_i2c_reg(pd->regs, AD_ADDR, AD_CMD_REG); - write_i2c_reg(pd->regs, AD_CMD, (i << 6) | (i << 4) | SYNC_LVL_3); - return 0; -} - -static const struct v4l2_ioctl_ops dt3155_ioctl_ops = { - .vidioc_querycap = dt3155_querycap, - .vidioc_enum_fmt_vid_cap = dt3155_enum_fmt_vid_cap, - .vidioc_try_fmt_vid_cap = dt3155_fmt_vid_cap, - .vidioc_g_fmt_vid_cap = dt3155_fmt_vid_cap, - .vidioc_s_fmt_vid_cap = dt3155_fmt_vid_cap, - .vidioc_reqbufs = vb2_ioctl_reqbufs, - .vidioc_create_bufs = vb2_ioctl_create_bufs, - .vidioc_querybuf = vb2_ioctl_querybuf, - .vidioc_expbuf = vb2_ioctl_expbuf, - .vidioc_qbuf = vb2_ioctl_qbuf, - .vidioc_dqbuf = vb2_ioctl_dqbuf, - .vidioc_streamon = vb2_ioctl_streamon, - .vidioc_streamoff = vb2_ioctl_streamoff, - .vidioc_g_std = dt3155_g_std, - .vidioc_s_std = dt3155_s_std, - .vidioc_enum_input = dt3155_enum_input, - .vidioc_g_input = dt3155_g_input, - .vidioc_s_input = dt3155_s_input, -}; - -static int dt3155_init_board(struct dt3155_priv *pd) -{ - struct pci_dev *pdev = pd->pdev; - int i; - u8 tmp = 0; - - pci_set_master(pdev); /* dt3155 needs it */ - - /* resetting the adapter */ - iowrite32(ADDR_ERR_ODD | ADDR_ERR_EVEN | FLD_CRPT_ODD | FLD_CRPT_EVEN | - FLD_DN_ODD | FLD_DN_EVEN, pd->regs + CSR1); - mmiowb(); - msleep(20); - - /* initializing adapter registers */ - iowrite32(FIFO_EN | SRST, pd->regs + CSR1); - mmiowb(); - iowrite32(0xEEEEEE01, pd->regs + EVEN_PIXEL_FMT); - iowrite32(0xEEEEEE01, pd->regs + ODD_PIXEL_FMT); - iowrite32(0x00000020, pd->regs + FIFO_TRIGER); - iowrite32(0x00000103, pd->regs + XFER_MODE); - iowrite32(0, pd->regs + RETRY_WAIT_CNT); - iowrite32(0, pd->regs + INT_CSR); - iowrite32(1, pd->regs + EVEN_FLD_MASK); - iowrite32(1, pd->regs + ODD_FLD_MASK); - iowrite32(0, pd->regs + MASK_LENGTH); - iowrite32(0x0005007C, pd->regs + FIFO_FLAG_CNT); - iowrite32(0x01010101, pd->regs + IIC_CLK_DUR); - mmiowb(); - - /* verifying that we have a DT3155 board (not just a SAA7116 chip) */ - read_i2c_reg(pd->regs, DT_ID, &tmp); - if (tmp != DT3155_ID) - return -ENODEV; - - /* initialize AD LUT */ - write_i2c_reg(pd->regs, AD_ADDR, 0); - for (i = 0; i < 256; i++) - write_i2c_reg(pd->regs, AD_LUT, i); - - /* initialize ADC references */ - /* FIXME: pos_ref & neg_ref depend on VT_50HZ */ - write_i2c_reg(pd->regs, AD_ADDR, AD_CMD_REG); - write_i2c_reg(pd->regs, AD_CMD, VIDEO_CNL_1 | SYNC_CNL_1 | SYNC_LVL_3); - write_i2c_reg(pd->regs, AD_ADDR, AD_POS_REF); - write_i2c_reg(pd->regs, AD_CMD, 34); - write_i2c_reg(pd->regs, AD_ADDR, AD_NEG_REF); - write_i2c_reg(pd->regs, AD_CMD, 0); - - /* initialize PM LUT */ - write_i2c_reg(pd->regs, CONFIG, pd->config | PM_LUT_PGM); - for (i = 0; i < 256; i++) { - write_i2c_reg(pd->regs, PM_LUT_ADDR, i); - write_i2c_reg(pd->regs, PM_LUT_DATA, i); - } - write_i2c_reg(pd->regs, CONFIG, pd->config | PM_LUT_PGM | PM_LUT_SEL); - for (i = 0; i < 256; i++) { - write_i2c_reg(pd->regs, PM_LUT_ADDR, i); - write_i2c_reg(pd->regs, PM_LUT_DATA, i); - } - write_i2c_reg(pd->regs, CONFIG, pd->config); /* ACQ_MODE_EVEN */ - - /* select channel 1 for input and set sync level */ - write_i2c_reg(pd->regs, AD_ADDR, AD_CMD_REG); - write_i2c_reg(pd->regs, AD_CMD, VIDEO_CNL_1 | SYNC_CNL_1 | SYNC_LVL_3); - - /* disable all irqs, clear all irq flags */ - iowrite32(FLD_START | FLD_END_EVEN | FLD_END_ODD, - pd->regs + INT_CSR); - - return 0; -} - -static struct video_device dt3155_vdev = { - .name = DT3155_NAME, - .fops = &dt3155_fops, - .ioctl_ops = &dt3155_ioctl_ops, - .minor = -1, - .release = video_device_release_empty, - .tvnorms = V4L2_STD_ALL, -}; - -static int dt3155_probe(struct pci_dev *pdev, const struct pci_device_id *id) -{ - int err; - struct dt3155_priv *pd; - - err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); - if (err) - return -ENODEV; - pd = devm_kzalloc(&pdev->dev, sizeof(*pd), GFP_KERNEL); - if (!pd) - return -ENOMEM; - - err = v4l2_device_register(&pdev->dev, &pd->v4l2_dev); - if (err) - return err; - pd->vdev = dt3155_vdev; - pd->vdev.v4l2_dev = &pd->v4l2_dev; - video_set_drvdata(&pd->vdev, pd); /* for use in video_fops */ - pd->pdev = pdev; - pd->std = V4L2_STD_625_50; - pd->csr2 = VT_50HZ; - pd->width = 768; - pd->height = 576; - INIT_LIST_HEAD(&pd->dmaq); - mutex_init(&pd->mux); - pd->vdev.lock = &pd->mux; /* for locking v4l2_file_operations */ - pd->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - pd->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; - pd->vidq.io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ; - pd->vidq.ops = &q_ops; - pd->vidq.mem_ops = &vb2_dma_contig_memops; - pd->vidq.drv_priv = pd; - pd->vidq.min_buffers_needed = 2; - pd->vidq.lock = &pd->mux; /* for locking v4l2_file_operations */ - pd->vdev.queue = &pd->vidq; - err = vb2_queue_init(&pd->vidq); - if (err < 0) - goto err_v4l2_dev_unreg; - pd->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); - if (IS_ERR(pd->alloc_ctx)) { - dev_err(&pdev->dev, "Can't allocate buffer context"); - err = PTR_ERR(pd->alloc_ctx); - goto err_v4l2_dev_unreg; - } - spin_lock_init(&pd->lock); - pd->config = ACQ_MODE_EVEN; - err = pci_enable_device(pdev); - if (err) - goto err_free_ctx; - err = pci_request_region(pdev, 0, pci_name(pdev)); - if (err) - goto err_pci_disable; - pd->regs = pci_iomap(pdev, 0, pci_resource_len(pd->pdev, 0)); - if (!pd->regs) { - err = -ENOMEM; - goto err_free_reg; - } - err = dt3155_init_board(pd); - if (err) - goto err_iounmap; - err = request_irq(pd->pdev->irq, dt3155_irq_handler_even, - IRQF_SHARED, DT3155_NAME, pd); - if (err) - goto err_iounmap; - err = video_register_device(&pd->vdev, VFL_TYPE_GRABBER, -1); - if (err) - goto err_free_irq; - dev_info(&pdev->dev, "/dev/video%i is ready\n", pd->vdev.minor); - return 0; /* success */ - -err_free_irq: - free_irq(pd->pdev->irq, pd); -err_iounmap: - pci_iounmap(pdev, pd->regs); -err_free_reg: - pci_release_region(pdev, 0); -err_pci_disable: - pci_disable_device(pdev); -err_free_ctx: - vb2_dma_contig_cleanup_ctx(pd->alloc_ctx); -err_v4l2_dev_unreg: - v4l2_device_unregister(&pd->v4l2_dev); - return err; -} - -static void dt3155_remove(struct pci_dev *pdev) -{ - struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev); - struct dt3155_priv *pd = container_of(v4l2_dev, struct dt3155_priv, v4l2_dev); - - video_unregister_device(&pd->vdev); - free_irq(pd->pdev->irq, pd); - vb2_queue_release(&pd->vidq); - v4l2_device_unregister(&pd->v4l2_dev); - pci_iounmap(pdev, pd->regs); - pci_release_region(pdev, 0); - pci_disable_device(pdev); - vb2_dma_contig_cleanup_ctx(pd->alloc_ctx); -} - -static const struct pci_device_id pci_ids[] = { - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, DT3155_DEVICE_ID) }, - { 0, /* zero marks the end */ }, -}; -MODULE_DEVICE_TABLE(pci, pci_ids); - -static struct pci_driver pci_driver = { - .name = DT3155_NAME, - .id_table = pci_ids, - .probe = dt3155_probe, - .remove = dt3155_remove, -}; - -module_pci_driver(pci_driver); - -MODULE_DESCRIPTION("video4linux pci-driver for dt3155 frame grabber"); -MODULE_AUTHOR("Marin Mitov "); -MODULE_VERSION(DT3155_VERSION); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/media/dt3155v4l/dt3155v4l.h b/drivers/staging/media/dt3155v4l/dt3155v4l.h deleted file mode 100644 index bcf7b5ef75e6..000000000000 --- a/drivers/staging/media/dt3155v4l/dt3155v4l.h +++ /dev/null @@ -1,196 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006-2010 by Marin Mitov * - * mitov@issp.bas.bg * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - ***************************************************************************/ - -/* DT3155 header file */ -#ifndef _DT3155_H_ -#define _DT3155_H_ - -#include -#include -#include -#include - -#define DT3155_NAME "dt3155" -#define DT3155_VER_MAJ 1 -#define DT3155_VER_MIN 1 -#define DT3155_VER_EXT 0 -#define DT3155_VERSION __stringify(DT3155_VER_MAJ) "." \ - __stringify(DT3155_VER_MIN) "." \ - __stringify(DT3155_VER_EXT) - -/* DT3155 Base Register offsets (memory mapped) */ -#define EVEN_DMA_START 0x00 -#define ODD_DMA_START 0x0C -#define EVEN_DMA_STRIDE 0x18 -#define ODD_DMA_STRIDE 0x24 -#define EVEN_PIXEL_FMT 0x30 -#define ODD_PIXEL_FMT 0x34 -#define FIFO_TRIGER 0x38 -#define XFER_MODE 0x3C -#define CSR1 0x40 -#define RETRY_WAIT_CNT 0x44 -#define INT_CSR 0x48 -#define EVEN_FLD_MASK 0x4C -#define ODD_FLD_MASK 0x50 -#define MASK_LENGTH 0x54 -#define FIFO_FLAG_CNT 0x58 -#define IIC_CLK_DUR 0x5C -#define IIC_CSR1 0x60 -#define IIC_CSR2 0x64 - -/* DT3155 Internal Registers indexes (i2c/IIC mapped) */ -#define CSR2 0x10 -#define EVEN_CSR 0x11 -#define ODD_CSR 0x12 -#define CONFIG 0x13 -#define DT_ID 0x1F -#define X_CLIP_START 0x20 -#define Y_CLIP_START 0x22 -#define X_CLIP_END 0x24 -#define Y_CLIP_END 0x26 -#define AD_ADDR 0x30 -#define AD_LUT 0x31 -#define AD_CMD 0x32 -#define DIG_OUT 0x40 -#define PM_LUT_ADDR 0x50 -#define PM_LUT_DATA 0x51 - -/* AD command register values */ -#define AD_CMD_REG 0x00 -#define AD_POS_REF 0x01 -#define AD_NEG_REF 0x02 - -/* CSR1 bit masks */ -#define RANGE_EN 0x00008000 -#define CRPT_DIS 0x00004000 -#define ADDR_ERR_ODD 0x00000800 -#define ADDR_ERR_EVEN 0x00000400 -#define FLD_CRPT_ODD 0x00000200 -#define FLD_CRPT_EVEN 0x00000100 -#define FIFO_EN 0x00000080 -#define SRST 0x00000040 -#define FLD_DN_ODD 0x00000020 -#define FLD_DN_EVEN 0x00000010 -/* These should not be used. - * Use CAP_CONT_ODD/EVEN instead -#define CAP_SNGL_ODD 0x00000008 -#define CAP_SNGL_EVEN 0x00000004 -*/ -#define CAP_CONT_ODD 0x00000002 -#define CAP_CONT_EVEN 0x00000001 - -/* INT_CSR bit masks */ -#define FLD_START_EN 0x00000400 -#define FLD_END_ODD_EN 0x00000200 -#define FLD_END_EVEN_EN 0x00000100 -#define FLD_START 0x00000004 -#define FLD_END_ODD 0x00000002 -#define FLD_END_EVEN 0x00000001 - -/* IIC_CSR1 bit masks */ -#define DIRECT_ABORT 0x00000200 - -/* IIC_CSR2 bit masks */ -#define NEW_CYCLE 0x01000000 -#define DIR_RD 0x00010000 -#define IIC_READ 0x01010000 -#define IIC_WRITE 0x01000000 - -/* CSR2 bit masks */ -#define DISP_PASS 0x40 -#define BUSY_ODD 0x20 -#define BUSY_EVEN 0x10 -#define SYNC_PRESENT 0x08 -#define VT_50HZ 0x04 -#define SYNC_SNTL 0x02 -#define CHROM_FILT 0x01 -#define VT_60HZ 0x00 - -/* CSR_EVEN/ODD bit masks */ -#define CSR_ERROR 0x04 -#define CSR_SNGL 0x02 -#define CSR_DONE 0x01 - -/* CONFIG bit masks */ -#define PM_LUT_PGM 0x80 -#define PM_LUT_SEL 0x40 -#define CLIP_EN 0x20 -#define HSCALE_EN 0x10 -#define EXT_TRIG_UP 0x0C -#define EXT_TRIG_DOWN 0x04 -#define ACQ_MODE_NEXT 0x02 -#define ACQ_MODE_ODD 0x01 -#define ACQ_MODE_EVEN 0x00 - -/* AD_CMD bit masks */ -#define VIDEO_CNL_1 0x00 -#define VIDEO_CNL_2 0x40 -#define VIDEO_CNL_3 0x80 -#define VIDEO_CNL_4 0xC0 -#define SYNC_CNL_1 0x00 -#define SYNC_CNL_2 0x10 -#define SYNC_CNL_3 0x20 -#define SYNC_CNL_4 0x30 -#define SYNC_LVL_1 0x00 -#define SYNC_LVL_2 0x04 -#define SYNC_LVL_3 0x08 -#define SYNC_LVL_4 0x0C - -/* DT3155 identificator */ -#define DT3155_ID 0x20 - -/* per board private data structure */ -/** - * struct dt3155_priv - private data structure - * - * @v4l2_dev: v4l2_device structure - * @vdev: video_device structure - * @pdev: pointer to pci_dev structure - * @vidq: vb2_queue structure - * @alloc_ctx: dma_contig allocation context - * @curr_buf: pointer to curren buffer - * @mux: mutex to protect the instance - * @dmaq: queue for dma buffers - * @lock: spinlock for dma queue - * @std: input standard - * @width: frame width - * @height: frame height - * @input: current input - * @sequence: frame counter - * @stats: statistics structure - * @regs: local copy of mmio base register - * @csr2: local copy of csr2 register - * @config: local copy of config register - */ -struct dt3155_priv { - struct v4l2_device v4l2_dev; - struct video_device vdev; - struct pci_dev *pdev; - struct vb2_queue vidq; - struct vb2_alloc_ctx *alloc_ctx; - struct vb2_buffer *curr_buf; - struct mutex mux; - struct list_head dmaq; - spinlock_t lock; - v4l2_std_id std; - unsigned width, height; - unsigned input; - unsigned int sequence; - void __iomem *regs; - u8 csr2, config; -}; - -#endif /* _DT3155_H_ */ -- cgit v1.2.3-59-g8ed1b From 7c89a21b88e6a07e1be811508f381673f498bc8a Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 26 Apr 2015 06:27:00 -0300 Subject: [media] dt3155: add GFP_DMA32 flag to vb2 queue Ensure that buffers are allocated from the DMA32 zone since this device only handles 32 bit DMA addresses. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/dt3155/dt3155.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/pci/dt3155/dt3155.c b/drivers/media/pci/dt3155/dt3155.c index 3131c2ee3b85..586c446a7054 100644 --- a/drivers/media/pci/dt3155/dt3155.c +++ b/drivers/media/pci/dt3155/dt3155.c @@ -538,6 +538,7 @@ static int dt3155_probe(struct pci_dev *pdev, const struct pci_device_id *id) pd->vidq.mem_ops = &vb2_dma_contig_memops; pd->vidq.drv_priv = pd; pd->vidq.min_buffers_needed = 2; + pd->vidq.gfp_flags = GFP_DMA32; pd->vidq.lock = &pd->mux; /* for locking v4l2_file_operations */ pd->vdev.queue = &pd->vidq; err = vb2_queue_init(&pd->vidq); -- cgit v1.2.3-59-g8ed1b From 90874cd61d5f5260714fc1b5728a3fbb28348b53 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 1 May 2015 08:30:06 -0300 Subject: dt3155: fix CodingStyle issues There are a few lines longer than 80 cols for no good reason. Fix them sooner than latter, making checkpatch.pl happy. Cc: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/dt3155/dt3155.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/dt3155/dt3155.c b/drivers/media/pci/dt3155/dt3155.c index 586c446a7054..89d0dc705e4a 100644 --- a/drivers/media/pci/dt3155/dt3155.c +++ b/drivers/media/pci/dt3155/dt3155.c @@ -303,7 +303,8 @@ static const struct v4l2_file_operations dt3155_fops = { .poll = vb2_fop_poll }; -static int dt3155_querycap(struct file *filp, void *p, struct v4l2_capability *cap) +static int dt3155_querycap(struct file *filp, void *p, + struct v4l2_capability *cap) { struct dt3155_priv *pd = video_drvdata(filp); @@ -316,7 +317,8 @@ static int dt3155_querycap(struct file *filp, void *p, struct v4l2_capability *c return 0; } -static int dt3155_enum_fmt_vid_cap(struct file *filp, void *p, struct v4l2_fmtdesc *f) +static int dt3155_enum_fmt_vid_cap(struct file *filp, + void *p, struct v4l2_fmtdesc *f) { if (f->index) return -EINVAL; @@ -368,12 +370,14 @@ static int dt3155_s_std(struct file *filp, void *p, v4l2_std_id norm) return 0; } -static int dt3155_enum_input(struct file *filp, void *p, struct v4l2_input *input) +static int dt3155_enum_input(struct file *filp, void *p, + struct v4l2_input *input) { if (input->index > 3) return -EINVAL; if (input->index) - snprintf(input->name, sizeof(input->name), "VID%d", input->index); + snprintf(input->name, sizeof(input->name), "VID%d", + input->index); else strlcpy(input->name, "J2/VID0", sizeof(input->name)); input->type = V4L2_INPUT_TYPE_CAMERA; @@ -594,7 +598,8 @@ err_v4l2_dev_unreg: static void dt3155_remove(struct pci_dev *pdev) { struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev); - struct dt3155_priv *pd = container_of(v4l2_dev, struct dt3155_priv, v4l2_dev); + struct dt3155_priv *pd = container_of(v4l2_dev, struct dt3155_priv, + v4l2_dev); video_unregister_device(&pd->vdev); free_irq(pd->pdev->irq, pd); -- cgit v1.2.3-59-g8ed1b From ebcff5fce6b189306756b0cb06779e15f1c93848 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 9 Apr 2015 04:01:33 -0300 Subject: [media] v4l2: replace enum_mbus_fmt by enum_mbus_code Replace all calls to the enum_mbus_fmt video op by the pad enum_mbus_code op and remove the duplicate video op. Signed-off-by: Hans Verkuil Acked-by: Guennadi Liakhovetski Acked-by: Scott Jiang Cc: Jonathan Corbet Cc: Kamil Debski Acked-by: Prabhakar Lad Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7170.c | 15 ++++++++---- drivers/media/i2c/adv7175.c | 15 ++++++++---- drivers/media/i2c/adv7183.c | 15 ++++++++---- drivers/media/i2c/adv7842.c | 11 +++++---- drivers/media/i2c/ak881x.c | 15 ++++++++---- drivers/media/i2c/ml86v7667.c | 15 ++++++++---- drivers/media/i2c/mt9v011.c | 15 ++++++++---- drivers/media/i2c/ov7670.c | 11 +++++---- drivers/media/i2c/soc_camera/imx074.c | 16 +++++++++---- drivers/media/i2c/soc_camera/mt9m001.c | 15 ++++++++---- drivers/media/i2c/soc_camera/mt9m111.c | 15 ++++++++---- drivers/media/i2c/soc_camera/mt9t031.c | 15 ++++++++---- drivers/media/i2c/soc_camera/mt9t112.c | 15 ++++++++---- drivers/media/i2c/soc_camera/mt9v022.c | 15 ++++++++---- drivers/media/i2c/soc_camera/ov2640.c | 15 ++++++++---- drivers/media/i2c/soc_camera/ov5642.c | 15 ++++++++---- drivers/media/i2c/soc_camera/ov6650.c | 15 ++++++++---- drivers/media/i2c/soc_camera/ov772x.c | 15 ++++++++---- drivers/media/i2c/soc_camera/ov9640.c | 15 ++++++++---- drivers/media/i2c/soc_camera/ov9740.c | 19 +++++++++------ drivers/media/i2c/soc_camera/rj54n1cb0c.c | 15 ++++++++---- drivers/media/i2c/soc_camera/tw9910.c | 15 ++++++++---- drivers/media/i2c/sr030pc30.c | 16 +++++++++---- drivers/media/i2c/tvp514x.c | 20 ---------------- drivers/media/i2c/tvp5150.c | 15 ++++++++---- drivers/media/i2c/tvp7002.c | 20 ---------------- drivers/media/i2c/vs6624.c | 15 ++++++++---- drivers/media/platform/blackfin/bfin_capture.c | 17 +++++++++----- drivers/media/platform/soc_camera/atmel-isi.c | 19 ++++++++------- drivers/media/platform/soc_camera/mx2_camera.c | 27 ++++++++++++---------- drivers/media/platform/soc_camera/mx3_camera.c | 23 ++++++++++-------- drivers/media/platform/soc_camera/omap1_camera.c | 21 +++++++++-------- drivers/media/platform/soc_camera/pxa_camera.c | 19 ++++++++------- drivers/media/platform/soc_camera/rcar_vin.c | 19 ++++++++------- .../platform/soc_camera/sh_mobile_ceu_camera.c | 19 ++++++++------- drivers/media/platform/soc_camera/soc_camera.c | 15 ++++++++---- .../platform/soc_camera/soc_camera_platform.c | 15 ++++++++---- include/media/v4l2-subdev.h | 4 ---- 38 files changed, 361 insertions(+), 250 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/adv7170.c b/drivers/media/i2c/adv7170.c index 40a1a95c7ce9..cfe963b2fe1c 100644 --- a/drivers/media/i2c/adv7170.c +++ b/drivers/media/i2c/adv7170.c @@ -262,13 +262,14 @@ static int adv7170_s_routing(struct v4l2_subdev *sd, return 0; } -static int adv7170_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - u32 *code) +static int adv7170_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { - if (index >= ARRAY_SIZE(adv7170_codes)) + if (code->pad || code->index >= ARRAY_SIZE(adv7170_codes)) return -EINVAL; - *code = adv7170_codes[index]; + code->code = adv7170_codes[code->index]; return 0; } @@ -323,11 +324,15 @@ static const struct v4l2_subdev_video_ops adv7170_video_ops = { .s_routing = adv7170_s_routing, .s_mbus_fmt = adv7170_s_fmt, .g_mbus_fmt = adv7170_g_fmt, - .enum_mbus_fmt = adv7170_enum_fmt, +}; + +static const struct v4l2_subdev_pad_ops adv7170_pad_ops = { + .enum_mbus_code = adv7170_enum_mbus_code, }; static const struct v4l2_subdev_ops adv7170_ops = { .video = &adv7170_video_ops, + .pad = &adv7170_pad_ops, }; /* ----------------------------------------------------------------------- */ diff --git a/drivers/media/i2c/adv7175.c b/drivers/media/i2c/adv7175.c index d220af579a64..3f40304e856c 100644 --- a/drivers/media/i2c/adv7175.c +++ b/drivers/media/i2c/adv7175.c @@ -300,13 +300,14 @@ static int adv7175_s_routing(struct v4l2_subdev *sd, return 0; } -static int adv7175_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - u32 *code) +static int adv7175_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { - if (index >= ARRAY_SIZE(adv7175_codes)) + if (code->pad || code->index >= ARRAY_SIZE(adv7175_codes)) return -EINVAL; - *code = adv7175_codes[index]; + code->code = adv7175_codes[code->index]; return 0; } @@ -376,12 +377,16 @@ static const struct v4l2_subdev_video_ops adv7175_video_ops = { .s_routing = adv7175_s_routing, .s_mbus_fmt = adv7175_s_fmt, .g_mbus_fmt = adv7175_g_fmt, - .enum_mbus_fmt = adv7175_enum_fmt, +}; + +static const struct v4l2_subdev_pad_ops adv7175_pad_ops = { + .enum_mbus_code = adv7175_enum_mbus_code, }; static const struct v4l2_subdev_ops adv7175_ops = { .core = &adv7175_core_ops, .video = &adv7175_video_ops, + .pad = &adv7175_pad_ops, }; /* ----------------------------------------------------------------------- */ diff --git a/drivers/media/i2c/adv7183.c b/drivers/media/i2c/adv7183.c index 28940cc3a766..a0bcfefc28fc 100644 --- a/drivers/media/i2c/adv7183.c +++ b/drivers/media/i2c/adv7183.c @@ -420,13 +420,14 @@ static int adv7183_g_input_status(struct v4l2_subdev *sd, u32 *status) return 0; } -static int adv7183_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, - u32 *code) +static int adv7183_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { - if (index > 0) + if (code->pad || code->index > 0) return -EINVAL; - *code = MEDIA_BUS_FMT_UYVY8_2X8; + code->code = MEDIA_BUS_FMT_UYVY8_2X8; return 0; } @@ -514,16 +515,20 @@ static const struct v4l2_subdev_video_ops adv7183_video_ops = { .s_routing = adv7183_s_routing, .querystd = adv7183_querystd, .g_input_status = adv7183_g_input_status, - .enum_mbus_fmt = adv7183_enum_mbus_fmt, .try_mbus_fmt = adv7183_try_mbus_fmt, .s_mbus_fmt = adv7183_s_mbus_fmt, .g_mbus_fmt = adv7183_g_mbus_fmt, .s_stream = adv7183_s_stream, }; +static const struct v4l2_subdev_pad_ops adv7183_pad_ops = { + .enum_mbus_code = adv7183_enum_mbus_code, +}; + static const struct v4l2_subdev_ops adv7183_ops = { .core = &adv7183_core_ops, .video = &adv7183_video_ops, + .pad = &adv7183_pad_ops, }; static int adv7183_probe(struct i2c_client *client, diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index b5a37fe10a6a..644e910f9d8a 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -1867,13 +1867,14 @@ static int adv7842_s_routing(struct v4l2_subdev *sd, return 0; } -static int adv7842_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index, - u32 *code) +static int adv7842_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { - if (index) + if (code->pad || code->index) return -EINVAL; /* Good enough for now */ - *code = MEDIA_BUS_FMT_FIXED; + code->code = MEDIA_BUS_FMT_FIXED; return 0; } @@ -2809,7 +2810,6 @@ static const struct v4l2_subdev_video_ops adv7842_video_ops = { .s_dv_timings = adv7842_s_dv_timings, .g_dv_timings = adv7842_g_dv_timings, .query_dv_timings = adv7842_query_dv_timings, - .enum_mbus_fmt = adv7842_enum_mbus_fmt, .g_mbus_fmt = adv7842_g_mbus_fmt, .try_mbus_fmt = adv7842_g_mbus_fmt, .s_mbus_fmt = adv7842_g_mbus_fmt, @@ -2820,6 +2820,7 @@ static const struct v4l2_subdev_pad_ops adv7842_pad_ops = { .set_edid = adv7842_set_edid, .enum_dv_timings = adv7842_enum_dv_timings, .dv_timings_cap = adv7842_dv_timings_cap, + .enum_mbus_code = adv7842_enum_mbus_code, }; static const struct v4l2_subdev_ops adv7842_ops = { diff --git a/drivers/media/i2c/ak881x.c b/drivers/media/i2c/ak881x.c index 69aeaf397624..4428fb95d033 100644 --- a/drivers/media/i2c/ak881x.c +++ b/drivers/media/i2c/ak881x.c @@ -118,13 +118,14 @@ static int ak881x_s_mbus_fmt(struct v4l2_subdev *sd, return ak881x_try_g_mbus_fmt(sd, mf); } -static int ak881x_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index, - u32 *code) +static int ak881x_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { - if (index) + if (code->pad || code->index) return -EINVAL; - *code = MEDIA_BUS_FMT_YUYV8_2X8; + code->code = MEDIA_BUS_FMT_YUYV8_2X8; return 0; } @@ -215,14 +216,18 @@ static struct v4l2_subdev_video_ops ak881x_subdev_video_ops = { .g_mbus_fmt = ak881x_try_g_mbus_fmt, .try_mbus_fmt = ak881x_try_g_mbus_fmt, .cropcap = ak881x_cropcap, - .enum_mbus_fmt = ak881x_enum_mbus_fmt, .s_std_output = ak881x_s_std_output, .s_stream = ak881x_s_stream, }; +static const struct v4l2_subdev_pad_ops ak881x_subdev_pad_ops = { + .enum_mbus_code = ak881x_enum_mbus_code, +}; + static struct v4l2_subdev_ops ak881x_subdev_ops = { .core = &ak881x_subdev_core_ops, .video = &ak881x_subdev_video_ops, + .pad = &ak881x_subdev_pad_ops, }; static int ak881x_probe(struct i2c_client *client, diff --git a/drivers/media/i2c/ml86v7667.c b/drivers/media/i2c/ml86v7667.c index d7307862c2c5..e7b220239d30 100644 --- a/drivers/media/i2c/ml86v7667.c +++ b/drivers/media/i2c/ml86v7667.c @@ -191,13 +191,14 @@ static int ml86v7667_g_input_status(struct v4l2_subdev *sd, u32 *status) return 0; } -static int ml86v7667_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index, - u32 *code) +static int ml86v7667_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { - if (index > 0) + if (code->pad || code->index > 0) return -EINVAL; - *code = MEDIA_BUS_FMT_YUYV8_2X8; + code->code = MEDIA_BUS_FMT_YUYV8_2X8; return 0; } @@ -279,13 +280,16 @@ static struct v4l2_subdev_video_ops ml86v7667_subdev_video_ops = { .s_std = ml86v7667_s_std, .querystd = ml86v7667_querystd, .g_input_status = ml86v7667_g_input_status, - .enum_mbus_fmt = ml86v7667_enum_mbus_fmt, .try_mbus_fmt = ml86v7667_mbus_fmt, .g_mbus_fmt = ml86v7667_mbus_fmt, .s_mbus_fmt = ml86v7667_mbus_fmt, .g_mbus_config = ml86v7667_g_mbus_config, }; +static const struct v4l2_subdev_pad_ops ml86v7667_subdev_pad_ops = { + .enum_mbus_code = ml86v7667_enum_mbus_code, +}; + static struct v4l2_subdev_core_ops ml86v7667_subdev_core_ops = { #ifdef CONFIG_VIDEO_ADV_DEBUG .g_register = ml86v7667_g_register, @@ -296,6 +300,7 @@ static struct v4l2_subdev_core_ops ml86v7667_subdev_core_ops = { static struct v4l2_subdev_ops ml86v7667_subdev_ops = { .core = &ml86v7667_subdev_core_ops, .video = &ml86v7667_subdev_video_ops, + .pad = &ml86v7667_subdev_pad_ops, }; static int ml86v7667_init(struct ml86v7667_priv *priv) diff --git a/drivers/media/i2c/mt9v011.c b/drivers/media/i2c/mt9v011.c index a10f7f8f0558..6fae8fce4617 100644 --- a/drivers/media/i2c/mt9v011.c +++ b/drivers/media/i2c/mt9v011.c @@ -324,13 +324,14 @@ static int mt9v011_reset(struct v4l2_subdev *sd, u32 val) return 0; } -static int mt9v011_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, - u32 *code) +static int mt9v011_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { - if (index > 0) + if (code->pad || code->index > 0) return -EINVAL; - *code = MEDIA_BUS_FMT_SGRBG8_1X8; + code->code = MEDIA_BUS_FMT_SGRBG8_1X8; return 0; } @@ -469,16 +470,20 @@ static const struct v4l2_subdev_core_ops mt9v011_core_ops = { }; static const struct v4l2_subdev_video_ops mt9v011_video_ops = { - .enum_mbus_fmt = mt9v011_enum_mbus_fmt, .try_mbus_fmt = mt9v011_try_mbus_fmt, .s_mbus_fmt = mt9v011_s_mbus_fmt, .g_parm = mt9v011_g_parm, .s_parm = mt9v011_s_parm, }; +static const struct v4l2_subdev_pad_ops mt9v011_pad_ops = { + .enum_mbus_code = mt9v011_enum_mbus_code, +}; + static const struct v4l2_subdev_ops mt9v011_ops = { .core = &mt9v011_core_ops, .video = &mt9v011_video_ops, + .pad = &mt9v011_pad_ops, }; diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c index 394f416b3543..5511208c8308 100644 --- a/drivers/media/i2c/ov7670.c +++ b/drivers/media/i2c/ov7670.c @@ -899,13 +899,14 @@ static int ov7670_set_hw(struct v4l2_subdev *sd, int hstart, int hstop, } -static int ov7670_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, - u32 *code) +static int ov7670_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { - if (index >= N_OV7670_FMTS) + if (code->pad || code->index >= N_OV7670_FMTS) return -EINVAL; - *code = ov7670_formats[index].mbus_code; + code->code = ov7670_formats[code->index].mbus_code; return 0; } @@ -1508,7 +1509,6 @@ static const struct v4l2_subdev_core_ops ov7670_core_ops = { }; static const struct v4l2_subdev_video_ops ov7670_video_ops = { - .enum_mbus_fmt = ov7670_enum_mbus_fmt, .try_mbus_fmt = ov7670_try_mbus_fmt, .s_mbus_fmt = ov7670_s_mbus_fmt, .s_parm = ov7670_s_parm, @@ -1518,6 +1518,7 @@ static const struct v4l2_subdev_video_ops ov7670_video_ops = { static const struct v4l2_subdev_pad_ops ov7670_pad_ops = { .enum_frame_interval = ov7670_enum_frame_interval, .enum_frame_size = ov7670_enum_frame_size, + .enum_mbus_code = ov7670_enum_mbus_code, }; static const struct v4l2_subdev_ops ov7670_ops = { diff --git a/drivers/media/i2c/soc_camera/imx074.c b/drivers/media/i2c/soc_camera/imx074.c index ec89cfa927a2..7a2d90654fee 100644 --- a/drivers/media/i2c/soc_camera/imx074.c +++ b/drivers/media/i2c/soc_camera/imx074.c @@ -235,13 +235,15 @@ static int imx074_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) return 0; } -static int imx074_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - u32 *code) +static int imx074_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { - if ((unsigned int)index >= ARRAY_SIZE(imx074_colour_fmts)) + if (code->pad || + (unsigned int)code->index >= ARRAY_SIZE(imx074_colour_fmts)) return -EINVAL; - *code = imx074_colour_fmts[index].code; + code->code = imx074_colour_fmts[code->index].code; return 0; } @@ -278,7 +280,6 @@ static struct v4l2_subdev_video_ops imx074_subdev_video_ops = { .s_mbus_fmt = imx074_s_fmt, .g_mbus_fmt = imx074_g_fmt, .try_mbus_fmt = imx074_try_fmt, - .enum_mbus_fmt = imx074_enum_fmt, .g_crop = imx074_g_crop, .cropcap = imx074_cropcap, .g_mbus_config = imx074_g_mbus_config, @@ -288,9 +289,14 @@ static struct v4l2_subdev_core_ops imx074_subdev_core_ops = { .s_power = imx074_s_power, }; +static const struct v4l2_subdev_pad_ops imx074_subdev_pad_ops = { + .enum_mbus_code = imx074_enum_mbus_code, +}; + static struct v4l2_subdev_ops imx074_subdev_ops = { .core = &imx074_subdev_core_ops, .video = &imx074_subdev_video_ops, + .pad = &imx074_subdev_pad_ops, }; static int imx074_video_probe(struct i2c_client *client) diff --git a/drivers/media/i2c/soc_camera/mt9m001.c b/drivers/media/i2c/soc_camera/mt9m001.c index 2e9a53502551..ba18e010b9da 100644 --- a/drivers/media/i2c/soc_camera/mt9m001.c +++ b/drivers/media/i2c/soc_camera/mt9m001.c @@ -562,16 +562,17 @@ static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = { .s_power = mt9m001_s_power, }; -static int mt9m001_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - u32 *code) +static int mt9m001_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9m001 *mt9m001 = to_mt9m001(client); - if (index >= mt9m001->num_fmts) + if (code->pad || code->index >= mt9m001->num_fmts) return -EINVAL; - *code = mt9m001->fmts[index].code; + code->code = mt9m001->fmts[code->index].code; return 0; } @@ -617,7 +618,6 @@ static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = { .s_crop = mt9m001_s_crop, .g_crop = mt9m001_g_crop, .cropcap = mt9m001_cropcap, - .enum_mbus_fmt = mt9m001_enum_fmt, .g_mbus_config = mt9m001_g_mbus_config, .s_mbus_config = mt9m001_s_mbus_config, }; @@ -626,10 +626,15 @@ static struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = { .g_skip_top_lines = mt9m001_g_skip_top_lines, }; +static const struct v4l2_subdev_pad_ops mt9m001_subdev_pad_ops = { + .enum_mbus_code = mt9m001_enum_mbus_code, +}; + static struct v4l2_subdev_ops mt9m001_subdev_ops = { .core = &mt9m001_subdev_core_ops, .video = &mt9m001_subdev_video_ops, .sensor = &mt9m001_subdev_sensor_ops, + .pad = &mt9m001_subdev_pad_ops, }; static int mt9m001_probe(struct i2c_client *client, diff --git a/drivers/media/i2c/soc_camera/mt9m111.c b/drivers/media/i2c/soc_camera/mt9m111.c index 441e0fda24fe..b7731401dc39 100644 --- a/drivers/media/i2c/soc_camera/mt9m111.c +++ b/drivers/media/i2c/soc_camera/mt9m111.c @@ -839,13 +839,14 @@ static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = { #endif }; -static int mt9m111_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - u32 *code) +static int mt9m111_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { - if (index >= ARRAY_SIZE(mt9m111_colour_fmts)) + if (code->pad || code->index >= ARRAY_SIZE(mt9m111_colour_fmts)) return -EINVAL; - *code = mt9m111_colour_fmts[index].code; + code->code = mt9m111_colour_fmts[code->index].code; return 0; } @@ -871,13 +872,17 @@ static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = { .s_crop = mt9m111_s_crop, .g_crop = mt9m111_g_crop, .cropcap = mt9m111_cropcap, - .enum_mbus_fmt = mt9m111_enum_fmt, .g_mbus_config = mt9m111_g_mbus_config, }; +static const struct v4l2_subdev_pad_ops mt9m111_subdev_pad_ops = { + .enum_mbus_code = mt9m111_enum_mbus_code, +}; + static struct v4l2_subdev_ops mt9m111_subdev_ops = { .core = &mt9m111_subdev_core_ops, .video = &mt9m111_subdev_video_ops, + .pad = &mt9m111_subdev_pad_ops, }; /* diff --git a/drivers/media/i2c/soc_camera/mt9t031.c b/drivers/media/i2c/soc_camera/mt9t031.c index 35d9c8d25589..15ac4dc29967 100644 --- a/drivers/media/i2c/soc_camera/mt9t031.c +++ b/drivers/media/i2c/soc_camera/mt9t031.c @@ -672,13 +672,14 @@ static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = { #endif }; -static int mt9t031_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - u32 *code) +static int mt9t031_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { - if (index) + if (code->pad || code->index) return -EINVAL; - *code = MEDIA_BUS_FMT_SBGGR10_1X10; + code->code = MEDIA_BUS_FMT_SBGGR10_1X10; return 0; } @@ -718,7 +719,6 @@ static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = { .s_crop = mt9t031_s_crop, .g_crop = mt9t031_g_crop, .cropcap = mt9t031_cropcap, - .enum_mbus_fmt = mt9t031_enum_fmt, .g_mbus_config = mt9t031_g_mbus_config, .s_mbus_config = mt9t031_s_mbus_config, }; @@ -727,10 +727,15 @@ static struct v4l2_subdev_sensor_ops mt9t031_subdev_sensor_ops = { .g_skip_top_lines = mt9t031_g_skip_top_lines, }; +static const struct v4l2_subdev_pad_ops mt9t031_subdev_pad_ops = { + .enum_mbus_code = mt9t031_enum_mbus_code, +}; + static struct v4l2_subdev_ops mt9t031_subdev_ops = { .core = &mt9t031_subdev_core_ops, .video = &mt9t031_subdev_video_ops, .sensor = &mt9t031_subdev_sensor_ops, + .pad = &mt9t031_subdev_pad_ops, }; static int mt9t031_probe(struct i2c_client *client, diff --git a/drivers/media/i2c/soc_camera/mt9t112.c b/drivers/media/i2c/soc_camera/mt9t112.c index 64f08365e6b2..8b0cfb7f80b1 100644 --- a/drivers/media/i2c/soc_camera/mt9t112.c +++ b/drivers/media/i2c/soc_camera/mt9t112.c @@ -966,16 +966,17 @@ static int mt9t112_try_fmt(struct v4l2_subdev *sd, return 0; } -static int mt9t112_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - u32 *code) +static int mt9t112_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9t112_priv *priv = to_mt9t112(client); - if (index >= priv->num_formats) + if (code->pad || code->index >= priv->num_formats) return -EINVAL; - *code = mt9t112_cfmts[index].code; + code->code = mt9t112_cfmts[code->index].code; return 0; } @@ -1016,17 +1017,21 @@ static struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = { .cropcap = mt9t112_cropcap, .g_crop = mt9t112_g_crop, .s_crop = mt9t112_s_crop, - .enum_mbus_fmt = mt9t112_enum_fmt, .g_mbus_config = mt9t112_g_mbus_config, .s_mbus_config = mt9t112_s_mbus_config, }; +static const struct v4l2_subdev_pad_ops mt9t112_subdev_pad_ops = { + .enum_mbus_code = mt9t112_enum_mbus_code, +}; + /************************************************************************ i2c driver ************************************************************************/ static struct v4l2_subdev_ops mt9t112_subdev_ops = { .core = &mt9t112_subdev_core_ops, .video = &mt9t112_subdev_video_ops, + .pad = &mt9t112_subdev_pad_ops, }; static int mt9t112_camera_probe(struct i2c_client *client) diff --git a/drivers/media/i2c/soc_camera/mt9v022.c b/drivers/media/i2c/soc_camera/mt9v022.c index a246d4d64b8b..780c7ae74d69 100644 --- a/drivers/media/i2c/soc_camera/mt9v022.c +++ b/drivers/media/i2c/soc_camera/mt9v022.c @@ -758,16 +758,17 @@ static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = { .s_power = mt9v022_s_power, }; -static int mt9v022_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - u32 *code) +static int mt9v022_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9v022 *mt9v022 = to_mt9v022(client); - if (index >= mt9v022->num_fmts) + if (code->pad || code->index >= mt9v022->num_fmts) return -EINVAL; - *code = mt9v022->fmts[index].code; + code->code = mt9v022->fmts[code->index].code; return 0; } @@ -845,7 +846,6 @@ static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = { .s_crop = mt9v022_s_crop, .g_crop = mt9v022_g_crop, .cropcap = mt9v022_cropcap, - .enum_mbus_fmt = mt9v022_enum_fmt, .g_mbus_config = mt9v022_g_mbus_config, .s_mbus_config = mt9v022_s_mbus_config, }; @@ -854,10 +854,15 @@ static struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = { .g_skip_top_lines = mt9v022_g_skip_top_lines, }; +static const struct v4l2_subdev_pad_ops mt9v022_subdev_pad_ops = { + .enum_mbus_code = mt9v022_enum_mbus_code, +}; + static struct v4l2_subdev_ops mt9v022_subdev_ops = { .core = &mt9v022_subdev_core_ops, .video = &mt9v022_subdev_video_ops, .sensor = &mt9v022_subdev_sensor_ops, + .pad = &mt9v022_subdev_pad_ops, }; static int mt9v022_probe(struct i2c_client *client, diff --git a/drivers/media/i2c/soc_camera/ov2640.c b/drivers/media/i2c/soc_camera/ov2640.c index e3c907a97765..4327871c8f9f 100644 --- a/drivers/media/i2c/soc_camera/ov2640.c +++ b/drivers/media/i2c/soc_camera/ov2640.c @@ -925,13 +925,14 @@ static int ov2640_try_fmt(struct v4l2_subdev *sd, return 0; } -static int ov2640_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - u32 *code) +static int ov2640_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { - if (index >= ARRAY_SIZE(ov2640_codes)) + if (code->pad || code->index >= ARRAY_SIZE(ov2640_codes)) return -EINVAL; - *code = ov2640_codes[index]; + code->code = ov2640_codes[code->index]; return 0; } @@ -1036,13 +1037,17 @@ static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = { .try_mbus_fmt = ov2640_try_fmt, .cropcap = ov2640_cropcap, .g_crop = ov2640_g_crop, - .enum_mbus_fmt = ov2640_enum_fmt, .g_mbus_config = ov2640_g_mbus_config, }; +static const struct v4l2_subdev_pad_ops ov2640_subdev_pad_ops = { + .enum_mbus_code = ov2640_enum_mbus_code, +}; + static struct v4l2_subdev_ops ov2640_subdev_ops = { .core = &ov2640_subdev_core_ops, .video = &ov2640_subdev_video_ops, + .pad = &ov2640_subdev_pad_ops, }; /* OF probe functions */ diff --git a/drivers/media/i2c/soc_camera/ov5642.c b/drivers/media/i2c/soc_camera/ov5642.c index 93ae031bdafb..fcddd0ded2e3 100644 --- a/drivers/media/i2c/soc_camera/ov5642.c +++ b/drivers/media/i2c/soc_camera/ov5642.c @@ -839,13 +839,14 @@ static int ov5642_g_fmt(struct v4l2_subdev *sd, return 0; } -static int ov5642_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - u32 *code) +static int ov5642_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { - if (index >= ARRAY_SIZE(ov5642_colour_fmts)) + if (code->pad || code->index >= ARRAY_SIZE(ov5642_colour_fmts)) return -EINVAL; - *code = ov5642_colour_fmts[index].code; + code->code = ov5642_colour_fmts[code->index].code; return 0; } @@ -942,13 +943,16 @@ static struct v4l2_subdev_video_ops ov5642_subdev_video_ops = { .s_mbus_fmt = ov5642_s_fmt, .g_mbus_fmt = ov5642_g_fmt, .try_mbus_fmt = ov5642_try_fmt, - .enum_mbus_fmt = ov5642_enum_fmt, .s_crop = ov5642_s_crop, .g_crop = ov5642_g_crop, .cropcap = ov5642_cropcap, .g_mbus_config = ov5642_g_mbus_config, }; +static const struct v4l2_subdev_pad_ops ov5642_subdev_pad_ops = { + .enum_mbus_code = ov5642_enum_mbus_code, +}; + static struct v4l2_subdev_core_ops ov5642_subdev_core_ops = { .s_power = ov5642_s_power, #ifdef CONFIG_VIDEO_ADV_DEBUG @@ -960,6 +964,7 @@ static struct v4l2_subdev_core_ops ov5642_subdev_core_ops = { static struct v4l2_subdev_ops ov5642_subdev_ops = { .core = &ov5642_subdev_core_ops, .video = &ov5642_subdev_video_ops, + .pad = &ov5642_subdev_pad_ops, }; static int ov5642_video_probe(struct i2c_client *client) diff --git a/drivers/media/i2c/soc_camera/ov6650.c b/drivers/media/i2c/soc_camera/ov6650.c index f4eef2fa6f6f..99e0738fdb38 100644 --- a/drivers/media/i2c/soc_camera/ov6650.c +++ b/drivers/media/i2c/soc_camera/ov6650.c @@ -716,13 +716,14 @@ static int ov6650_try_fmt(struct v4l2_subdev *sd, return 0; } -static int ov6650_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - u32 *code) +static int ov6650_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { - if (index >= ARRAY_SIZE(ov6650_codes)) + if (code->pad || code->index >= ARRAY_SIZE(ov6650_codes)) return -EINVAL; - *code = ov6650_codes[index]; + code->code = ov6650_codes[code->index]; return 0; } @@ -932,7 +933,6 @@ static struct v4l2_subdev_video_ops ov6650_video_ops = { .g_mbus_fmt = ov6650_g_fmt, .s_mbus_fmt = ov6650_s_fmt, .try_mbus_fmt = ov6650_try_fmt, - .enum_mbus_fmt = ov6650_enum_fmt, .cropcap = ov6650_cropcap, .g_crop = ov6650_g_crop, .s_crop = ov6650_s_crop, @@ -942,9 +942,14 @@ static struct v4l2_subdev_video_ops ov6650_video_ops = { .s_mbus_config = ov6650_s_mbus_config, }; +static const struct v4l2_subdev_pad_ops ov6650_pad_ops = { + .enum_mbus_code = ov6650_enum_mbus_code, +}; + static struct v4l2_subdev_ops ov6650_subdev_ops = { .core = &ov6650_core_ops, .video = &ov6650_video_ops, + .pad = &ov6650_pad_ops, }; /* diff --git a/drivers/media/i2c/soc_camera/ov772x.c b/drivers/media/i2c/soc_camera/ov772x.c index 8daac88b33fe..e3a31f806636 100644 --- a/drivers/media/i2c/soc_camera/ov772x.c +++ b/drivers/media/i2c/soc_camera/ov772x.c @@ -989,13 +989,14 @@ static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = { .s_power = ov772x_s_power, }; -static int ov772x_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - u32 *code) +static int ov772x_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { - if (index >= ARRAY_SIZE(ov772x_cfmts)) + if (code->pad || code->index >= ARRAY_SIZE(ov772x_cfmts)) return -EINVAL; - *code = ov772x_cfmts[index].code; + code->code = ov772x_cfmts[code->index].code; return 0; } @@ -1021,13 +1022,17 @@ static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = { .try_mbus_fmt = ov772x_try_fmt, .cropcap = ov772x_cropcap, .g_crop = ov772x_g_crop, - .enum_mbus_fmt = ov772x_enum_fmt, .g_mbus_config = ov772x_g_mbus_config, }; +static const struct v4l2_subdev_pad_ops ov772x_subdev_pad_ops = { + .enum_mbus_code = ov772x_enum_mbus_code, +}; + static struct v4l2_subdev_ops ov772x_subdev_ops = { .core = &ov772x_subdev_core_ops, .video = &ov772x_subdev_video_ops, + .pad = &ov772x_subdev_pad_ops, }; /* diff --git a/drivers/media/i2c/soc_camera/ov9640.c b/drivers/media/i2c/soc_camera/ov9640.c index aa93d2e88572..899b4d9352fe 100644 --- a/drivers/media/i2c/soc_camera/ov9640.c +++ b/drivers/media/i2c/soc_camera/ov9640.c @@ -540,13 +540,14 @@ static int ov9640_try_fmt(struct v4l2_subdev *sd, return 0; } -static int ov9640_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - u32 *code) +static int ov9640_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { - if (index >= ARRAY_SIZE(ov9640_codes)) + if (code->pad || code->index >= ARRAY_SIZE(ov9640_codes)) return -EINVAL; - *code = ov9640_codes[index]; + code->code = ov9640_codes[code->index]; return 0; } @@ -658,15 +659,19 @@ static struct v4l2_subdev_video_ops ov9640_video_ops = { .s_stream = ov9640_s_stream, .s_mbus_fmt = ov9640_s_fmt, .try_mbus_fmt = ov9640_try_fmt, - .enum_mbus_fmt = ov9640_enum_fmt, .cropcap = ov9640_cropcap, .g_crop = ov9640_g_crop, .g_mbus_config = ov9640_g_mbus_config, }; +static const struct v4l2_subdev_pad_ops ov9640_pad_ops = { + .enum_mbus_code = ov9640_enum_mbus_code, +}; + static struct v4l2_subdev_ops ov9640_subdev_ops = { .core = &ov9640_core_ops, .video = &ov9640_video_ops, + .pad = &ov9640_pad_ops, }; /* diff --git a/drivers/media/i2c/soc_camera/ov9740.c b/drivers/media/i2c/soc_camera/ov9740.c index 841dc55457cf..5d9b2492b7d2 100644 --- a/drivers/media/i2c/soc_camera/ov9740.c +++ b/drivers/media/i2c/soc_camera/ov9740.c @@ -716,13 +716,14 @@ static int ov9740_try_fmt(struct v4l2_subdev *sd, return 0; } -static int ov9740_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - u32 *code) +static int ov9740_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { - if (index >= ARRAY_SIZE(ov9740_codes)) + if (code->pad || code->index >= ARRAY_SIZE(ov9740_codes)) return -EINVAL; - *code = ov9740_codes[index]; + code->code = ov9740_codes[code->index]; return 0; } @@ -906,7 +907,6 @@ static struct v4l2_subdev_video_ops ov9740_video_ops = { .s_stream = ov9740_s_stream, .s_mbus_fmt = ov9740_s_fmt, .try_mbus_fmt = ov9740_try_fmt, - .enum_mbus_fmt = ov9740_enum_fmt, .cropcap = ov9740_cropcap, .g_crop = ov9740_g_crop, .g_mbus_config = ov9740_g_mbus_config, @@ -920,9 +920,14 @@ static struct v4l2_subdev_core_ops ov9740_core_ops = { #endif }; +static const struct v4l2_subdev_pad_ops ov9740_pad_ops = { + .enum_mbus_code = ov9740_enum_mbus_code, +}; + static struct v4l2_subdev_ops ov9740_subdev_ops = { - .core = &ov9740_core_ops, - .video = &ov9740_video_ops, + .core = &ov9740_core_ops, + .video = &ov9740_video_ops, + .pad = &ov9740_pad_ops, }; static const struct v4l2_ctrl_ops ov9740_ctrl_ops = { diff --git a/drivers/media/i2c/soc_camera/rj54n1cb0c.c b/drivers/media/i2c/soc_camera/rj54n1cb0c.c index 1752428c43c5..4927a76d2240 100644 --- a/drivers/media/i2c/soc_camera/rj54n1cb0c.c +++ b/drivers/media/i2c/soc_camera/rj54n1cb0c.c @@ -485,13 +485,14 @@ static int reg_write_multiple(struct i2c_client *client, return 0; } -static int rj54n1_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - u32 *code) +static int rj54n1_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { - if (index >= ARRAY_SIZE(rj54n1_colour_fmts)) + if (code->pad || code->index >= ARRAY_SIZE(rj54n1_colour_fmts)) return -EINVAL; - *code = rj54n1_colour_fmts[index].code; + code->code = rj54n1_colour_fmts[code->index].code; return 0; } @@ -1252,7 +1253,6 @@ static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = { .s_mbus_fmt = rj54n1_s_fmt, .g_mbus_fmt = rj54n1_g_fmt, .try_mbus_fmt = rj54n1_try_fmt, - .enum_mbus_fmt = rj54n1_enum_fmt, .g_crop = rj54n1_g_crop, .s_crop = rj54n1_s_crop, .cropcap = rj54n1_cropcap, @@ -1260,9 +1260,14 @@ static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = { .s_mbus_config = rj54n1_s_mbus_config, }; +static const struct v4l2_subdev_pad_ops rj54n1_subdev_pad_ops = { + .enum_mbus_code = rj54n1_enum_mbus_code, +}; + static struct v4l2_subdev_ops rj54n1_subdev_ops = { .core = &rj54n1_subdev_core_ops, .video = &rj54n1_subdev_video_ops, + .pad = &rj54n1_subdev_pad_ops, }; /* diff --git a/drivers/media/i2c/soc_camera/tw9910.c b/drivers/media/i2c/soc_camera/tw9910.c index 9b853215d146..f8c0c713d06c 100644 --- a/drivers/media/i2c/soc_camera/tw9910.c +++ b/drivers/media/i2c/soc_camera/tw9910.c @@ -821,13 +821,14 @@ static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = { .s_power = tw9910_s_power, }; -static int tw9910_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - u32 *code) +static int tw9910_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { - if (index) + if (code->pad || code->index) return -EINVAL; - *code = MEDIA_BUS_FMT_UYVY8_2X8; + code->code = MEDIA_BUS_FMT_UYVY8_2X8; return 0; } @@ -885,15 +886,19 @@ static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = { .try_mbus_fmt = tw9910_try_fmt, .cropcap = tw9910_cropcap, .g_crop = tw9910_g_crop, - .enum_mbus_fmt = tw9910_enum_fmt, .g_mbus_config = tw9910_g_mbus_config, .s_mbus_config = tw9910_s_mbus_config, .g_tvnorms = tw9910_g_tvnorms, }; +static const struct v4l2_subdev_pad_ops tw9910_subdev_pad_ops = { + .enum_mbus_code = tw9910_enum_mbus_code, +}; + static struct v4l2_subdev_ops tw9910_subdev_ops = { .core = &tw9910_subdev_core_ops, .video = &tw9910_subdev_video_ops, + .pad = &tw9910_subdev_pad_ops, }; /* diff --git a/drivers/media/i2c/sr030pc30.c b/drivers/media/i2c/sr030pc30.c index 10c735c3a082..0a0a1886ee4c 100644 --- a/drivers/media/i2c/sr030pc30.c +++ b/drivers/media/i2c/sr030pc30.c @@ -471,13 +471,15 @@ static int sr030pc30_s_ctrl(struct v4l2_ctrl *ctrl) return 0; } -static int sr030pc30_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - u32 *code) +static int sr030pc30_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { - if (!code || index >= ARRAY_SIZE(sr030pc30_formats)) + if (!code || code->pad || + code->index >= ARRAY_SIZE(sr030pc30_formats)) return -EINVAL; - *code = sr030pc30_formats[index].code; + code->code = sr030pc30_formats[code->index].code; return 0; } @@ -640,12 +642,16 @@ static const struct v4l2_subdev_video_ops sr030pc30_video_ops = { .g_mbus_fmt = sr030pc30_g_fmt, .s_mbus_fmt = sr030pc30_s_fmt, .try_mbus_fmt = sr030pc30_try_fmt, - .enum_mbus_fmt = sr030pc30_enum_fmt, +}; + +static const struct v4l2_subdev_pad_ops sr030pc30_pad_ops = { + .enum_mbus_code = sr030pc30_enum_mbus_code, }; static const struct v4l2_subdev_ops sr030pc30_ops = { .core = &sr030pc30_core_ops, .video = &sr030pc30_video_ops, + .pad = &sr030pc30_pad_ops, }; /* diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c index 1c6bc306ecdc..a822d1541614 100644 --- a/drivers/media/i2c/tvp514x.c +++ b/drivers/media/i2c/tvp514x.c @@ -746,25 +746,6 @@ static int tvp514x_s_ctrl(struct v4l2_ctrl *ctrl) return err; } -/** - * tvp514x_enum_mbus_fmt() - V4L2 decoder interface handler for enum_mbus_fmt - * @sd: pointer to standard V4L2 sub-device structure - * @index: index of pixelcode to retrieve - * @code: receives the pixelcode - * - * Enumerates supported mediabus formats - */ -static int -tvp514x_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, - u32 *code) -{ - if (index) - return -EINVAL; - - *code = MEDIA_BUS_FMT_YUYV10_2X10; - return 0; -} - /** * tvp514x_mbus_fmt() - V4L2 decoder interface handler for try/s/g_mbus_fmt * @sd: pointer to standard V4L2 sub-device structure @@ -1016,7 +997,6 @@ static const struct v4l2_subdev_video_ops tvp514x_video_ops = { .s_std = tvp514x_s_std, .s_routing = tvp514x_s_routing, .querystd = tvp514x_querystd, - .enum_mbus_fmt = tvp514x_enum_mbus_fmt, .g_mbus_fmt = tvp514x_mbus_fmt, .try_mbus_fmt = tvp514x_mbus_fmt, .s_mbus_fmt = tvp514x_mbus_fmt, diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c index 68cdab9c0903..f2f87b73184c 100644 --- a/drivers/media/i2c/tvp5150.c +++ b/drivers/media/i2c/tvp5150.c @@ -817,13 +817,14 @@ static v4l2_std_id tvp5150_read_std(struct v4l2_subdev *sd) } } -static int tvp5150_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, - u32 *code) +static int tvp5150_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { - if (index) + if (code->pad || code->index) return -EINVAL; - *code = MEDIA_BUS_FMT_UYVY8_2X8; + code->code = MEDIA_BUS_FMT_UYVY8_2X8; return 0; } @@ -1068,7 +1069,6 @@ static const struct v4l2_subdev_tuner_ops tvp5150_tuner_ops = { static const struct v4l2_subdev_video_ops tvp5150_video_ops = { .s_std = tvp5150_s_std, .s_routing = tvp5150_s_routing, - .enum_mbus_fmt = tvp5150_enum_mbus_fmt, .s_mbus_fmt = tvp5150_mbus_fmt, .try_mbus_fmt = tvp5150_mbus_fmt, .g_mbus_fmt = tvp5150_mbus_fmt, @@ -1084,11 +1084,16 @@ static const struct v4l2_subdev_vbi_ops tvp5150_vbi_ops = { .s_raw_fmt = tvp5150_s_raw_fmt, }; +static const struct v4l2_subdev_pad_ops tvp5150_pad_ops = { + .enum_mbus_code = tvp5150_enum_mbus_code, +}; + static const struct v4l2_subdev_ops tvp5150_ops = { .core = &tvp5150_core_ops, .tuner = &tvp5150_tuner_ops, .video = &tvp5150_video_ops, .vbi = &tvp5150_vbi_ops, + .pad = &tvp5150_pad_ops, }; diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c index 787cdfb08749..d21fa1a62e41 100644 --- a/drivers/media/i2c/tvp7002.c +++ b/drivers/media/i2c/tvp7002.c @@ -746,25 +746,6 @@ static int tvp7002_s_register(struct v4l2_subdev *sd, } #endif -/* - * tvp7002_enum_mbus_fmt() - Enum supported mediabus formats - * @sd: pointer to standard V4L2 sub-device structure - * @index: format index - * @code: pointer to mediabus format - * - * Enumerate supported mediabus formats. - */ - -static int tvp7002_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, - u32 *code) -{ - /* Check requested format index is within range */ - if (index) - return -EINVAL; - *code = MEDIA_BUS_FMT_YUYV10_1X20; - return 0; -} - /* * tvp7002_s_stream() - V4L2 decoder i/f handler for s_stream * @sd: pointer to standard V4L2 sub-device structure @@ -927,7 +908,6 @@ static const struct v4l2_subdev_video_ops tvp7002_video_ops = { .g_mbus_fmt = tvp7002_mbus_fmt, .try_mbus_fmt = tvp7002_mbus_fmt, .s_mbus_fmt = tvp7002_mbus_fmt, - .enum_mbus_fmt = tvp7002_enum_mbus_fmt, }; /* media pad related operation handlers */ diff --git a/drivers/media/i2c/vs6624.c b/drivers/media/i2c/vs6624.c index 00e7f043977e..b1d0a1b28ca8 100644 --- a/drivers/media/i2c/vs6624.c +++ b/drivers/media/i2c/vs6624.c @@ -557,13 +557,14 @@ static int vs6624_s_ctrl(struct v4l2_ctrl *ctrl) return 0; } -static int vs6624_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, - u32 *code) +static int vs6624_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { - if (index >= ARRAY_SIZE(vs6624_formats)) + if (code->pad || code->index >= ARRAY_SIZE(vs6624_formats)) return -EINVAL; - *code = vs6624_formats[index].mbus_code; + code->code = vs6624_formats[code->index].mbus_code; return 0; } @@ -738,7 +739,6 @@ static const struct v4l2_subdev_core_ops vs6624_core_ops = { }; static const struct v4l2_subdev_video_ops vs6624_video_ops = { - .enum_mbus_fmt = vs6624_enum_mbus_fmt, .try_mbus_fmt = vs6624_try_mbus_fmt, .s_mbus_fmt = vs6624_s_mbus_fmt, .g_mbus_fmt = vs6624_g_mbus_fmt, @@ -747,9 +747,14 @@ static const struct v4l2_subdev_video_ops vs6624_video_ops = { .s_stream = vs6624_s_stream, }; +static const struct v4l2_subdev_pad_ops vs6624_pad_ops = { + .enum_mbus_code = vs6624_enum_mbus_code, +}; + static const struct v4l2_subdev_ops vs6624_ops = { .core = &vs6624_core_ops, .video = &vs6624_video_ops, + .pad = &vs6624_pad_ops, }; static int vs6624_probe(struct i2c_client *client, diff --git a/drivers/media/platform/blackfin/bfin_capture.c b/drivers/media/platform/blackfin/bfin_capture.c index 6a437f86dcdc..6ea11b1e755e 100644 --- a/drivers/media/platform/blackfin/bfin_capture.c +++ b/drivers/media/platform/blackfin/bfin_capture.c @@ -156,14 +156,18 @@ static struct bcap_buffer *to_bcap_vb(struct vb2_buffer *vb) static int bcap_init_sensor_formats(struct bcap_device *bcap_dev) { - u32 code; + struct v4l2_subdev_mbus_code_enum code = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; struct bcap_format *sf; unsigned int num_formats = 0; int i, j; - while (!v4l2_subdev_call(bcap_dev->sd, video, - enum_mbus_fmt, num_formats, &code)) + while (!v4l2_subdev_call(bcap_dev->sd, pad, + enum_mbus_code, NULL, &code)) { num_formats++; + code.index++; + } if (!num_formats) return -ENXIO; @@ -172,10 +176,11 @@ static int bcap_init_sensor_formats(struct bcap_device *bcap_dev) return -ENOMEM; for (i = 0; i < num_formats; i++) { - v4l2_subdev_call(bcap_dev->sd, video, - enum_mbus_fmt, i, &code); + code.index = i; + v4l2_subdev_call(bcap_dev->sd, pad, + enum_mbus_code, NULL, &code); for (j = 0; j < BCAP_MAX_FMTS; j++) - if (code == bcap_formats[j].mbus_code) + if (code.code == bcap_formats[j].mbus_code) break; if (j == BCAP_MAX_FMTS) { /* we don't allow this sensor working with our bridge */ diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index c835beb2a1a8..cbb7e22cab40 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -648,19 +648,22 @@ static int isi_camera_get_formats(struct soc_camera_device *icd, struct v4l2_subdev *sd = soc_camera_to_subdev(icd); int formats = 0, ret; /* sensor format */ - u32 code; + struct v4l2_subdev_mbus_code_enum code = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .index = idx, + }; /* soc camera host format */ const struct soc_mbus_pixelfmt *fmt; - ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); + ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code); if (ret < 0) /* No more formats */ return 0; - fmt = soc_mbus_get_fmtdesc(code); + fmt = soc_mbus_get_fmtdesc(code.code); if (!fmt) { dev_err(icd->parent, - "Invalid format code #%u: %d\n", idx, code); + "Invalid format code #%u: %d\n", idx, code.code); return 0; } @@ -672,7 +675,7 @@ static int isi_camera_get_formats(struct soc_camera_device *icd, return 0; } - switch (code) { + switch (code.code) { case MEDIA_BUS_FMT_UYVY8_2X8: case MEDIA_BUS_FMT_VYUY8_2X8: case MEDIA_BUS_FMT_YUYV8_2X8: @@ -680,10 +683,10 @@ static int isi_camera_get_formats(struct soc_camera_device *icd, formats++; if (xlate) { xlate->host_fmt = &isi_camera_formats[0]; - xlate->code = code; + xlate->code = code.code; xlate++; dev_dbg(icd->parent, "Providing format %s using code %d\n", - isi_camera_formats[0].name, code); + isi_camera_formats[0].name, code.code); } break; default: @@ -699,7 +702,7 @@ static int isi_camera_get_formats(struct soc_camera_device *icd, formats++; if (xlate) { xlate->host_fmt = fmt; - xlate->code = code; + xlate->code = code.code; xlate++; } diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c index 192377f55840..b891b7f2b7e9 100644 --- a/drivers/media/platform/soc_camera/mx2_camera.c +++ b/drivers/media/platform/soc_camera/mx2_camera.c @@ -943,22 +943,25 @@ static int mx2_camera_get_formats(struct soc_camera_device *icd, struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_mbus_pixelfmt *fmt; struct device *dev = icd->parent; - u32 code; + struct v4l2_subdev_mbus_code_enum code = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .index = idx, + }; int ret, formats = 0; - ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); + ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code); if (ret < 0) /* no more formats */ return 0; - fmt = soc_mbus_get_fmtdesc(code); + fmt = soc_mbus_get_fmtdesc(code.code); if (!fmt) { - dev_err(dev, "Invalid format code #%u: %d\n", idx, code); + dev_err(dev, "Invalid format code #%u: %d\n", idx, code.code); return 0; } - if (code == MEDIA_BUS_FMT_YUYV8_2X8 || - code == MEDIA_BUS_FMT_UYVY8_2X8) { + if (code.code == MEDIA_BUS_FMT_YUYV8_2X8 || + code.code == MEDIA_BUS_FMT_UYVY8_2X8) { formats++; if (xlate) { /* @@ -967,21 +970,21 @@ static int mx2_camera_get_formats(struct soc_camera_device *icd, */ xlate->host_fmt = soc_mbus_get_fmtdesc(MEDIA_BUS_FMT_YUYV8_1_5X8); - xlate->code = code; + xlate->code = code.code; dev_dbg(dev, "Providing host format %s for sensor code %d\n", - xlate->host_fmt->name, code); + xlate->host_fmt->name, code.code); xlate++; } } - if (code == MEDIA_BUS_FMT_UYVY8_2X8) { + if (code.code == MEDIA_BUS_FMT_UYVY8_2X8) { formats++; if (xlate) { xlate->host_fmt = soc_mbus_get_fmtdesc(MEDIA_BUS_FMT_YUYV8_2X8); - xlate->code = code; + xlate->code = code.code; dev_dbg(dev, "Providing host format %s for sensor code %d\n", - xlate->host_fmt->name, code); + xlate->host_fmt->name, code.code); xlate++; } } @@ -990,7 +993,7 @@ static int mx2_camera_get_formats(struct soc_camera_device *icd, formats++; if (xlate) { xlate->host_fmt = fmt; - xlate->code = code; + xlate->code = code.code; xlate++; } return formats; diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c index 3435fd2ca8ec..a29848976f92 100644 --- a/drivers/media/platform/soc_camera/mx3_camera.c +++ b/drivers/media/platform/soc_camera/mx3_camera.c @@ -659,18 +659,21 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, unsigned int id struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct device *dev = icd->parent; int formats = 0, ret; - u32 code; + struct v4l2_subdev_mbus_code_enum code = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .index = idx, + }; const struct soc_mbus_pixelfmt *fmt; - ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); + ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code); if (ret < 0) /* No more formats */ return 0; - fmt = soc_mbus_get_fmtdesc(code); + fmt = soc_mbus_get_fmtdesc(code.code); if (!fmt) { dev_warn(icd->parent, - "Unsupported format code #%u: 0x%x\n", idx, code); + "Unsupported format code #%u: 0x%x\n", idx, code.code); return 0; } @@ -679,25 +682,25 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, unsigned int id if (ret < 0) return 0; - switch (code) { + switch (code.code) { case MEDIA_BUS_FMT_SBGGR10_1X10: formats++; if (xlate) { xlate->host_fmt = &mx3_camera_formats[0]; - xlate->code = code; + xlate->code = code.code; xlate++; dev_dbg(dev, "Providing format %s using code 0x%x\n", - mx3_camera_formats[0].name, code); + mx3_camera_formats[0].name, code.code); } break; case MEDIA_BUS_FMT_Y10_1X10: formats++; if (xlate) { xlate->host_fmt = &mx3_camera_formats[1]; - xlate->code = code; + xlate->code = code.code; xlate++; dev_dbg(dev, "Providing format %s using code 0x%x\n", - mx3_camera_formats[1].name, code); + mx3_camera_formats[1].name, code.code); } break; default: @@ -709,7 +712,7 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, unsigned int id formats++; if (xlate) { xlate->host_fmt = fmt; - xlate->code = code; + xlate->code = code.code; dev_dbg(dev, "Providing format %c%c%c%c in pass-through mode\n", (fmt->fourcc >> (0*8)) & 0xFF, (fmt->fourcc >> (1*8)) & 0xFF, diff --git a/drivers/media/platform/soc_camera/omap1_camera.c b/drivers/media/platform/soc_camera/omap1_camera.c index 16f65ecb70a3..3f250767d162 100644 --- a/drivers/media/platform/soc_camera/omap1_camera.c +++ b/drivers/media/platform/soc_camera/omap1_camera.c @@ -1068,18 +1068,21 @@ static int omap1_cam_get_formats(struct soc_camera_device *icd, struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct device *dev = icd->parent; int formats = 0, ret; - u32 code; + struct v4l2_subdev_mbus_code_enum code = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .index = idx, + }; const struct soc_mbus_pixelfmt *fmt; - ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); + ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code); if (ret < 0) /* No more formats */ return 0; - fmt = soc_mbus_get_fmtdesc(code); + fmt = soc_mbus_get_fmtdesc(code.code); if (!fmt) { dev_warn(dev, "%s: unsupported format code #%d: %d\n", __func__, - idx, code); + idx, code.code); return 0; } @@ -1087,7 +1090,7 @@ static int omap1_cam_get_formats(struct soc_camera_device *icd, if (fmt->bits_per_sample != 8) return 0; - switch (code) { + switch (code.code) { case MEDIA_BUS_FMT_YUYV8_2X8: case MEDIA_BUS_FMT_YVYU8_2X8: case MEDIA_BUS_FMT_UYVY8_2X8: @@ -1098,14 +1101,14 @@ static int omap1_cam_get_formats(struct soc_camera_device *icd, case MEDIA_BUS_FMT_RGB565_2X8_LE: formats++; if (xlate) { - xlate->host_fmt = soc_mbus_find_fmtdesc(code, + xlate->host_fmt = soc_mbus_find_fmtdesc(code.code, omap1_cam_formats, ARRAY_SIZE(omap1_cam_formats)); - xlate->code = code; + xlate->code = code.code; xlate++; dev_dbg(dev, "%s: providing format %s as byte swapped code #%d\n", - __func__, xlate->host_fmt->name, code); + __func__, xlate->host_fmt->name, code.code); } default: if (xlate) @@ -1116,7 +1119,7 @@ static int omap1_cam_get_formats(struct soc_camera_device *icd, formats++; if (xlate) { xlate->host_fmt = fmt; - xlate->code = code; + xlate->code = code.code; xlate++; } diff --git a/drivers/media/platform/soc_camera/pxa_camera.c b/drivers/media/platform/soc_camera/pxa_camera.c index 8d6e343fec0f..f6fa0acc5251 100644 --- a/drivers/media/platform/soc_camera/pxa_camera.c +++ b/drivers/media/platform/soc_camera/pxa_camera.c @@ -1253,17 +1253,20 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, unsigned int id struct device *dev = icd->parent; int formats = 0, ret; struct pxa_cam *cam; - u32 code; + struct v4l2_subdev_mbus_code_enum code = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .index = idx, + }; const struct soc_mbus_pixelfmt *fmt; - ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); + ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code); if (ret < 0) /* No more formats */ return 0; - fmt = soc_mbus_get_fmtdesc(code); + fmt = soc_mbus_get_fmtdesc(code.code); if (!fmt) { - dev_err(dev, "Invalid format code #%u: %d\n", idx, code); + dev_err(dev, "Invalid format code #%u: %d\n", idx, code.code); return 0; } @@ -1282,15 +1285,15 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, unsigned int id cam = icd->host_priv; } - switch (code) { + switch (code.code) { case MEDIA_BUS_FMT_UYVY8_2X8: formats++; if (xlate) { xlate->host_fmt = &pxa_camera_formats[0]; - xlate->code = code; + xlate->code = code.code; xlate++; dev_dbg(dev, "Providing format %s using code %d\n", - pxa_camera_formats[0].name, code); + pxa_camera_formats[0].name, code.code); } case MEDIA_BUS_FMT_VYUY8_2X8: case MEDIA_BUS_FMT_YUYV8_2X8: @@ -1314,7 +1317,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, unsigned int id formats++; if (xlate) { xlate->host_fmt = fmt; - xlate->code = code; + xlate->code = code.code; xlate++; } diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c index 9351f64dee7b..8796bdce671f 100644 --- a/drivers/media/platform/soc_camera/rcar_vin.c +++ b/drivers/media/platform/soc_camera/rcar_vin.c @@ -1318,16 +1318,19 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx, int ret, k, n; int formats = 0; struct rcar_vin_cam *cam; - u32 code; + struct v4l2_subdev_mbus_code_enum code = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .index = idx, + }; const struct soc_mbus_pixelfmt *fmt; - ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); + ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code); if (ret < 0) return 0; - fmt = soc_mbus_get_fmtdesc(code); + fmt = soc_mbus_get_fmtdesc(code.code); if (!fmt) { - dev_warn(dev, "unsupported format code #%u: %d\n", idx, code); + dev_warn(dev, "unsupported format code #%u: %d\n", idx, code.code); return 0; } @@ -1408,7 +1411,7 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx, if (!idx) cam->extra_fmt = NULL; - switch (code) { + switch (code.code) { case MEDIA_BUS_FMT_YUYV8_1X16: case MEDIA_BUS_FMT_YUYV8_2X8: case MEDIA_BUS_FMT_YUYV10_2X10: @@ -1422,9 +1425,9 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx, formats += n; for (k = 0; xlate && k < n; k++, xlate++) { xlate->host_fmt = &rcar_vin_formats[k]; - xlate->code = code; + xlate->code = code.code; dev_dbg(dev, "Providing format %s using code %d\n", - rcar_vin_formats[k].name, code); + rcar_vin_formats[k].name, code.code); } break; default: @@ -1440,7 +1443,7 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx, formats++; if (xlate) { xlate->host_fmt = fmt; - xlate->code = code; + xlate->code = code.code; xlate++; } diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 9ce202f53934..b4faf8f1fd15 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -1048,17 +1048,20 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int int ret, k, n; int formats = 0; struct sh_mobile_ceu_cam *cam; - u32 code; + struct v4l2_subdev_mbus_code_enum code = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .index = idx, + }; const struct soc_mbus_pixelfmt *fmt; - ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); + ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code); if (ret < 0) /* No more formats */ return 0; - fmt = soc_mbus_get_fmtdesc(code); + fmt = soc_mbus_get_fmtdesc(code.code); if (!fmt) { - dev_warn(dev, "unsupported format code #%u: %d\n", idx, code); + dev_warn(dev, "unsupported format code #%u: %d\n", idx, code.code); return 0; } @@ -1140,7 +1143,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int if (!idx) cam->extra_fmt = NULL; - switch (code) { + switch (code.code) { case MEDIA_BUS_FMT_UYVY8_2X8: case MEDIA_BUS_FMT_VYUY8_2X8: case MEDIA_BUS_FMT_YUYV8_2X8: @@ -1163,10 +1166,10 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int formats += n; for (k = 0; xlate && k < n; k++) { xlate->host_fmt = &sh_mobile_ceu_formats[k]; - xlate->code = code; + xlate->code = code.code; xlate++; dev_dbg(dev, "Providing format %s using code %d\n", - sh_mobile_ceu_formats[k].name, code); + sh_mobile_ceu_formats[k].name, code.code); } break; default: @@ -1178,7 +1181,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int formats++; if (xlate) { xlate->host_fmt = fmt; - xlate->code = code; + xlate->code = code.code; xlate++; dev_dbg(dev, "Providing format %s in pass-through mode\n", fmt->name); diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index 7bfe7665687f..7fd49cb009d3 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -484,10 +484,14 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd) struct soc_camera_host *ici = to_soc_camera_host(icd->parent); unsigned int i, fmts = 0, raw_fmts = 0; int ret; - u32 code; + struct v4l2_subdev_mbus_code_enum code = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; - while (!v4l2_subdev_call(sd, video, enum_mbus_fmt, raw_fmts, &code)) + while (!v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code)) { raw_fmts++; + code.index++; + } if (!ici->ops->get_formats) /* @@ -521,11 +525,12 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd) fmts = 0; for (i = 0; i < raw_fmts; i++) if (!ici->ops->get_formats) { - v4l2_subdev_call(sd, video, enum_mbus_fmt, i, &code); + code.index = i; + v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code); icd->user_formats[fmts].host_fmt = - soc_mbus_get_fmtdesc(code); + soc_mbus_get_fmtdesc(code.code); if (icd->user_formats[fmts].host_fmt) - icd->user_formats[fmts++].code = code; + icd->user_formats[fmts++].code = code.code; } else { ret = ici->ops->get_formats(icd, i, &icd->user_formats[fmts]); diff --git a/drivers/media/platform/soc_camera/soc_camera_platform.c b/drivers/media/platform/soc_camera/soc_camera_platform.c index f535910b4187..934b9183cea8 100644 --- a/drivers/media/platform/soc_camera/soc_camera_platform.c +++ b/drivers/media/platform/soc_camera/soc_camera_platform.c @@ -61,15 +61,16 @@ static struct v4l2_subdev_core_ops platform_subdev_core_ops = { .s_power = soc_camera_platform_s_power, }; -static int soc_camera_platform_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - u32 *code) +static int soc_camera_platform_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd); - if (index) + if (code->pad || code->index) return -EINVAL; - *code = p->format.code; + code->code = p->format.code; return 0; } @@ -117,7 +118,6 @@ static int soc_camera_platform_g_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops platform_subdev_video_ops = { .s_stream = soc_camera_platform_s_stream, - .enum_mbus_fmt = soc_camera_platform_enum_fmt, .cropcap = soc_camera_platform_cropcap, .g_crop = soc_camera_platform_g_crop, .try_mbus_fmt = soc_camera_platform_fill_fmt, @@ -126,9 +126,14 @@ static struct v4l2_subdev_video_ops platform_subdev_video_ops = { .g_mbus_config = soc_camera_platform_g_mbus_config, }; +static const struct v4l2_subdev_pad_ops platform_subdev_pad_ops = { + .enum_mbus_code = soc_camera_platform_enum_mbus_code, +}; + static struct v4l2_subdev_ops platform_subdev_ops = { .core = &platform_subdev_core_ops, .video = &platform_subdev_video_ops, + .pad = &platform_subdev_pad_ops, }; static int soc_camera_platform_probe(struct platform_device *pdev) diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 2f0a345a7fed..c2eed99ebc78 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -293,8 +293,6 @@ struct v4l2_mbus_frame_desc { g_dv_timings(): Get custom dv timings in the sub device. - enum_mbus_fmt: enumerate pixel formats, provided by a video data source - g_mbus_fmt: get the current pixel format, provided by a video data source try_mbus_fmt: try to set a pixel format on a video data source @@ -338,8 +336,6 @@ struct v4l2_subdev_video_ops { struct v4l2_dv_timings *timings); int (*query_dv_timings)(struct v4l2_subdev *sd, struct v4l2_dv_timings *timings); - int (*enum_mbus_fmt)(struct v4l2_subdev *sd, unsigned int index, - u32 *code); int (*g_mbus_fmt)(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt); int (*try_mbus_fmt)(struct v4l2_subdev *sd, -- cgit v1.2.3-59-g8ed1b From da298c6d98d531de778ba8dd6657b1093ef855d0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 9 Apr 2015 04:02:34 -0300 Subject: [media] v4l2: replace video op g_mbus_fmt by pad op get_fmt The g_mbus_fmt video op is a duplicate of the pad op. Replace all uses by the get_fmt pad op and remove the video op. Signed-off-by: Hans Verkuil Acked-by: Guennadi Liakhovetski Acked-by: Prabhakar Lad Cc: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7170.c | 11 +++-- drivers/media/i2c/adv7175.c | 11 +++-- drivers/media/i2c/adv7183.c | 12 +++-- drivers/media/i2c/adv7842.c | 14 ++++-- drivers/media/i2c/ak881x.c | 24 ++++------ drivers/media/i2c/ml86v7667.c | 14 ++++-- drivers/media/i2c/saa6752hs.c | 14 +++++- drivers/media/i2c/soc_camera/imx074.c | 11 +++-- drivers/media/i2c/soc_camera/mt9m001.c | 11 +++-- drivers/media/i2c/soc_camera/mt9m111.c | 11 +++-- drivers/media/i2c/soc_camera/mt9t031.c | 11 +++-- drivers/media/i2c/soc_camera/mt9t112.c | 11 +++-- drivers/media/i2c/soc_camera/mt9v022.c | 11 +++-- drivers/media/i2c/soc_camera/ov2640.c | 11 +++-- drivers/media/i2c/soc_camera/ov5642.c | 11 +++-- drivers/media/i2c/soc_camera/ov6650.c | 11 +++-- drivers/media/i2c/soc_camera/ov772x.c | 11 +++-- drivers/media/i2c/soc_camera/rj54n1cb0c.c | 11 +++-- drivers/media/i2c/soc_camera/tw9910.c | 11 +++-- drivers/media/i2c/sr030pc30.c | 12 +++-- drivers/media/i2c/tvp514x.c | 35 ++------------ drivers/media/i2c/tvp5150.c | 15 +++--- drivers/media/i2c/tvp7002.c | 28 ----------- drivers/media/i2c/vs6624.c | 12 +++-- drivers/media/pci/saa7134/saa7134-empress.c | 9 ++-- drivers/media/platform/am437x/am437x-vpfe.c | 6 +-- drivers/media/platform/davinci/vpfe_capture.c | 19 ++++---- drivers/media/platform/s5p-tv/hdmi_drv.c | 12 +++-- drivers/media/platform/s5p-tv/mixer_drv.c | 15 ++++-- drivers/media/platform/s5p-tv/sdo_drv.c | 14 ++++-- drivers/media/platform/soc_camera/mx2_camera.c | 13 ++++-- drivers/media/platform/soc_camera/mx3_camera.c | 25 +++++----- drivers/media/platform/soc_camera/omap1_camera.c | 17 ++++--- drivers/media/platform/soc_camera/pxa_camera.c | 21 +++++---- drivers/media/platform/soc_camera/rcar_vin.c | 46 ++++++++++-------- .../platform/soc_camera/sh_mobile_ceu_camera.c | 54 ++++++++++++---------- drivers/media/platform/soc_camera/soc_camera.c | 15 +++--- .../platform/soc_camera/soc_camera_platform.c | 9 ++-- include/media/v4l2-subdev.h | 4 -- 39 files changed, 352 insertions(+), 261 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/adv7170.c b/drivers/media/i2c/adv7170.c index cfe963b2fe1c..58d0a3cc0759 100644 --- a/drivers/media/i2c/adv7170.c +++ b/drivers/media/i2c/adv7170.c @@ -273,11 +273,16 @@ static int adv7170_enum_mbus_code(struct v4l2_subdev *sd, return 0; } -static int adv7170_g_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int adv7170_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; u8 val = adv7170_read(sd, 0x7); + if (format->pad) + return -EINVAL; + if ((val & 0x40) == (1 << 6)) mf->code = MEDIA_BUS_FMT_UYVY8_1X16; else @@ -323,11 +328,11 @@ static const struct v4l2_subdev_video_ops adv7170_video_ops = { .s_std_output = adv7170_s_std_output, .s_routing = adv7170_s_routing, .s_mbus_fmt = adv7170_s_fmt, - .g_mbus_fmt = adv7170_g_fmt, }; static const struct v4l2_subdev_pad_ops adv7170_pad_ops = { .enum_mbus_code = adv7170_enum_mbus_code, + .get_fmt = adv7170_get_fmt, }; static const struct v4l2_subdev_ops adv7170_ops = { diff --git a/drivers/media/i2c/adv7175.c b/drivers/media/i2c/adv7175.c index 3f40304e856c..f7443454f682 100644 --- a/drivers/media/i2c/adv7175.c +++ b/drivers/media/i2c/adv7175.c @@ -311,11 +311,16 @@ static int adv7175_enum_mbus_code(struct v4l2_subdev *sd, return 0; } -static int adv7175_g_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int adv7175_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; u8 val = adv7175_read(sd, 0x7); + if (format->pad) + return -EINVAL; + if ((val & 0x40) == (1 << 6)) mf->code = MEDIA_BUS_FMT_UYVY8_1X16; else @@ -376,11 +381,11 @@ static const struct v4l2_subdev_video_ops adv7175_video_ops = { .s_std_output = adv7175_s_std_output, .s_routing = adv7175_s_routing, .s_mbus_fmt = adv7175_s_fmt, - .g_mbus_fmt = adv7175_g_fmt, }; static const struct v4l2_subdev_pad_ops adv7175_pad_ops = { .enum_mbus_code = adv7175_enum_mbus_code, + .get_fmt = adv7175_get_fmt, }; static const struct v4l2_subdev_ops adv7175_ops = { diff --git a/drivers/media/i2c/adv7183.c b/drivers/media/i2c/adv7183.c index a0bcfefc28fc..9d58b750ef1e 100644 --- a/drivers/media/i2c/adv7183.c +++ b/drivers/media/i2c/adv7183.c @@ -460,12 +460,16 @@ static int adv7183_s_mbus_fmt(struct v4l2_subdev *sd, return 0; } -static int adv7183_g_mbus_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *fmt) +static int adv7183_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { struct adv7183 *decoder = to_adv7183(sd); - *fmt = decoder->fmt; + if (format->pad) + return -EINVAL; + + format->format = decoder->fmt; return 0; } @@ -517,12 +521,12 @@ static const struct v4l2_subdev_video_ops adv7183_video_ops = { .g_input_status = adv7183_g_input_status, .try_mbus_fmt = adv7183_try_mbus_fmt, .s_mbus_fmt = adv7183_s_mbus_fmt, - .g_mbus_fmt = adv7183_g_mbus_fmt, .s_stream = adv7183_s_stream, }; static const struct v4l2_subdev_pad_ops adv7183_pad_ops = { .enum_mbus_code = adv7183_enum_mbus_code, + .get_fmt = adv7183_get_fmt, }; static const struct v4l2_subdev_ops adv7183_ops = { diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index 644e910f9d8a..86e65a8a5409 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -1878,11 +1878,16 @@ static int adv7842_enum_mbus_code(struct v4l2_subdev *sd, return 0; } -static int adv7842_g_mbus_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *fmt) +static int adv7842_fill_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *fmt = &format->format; struct adv7842_state *state = to_state(sd); + if (format->pad) + return -EINVAL; + fmt->width = state->timings.bt.width; fmt->height = state->timings.bt.height; fmt->code = MEDIA_BUS_FMT_FIXED; @@ -2810,9 +2815,6 @@ static const struct v4l2_subdev_video_ops adv7842_video_ops = { .s_dv_timings = adv7842_s_dv_timings, .g_dv_timings = adv7842_g_dv_timings, .query_dv_timings = adv7842_query_dv_timings, - .g_mbus_fmt = adv7842_g_mbus_fmt, - .try_mbus_fmt = adv7842_g_mbus_fmt, - .s_mbus_fmt = adv7842_g_mbus_fmt, }; static const struct v4l2_subdev_pad_ops adv7842_pad_ops = { @@ -2821,6 +2823,8 @@ static const struct v4l2_subdev_pad_ops adv7842_pad_ops = { .enum_dv_timings = adv7842_enum_dv_timings, .dv_timings_cap = adv7842_dv_timings_cap, .enum_mbus_code = adv7842_enum_mbus_code, + .get_fmt = adv7842_fill_fmt, + .set_fmt = adv7842_fill_fmt, }; static const struct v4l2_subdev_ops adv7842_ops = { diff --git a/drivers/media/i2c/ak881x.c b/drivers/media/i2c/ak881x.c index 4428fb95d033..29846245aa3b 100644 --- a/drivers/media/i2c/ak881x.c +++ b/drivers/media/i2c/ak881x.c @@ -93,12 +93,17 @@ static int ak881x_s_register(struct v4l2_subdev *sd, } #endif -static int ak881x_try_g_mbus_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int ak881x_fill_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; struct i2c_client *client = v4l2_get_subdevdata(sd); struct ak881x *ak881x = to_ak881x(client); + if (format->pad) + return -EINVAL; + v4l_bound_align_image(&mf->width, 0, 720, 2, &mf->height, 0, ak881x->lines, 1, 0); mf->field = V4L2_FIELD_INTERLACED; @@ -108,16 +113,6 @@ static int ak881x_try_g_mbus_fmt(struct v4l2_subdev *sd, return 0; } -static int ak881x_s_mbus_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) -{ - if (mf->field != V4L2_FIELD_INTERLACED || - mf->code != MEDIA_BUS_FMT_YUYV8_2X8) - return -EINVAL; - - return ak881x_try_g_mbus_fmt(sd, mf); -} - static int ak881x_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_mbus_code_enum *code) @@ -212,9 +207,6 @@ static struct v4l2_subdev_core_ops ak881x_subdev_core_ops = { }; static struct v4l2_subdev_video_ops ak881x_subdev_video_ops = { - .s_mbus_fmt = ak881x_s_mbus_fmt, - .g_mbus_fmt = ak881x_try_g_mbus_fmt, - .try_mbus_fmt = ak881x_try_g_mbus_fmt, .cropcap = ak881x_cropcap, .s_std_output = ak881x_s_std_output, .s_stream = ak881x_s_stream, @@ -222,6 +214,8 @@ static struct v4l2_subdev_video_ops ak881x_subdev_video_ops = { static const struct v4l2_subdev_pad_ops ak881x_subdev_pad_ops = { .enum_mbus_code = ak881x_enum_mbus_code, + .set_fmt = ak881x_fill_fmt, + .get_fmt = ak881x_fill_fmt, }; static struct v4l2_subdev_ops ak881x_subdev_ops = { diff --git a/drivers/media/i2c/ml86v7667.c b/drivers/media/i2c/ml86v7667.c index e7b220239d30..af5eaf2db2a0 100644 --- a/drivers/media/i2c/ml86v7667.c +++ b/drivers/media/i2c/ml86v7667.c @@ -203,10 +203,15 @@ static int ml86v7667_enum_mbus_code(struct v4l2_subdev *sd, return 0; } -static int ml86v7667_mbus_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *fmt) +static int ml86v7667_fill_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { struct ml86v7667_priv *priv = to_ml86v7667(sd); + struct v4l2_mbus_framefmt *fmt = &format->format; + + if (format->pad) + return -EINVAL; fmt->code = MEDIA_BUS_FMT_YUYV8_2X8; fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; @@ -280,14 +285,13 @@ static struct v4l2_subdev_video_ops ml86v7667_subdev_video_ops = { .s_std = ml86v7667_s_std, .querystd = ml86v7667_querystd, .g_input_status = ml86v7667_g_input_status, - .try_mbus_fmt = ml86v7667_mbus_fmt, - .g_mbus_fmt = ml86v7667_mbus_fmt, - .s_mbus_fmt = ml86v7667_mbus_fmt, .g_mbus_config = ml86v7667_g_mbus_config, }; static const struct v4l2_subdev_pad_ops ml86v7667_subdev_pad_ops = { .enum_mbus_code = ml86v7667_enum_mbus_code, + .get_fmt = ml86v7667_fill_fmt, + .set_fmt = ml86v7667_fill_fmt, }; static struct v4l2_subdev_core_ops ml86v7667_subdev_core_ops = { diff --git a/drivers/media/i2c/saa6752hs.c b/drivers/media/i2c/saa6752hs.c index f14c0e6435a3..b3829078d646 100644 --- a/drivers/media/i2c/saa6752hs.c +++ b/drivers/media/i2c/saa6752hs.c @@ -554,10 +554,16 @@ static int saa6752hs_init(struct v4l2_subdev *sd, u32 leading_null_bytes) return 0; } -static int saa6752hs_g_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f) +static int saa6752hs_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *f = &format->format; struct saa6752hs_state *h = to_state(sd); + if (format->pad) + return -EINVAL; + if (h->video_format == SAA6752HS_VF_UNKNOWN) h->video_format = SAA6752HS_VF_D1; f->width = v4l2_format_table[h->video_format].fmt.pix.width; @@ -649,12 +655,16 @@ static const struct v4l2_subdev_video_ops saa6752hs_video_ops = { .s_std = saa6752hs_s_std, .s_mbus_fmt = saa6752hs_s_mbus_fmt, .try_mbus_fmt = saa6752hs_try_mbus_fmt, - .g_mbus_fmt = saa6752hs_g_mbus_fmt, +}; + +static const struct v4l2_subdev_pad_ops saa6752hs_pad_ops = { + .get_fmt = saa6752hs_get_fmt, }; static const struct v4l2_subdev_ops saa6752hs_ops = { .core = &saa6752hs_core_ops, .video = &saa6752hs_video_ops, + .pad = &saa6752hs_pad_ops, }; static int saa6752hs_probe(struct i2c_client *client, diff --git a/drivers/media/i2c/soc_camera/imx074.c b/drivers/media/i2c/soc_camera/imx074.c index 7a2d90654fee..ba60ccfffa4f 100644 --- a/drivers/media/i2c/soc_camera/imx074.c +++ b/drivers/media/i2c/soc_camera/imx074.c @@ -191,14 +191,19 @@ static int imx074_s_fmt(struct v4l2_subdev *sd, return 0; } -static int imx074_g_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int imx074_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; struct i2c_client *client = v4l2_get_subdevdata(sd); struct imx074 *priv = to_imx074(client); const struct imx074_datafmt *fmt = priv->fmt; + if (format->pad) + return -EINVAL; + mf->code = fmt->code; mf->colorspace = fmt->colorspace; mf->width = IMX074_WIDTH; @@ -278,7 +283,6 @@ static int imx074_g_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops imx074_subdev_video_ops = { .s_stream = imx074_s_stream, .s_mbus_fmt = imx074_s_fmt, - .g_mbus_fmt = imx074_g_fmt, .try_mbus_fmt = imx074_try_fmt, .g_crop = imx074_g_crop, .cropcap = imx074_cropcap, @@ -291,6 +295,7 @@ static struct v4l2_subdev_core_ops imx074_subdev_core_ops = { static const struct v4l2_subdev_pad_ops imx074_subdev_pad_ops = { .enum_mbus_code = imx074_enum_mbus_code, + .get_fmt = imx074_get_fmt, }; static struct v4l2_subdev_ops imx074_subdev_ops = { diff --git a/drivers/media/i2c/soc_camera/mt9m001.c b/drivers/media/i2c/soc_camera/mt9m001.c index ba18e010b9da..06f4e116978d 100644 --- a/drivers/media/i2c/soc_camera/mt9m001.c +++ b/drivers/media/i2c/soc_camera/mt9m001.c @@ -250,11 +250,16 @@ static int mt9m001_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) return 0; } -static int mt9m001_g_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int mt9m001_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9m001 *mt9m001 = to_mt9m001(client); + struct v4l2_mbus_framefmt *mf = &format->format; + + if (format->pad) + return -EINVAL; mf->width = mt9m001->rect.width; mf->height = mt9m001->rect.height; @@ -613,7 +618,6 @@ static int mt9m001_s_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = { .s_stream = mt9m001_s_stream, .s_mbus_fmt = mt9m001_s_fmt, - .g_mbus_fmt = mt9m001_g_fmt, .try_mbus_fmt = mt9m001_try_fmt, .s_crop = mt9m001_s_crop, .g_crop = mt9m001_g_crop, @@ -628,6 +632,7 @@ static struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = { static const struct v4l2_subdev_pad_ops mt9m001_subdev_pad_ops = { .enum_mbus_code = mt9m001_enum_mbus_code, + .get_fmt = mt9m001_get_fmt, }; static struct v4l2_subdev_ops mt9m001_subdev_ops = { diff --git a/drivers/media/i2c/soc_camera/mt9m111.c b/drivers/media/i2c/soc_camera/mt9m111.c index b7731401dc39..7ac87b112a11 100644 --- a/drivers/media/i2c/soc_camera/mt9m111.c +++ b/drivers/media/i2c/soc_camera/mt9m111.c @@ -447,11 +447,16 @@ static int mt9m111_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) return 0; } -static int mt9m111_g_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int mt9m111_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev); + if (format->pad) + return -EINVAL; + mf->width = mt9m111->width; mf->height = mt9m111->height; mf->code = mt9m111->fmt->code; @@ -867,7 +872,6 @@ static int mt9m111_g_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = { .s_mbus_fmt = mt9m111_s_fmt, - .g_mbus_fmt = mt9m111_g_fmt, .try_mbus_fmt = mt9m111_try_fmt, .s_crop = mt9m111_s_crop, .g_crop = mt9m111_g_crop, @@ -877,6 +881,7 @@ static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = { static const struct v4l2_subdev_pad_ops mt9m111_subdev_pad_ops = { .enum_mbus_code = mt9m111_enum_mbus_code, + .get_fmt = mt9m111_get_fmt, }; static struct v4l2_subdev_ops mt9m111_subdev_ops = { diff --git a/drivers/media/i2c/soc_camera/mt9t031.c b/drivers/media/i2c/soc_camera/mt9t031.c index 15ac4dc29967..97193e471ab5 100644 --- a/drivers/media/i2c/soc_camera/mt9t031.c +++ b/drivers/media/i2c/soc_camera/mt9t031.c @@ -337,12 +337,17 @@ static int mt9t031_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) return 0; } -static int mt9t031_g_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int mt9t031_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9t031 *mt9t031 = to_mt9t031(client); + if (format->pad) + return -EINVAL; + mf->width = mt9t031->rect.width / mt9t031->xskip; mf->height = mt9t031->rect.height / mt9t031->yskip; mf->code = MEDIA_BUS_FMT_SBGGR10_1X10; @@ -714,7 +719,6 @@ static int mt9t031_s_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = { .s_stream = mt9t031_s_stream, .s_mbus_fmt = mt9t031_s_fmt, - .g_mbus_fmt = mt9t031_g_fmt, .try_mbus_fmt = mt9t031_try_fmt, .s_crop = mt9t031_s_crop, .g_crop = mt9t031_g_crop, @@ -729,6 +733,7 @@ static struct v4l2_subdev_sensor_ops mt9t031_subdev_sensor_ops = { static const struct v4l2_subdev_pad_ops mt9t031_subdev_pad_ops = { .enum_mbus_code = mt9t031_enum_mbus_code, + .get_fmt = mt9t031_get_fmt, }; static struct v4l2_subdev_ops mt9t031_subdev_ops = { diff --git a/drivers/media/i2c/soc_camera/mt9t112.c b/drivers/media/i2c/soc_camera/mt9t112.c index 8b0cfb7f80b1..889e98ee8c62 100644 --- a/drivers/media/i2c/soc_camera/mt9t112.c +++ b/drivers/media/i2c/soc_camera/mt9t112.c @@ -904,12 +904,17 @@ static int mt9t112_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) return mt9t112_set_params(priv, rect, priv->format->code); } -static int mt9t112_g_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int mt9t112_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9t112_priv *priv = to_mt9t112(client); + if (format->pad) + return -EINVAL; + mf->width = priv->frame.width; mf->height = priv->frame.height; mf->colorspace = priv->format->colorspace; @@ -1011,7 +1016,6 @@ static int mt9t112_s_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = { .s_stream = mt9t112_s_stream, - .g_mbus_fmt = mt9t112_g_fmt, .s_mbus_fmt = mt9t112_s_fmt, .try_mbus_fmt = mt9t112_try_fmt, .cropcap = mt9t112_cropcap, @@ -1023,6 +1027,7 @@ static struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = { static const struct v4l2_subdev_pad_ops mt9t112_subdev_pad_ops = { .enum_mbus_code = mt9t112_enum_mbus_code, + .get_fmt = mt9t112_get_fmt, }; /************************************************************************ diff --git a/drivers/media/i2c/soc_camera/mt9v022.c b/drivers/media/i2c/soc_camera/mt9v022.c index 780c7ae74d69..b4ba3c5930e3 100644 --- a/drivers/media/i2c/soc_camera/mt9v022.c +++ b/drivers/media/i2c/soc_camera/mt9v022.c @@ -375,12 +375,17 @@ static int mt9v022_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) return 0; } -static int mt9v022_g_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int mt9v022_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9v022 *mt9v022 = to_mt9v022(client); + if (format->pad) + return -EINVAL; + mf->width = mt9v022->rect.width; mf->height = mt9v022->rect.height; mf->code = mt9v022->fmt->code; @@ -841,7 +846,6 @@ static int mt9v022_s_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = { .s_stream = mt9v022_s_stream, .s_mbus_fmt = mt9v022_s_fmt, - .g_mbus_fmt = mt9v022_g_fmt, .try_mbus_fmt = mt9v022_try_fmt, .s_crop = mt9v022_s_crop, .g_crop = mt9v022_g_crop, @@ -856,6 +860,7 @@ static struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = { static const struct v4l2_subdev_pad_ops mt9v022_subdev_pad_ops = { .enum_mbus_code = mt9v022_enum_mbus_code, + .get_fmt = mt9v022_get_fmt, }; static struct v4l2_subdev_ops mt9v022_subdev_ops = { diff --git a/drivers/media/i2c/soc_camera/ov2640.c b/drivers/media/i2c/soc_camera/ov2640.c index 4327871c8f9f..0dffc63ee83f 100644 --- a/drivers/media/i2c/soc_camera/ov2640.c +++ b/drivers/media/i2c/soc_camera/ov2640.c @@ -845,12 +845,17 @@ err: return ret; } -static int ov2640_g_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int ov2640_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; struct i2c_client *client = v4l2_get_subdevdata(sd); struct ov2640_priv *priv = to_ov2640(client); + if (format->pad) + return -EINVAL; + if (!priv->win) { u32 width = SVGA_WIDTH, height = SVGA_HEIGHT; priv->win = ov2640_select_win(&width, &height); @@ -1032,7 +1037,6 @@ static int ov2640_g_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = { .s_stream = ov2640_s_stream, - .g_mbus_fmt = ov2640_g_fmt, .s_mbus_fmt = ov2640_s_fmt, .try_mbus_fmt = ov2640_try_fmt, .cropcap = ov2640_cropcap, @@ -1042,6 +1046,7 @@ static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = { static const struct v4l2_subdev_pad_ops ov2640_subdev_pad_ops = { .enum_mbus_code = ov2640_enum_mbus_code, + .get_fmt = ov2640_get_fmt, }; static struct v4l2_subdev_ops ov2640_subdev_ops = { diff --git a/drivers/media/i2c/soc_camera/ov5642.c b/drivers/media/i2c/soc_camera/ov5642.c index fcddd0ded2e3..a88397f60b8c 100644 --- a/drivers/media/i2c/soc_camera/ov5642.c +++ b/drivers/media/i2c/soc_camera/ov5642.c @@ -822,14 +822,19 @@ static int ov5642_s_fmt(struct v4l2_subdev *sd, return 0; } -static int ov5642_g_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int ov5642_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; struct i2c_client *client = v4l2_get_subdevdata(sd); struct ov5642 *priv = to_ov5642(client); const struct ov5642_datafmt *fmt = priv->fmt; + if (format->pad) + return -EINVAL; + mf->code = fmt->code; mf->colorspace = fmt->colorspace; mf->width = priv->crop_rect.width; @@ -941,7 +946,6 @@ static int ov5642_s_power(struct v4l2_subdev *sd, int on) static struct v4l2_subdev_video_ops ov5642_subdev_video_ops = { .s_mbus_fmt = ov5642_s_fmt, - .g_mbus_fmt = ov5642_g_fmt, .try_mbus_fmt = ov5642_try_fmt, .s_crop = ov5642_s_crop, .g_crop = ov5642_g_crop, @@ -951,6 +955,7 @@ static struct v4l2_subdev_video_ops ov5642_subdev_video_ops = { static const struct v4l2_subdev_pad_ops ov5642_subdev_pad_ops = { .enum_mbus_code = ov5642_enum_mbus_code, + .get_fmt = ov5642_get_fmt, }; static struct v4l2_subdev_core_ops ov5642_subdev_core_ops = { diff --git a/drivers/media/i2c/soc_camera/ov6650.c b/drivers/media/i2c/soc_camera/ov6650.c index 99e0738fdb38..29f73a55a312 100644 --- a/drivers/media/i2c/soc_camera/ov6650.c +++ b/drivers/media/i2c/soc_camera/ov6650.c @@ -499,12 +499,17 @@ static int ov6650_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) return 0; } -static int ov6650_g_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int ov6650_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; struct i2c_client *client = v4l2_get_subdevdata(sd); struct ov6650 *priv = to_ov6650(client); + if (format->pad) + return -EINVAL; + mf->width = priv->rect.width >> priv->half_scale; mf->height = priv->rect.height >> priv->half_scale; mf->code = priv->code; @@ -930,7 +935,6 @@ static int ov6650_s_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops ov6650_video_ops = { .s_stream = ov6650_s_stream, - .g_mbus_fmt = ov6650_g_fmt, .s_mbus_fmt = ov6650_s_fmt, .try_mbus_fmt = ov6650_try_fmt, .cropcap = ov6650_cropcap, @@ -944,6 +948,7 @@ static struct v4l2_subdev_video_ops ov6650_video_ops = { static const struct v4l2_subdev_pad_ops ov6650_pad_ops = { .enum_mbus_code = ov6650_enum_mbus_code, + .get_fmt = ov6650_get_fmt, }; static struct v4l2_subdev_ops ov6650_subdev_ops = { diff --git a/drivers/media/i2c/soc_camera/ov772x.c b/drivers/media/i2c/soc_camera/ov772x.c index e3a31f806636..1db204451384 100644 --- a/drivers/media/i2c/soc_camera/ov772x.c +++ b/drivers/media/i2c/soc_camera/ov772x.c @@ -876,11 +876,16 @@ static int ov772x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) return 0; } -static int ov772x_g_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int ov772x_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; struct ov772x_priv *priv = to_ov772x(sd); + if (format->pad) + return -EINVAL; + mf->width = priv->win->rect.width; mf->height = priv->win->rect.height; mf->code = priv->cfmt->code; @@ -1017,7 +1022,6 @@ static int ov772x_g_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = { .s_stream = ov772x_s_stream, - .g_mbus_fmt = ov772x_g_fmt, .s_mbus_fmt = ov772x_s_fmt, .try_mbus_fmt = ov772x_try_fmt, .cropcap = ov772x_cropcap, @@ -1027,6 +1031,7 @@ static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = { static const struct v4l2_subdev_pad_ops ov772x_subdev_pad_ops = { .enum_mbus_code = ov772x_enum_mbus_code, + .get_fmt = ov772x_get_fmt, }; static struct v4l2_subdev_ops ov772x_subdev_ops = { diff --git a/drivers/media/i2c/soc_camera/rj54n1cb0c.c b/drivers/media/i2c/soc_camera/rj54n1cb0c.c index 4927a76d2240..8787142493cc 100644 --- a/drivers/media/i2c/soc_camera/rj54n1cb0c.c +++ b/drivers/media/i2c/soc_camera/rj54n1cb0c.c @@ -598,12 +598,17 @@ static int rj54n1_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) return 0; } -static int rj54n1_g_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int rj54n1_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; struct i2c_client *client = v4l2_get_subdevdata(sd); struct rj54n1 *rj54n1 = to_rj54n1(client); + if (format->pad) + return -EINVAL; + mf->code = rj54n1->fmt->code; mf->colorspace = rj54n1->fmt->colorspace; mf->field = V4L2_FIELD_NONE; @@ -1251,7 +1256,6 @@ static int rj54n1_s_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = { .s_stream = rj54n1_s_stream, .s_mbus_fmt = rj54n1_s_fmt, - .g_mbus_fmt = rj54n1_g_fmt, .try_mbus_fmt = rj54n1_try_fmt, .g_crop = rj54n1_g_crop, .s_crop = rj54n1_s_crop, @@ -1262,6 +1266,7 @@ static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = { static const struct v4l2_subdev_pad_ops rj54n1_subdev_pad_ops = { .enum_mbus_code = rj54n1_enum_mbus_code, + .get_fmt = rj54n1_get_fmt, }; static struct v4l2_subdev_ops rj54n1_subdev_ops = { diff --git a/drivers/media/i2c/soc_camera/tw9910.c b/drivers/media/i2c/soc_camera/tw9910.c index f8c0c713d06c..95837959f409 100644 --- a/drivers/media/i2c/soc_camera/tw9910.c +++ b/drivers/media/i2c/soc_camera/tw9910.c @@ -691,12 +691,17 @@ static int tw9910_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) return 0; } -static int tw9910_g_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int tw9910_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; struct i2c_client *client = v4l2_get_subdevdata(sd); struct tw9910_priv *priv = to_tw9910(client); + if (format->pad) + return -EINVAL; + if (!priv->scale) { priv->scale = tw9910_select_norm(priv->norm, 640, 480); if (!priv->scale) @@ -881,7 +886,6 @@ static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = { .s_std = tw9910_s_std, .g_std = tw9910_g_std, .s_stream = tw9910_s_stream, - .g_mbus_fmt = tw9910_g_fmt, .s_mbus_fmt = tw9910_s_fmt, .try_mbus_fmt = tw9910_try_fmt, .cropcap = tw9910_cropcap, @@ -893,6 +897,7 @@ static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = { static const struct v4l2_subdev_pad_ops tw9910_subdev_pad_ops = { .enum_mbus_code = tw9910_enum_mbus_code, + .get_fmt = tw9910_get_fmt, }; static struct v4l2_subdev_ops tw9910_subdev_ops = { diff --git a/drivers/media/i2c/sr030pc30.c b/drivers/media/i2c/sr030pc30.c index 0a0a1886ee4c..c0fa94570c4f 100644 --- a/drivers/media/i2c/sr030pc30.c +++ b/drivers/media/i2c/sr030pc30.c @@ -483,15 +483,19 @@ static int sr030pc30_enum_mbus_code(struct v4l2_subdev *sd, return 0; } -static int sr030pc30_g_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int sr030pc30_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf; struct sr030pc30_info *info = to_sr030pc30(sd); int ret; - if (!mf) + if (!format || format->pad) return -EINVAL; + mf = &format->format; + if (!info->curr_win || !info->curr_fmt) { ret = sr030pc30_set_params(sd); if (ret) @@ -639,13 +643,13 @@ static const struct v4l2_subdev_core_ops sr030pc30_core_ops = { }; static const struct v4l2_subdev_video_ops sr030pc30_video_ops = { - .g_mbus_fmt = sr030pc30_g_fmt, .s_mbus_fmt = sr030pc30_s_fmt, .try_mbus_fmt = sr030pc30_try_fmt, }; static const struct v4l2_subdev_pad_ops sr030pc30_pad_ops = { .enum_mbus_code = sr030pc30_enum_mbus_code, + .get_fmt = sr030pc30_get_fmt, }; static const struct v4l2_subdev_ops sr030pc30_ops = { diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c index a822d1541614..24e47279e30c 100644 --- a/drivers/media/i2c/tvp514x.c +++ b/drivers/media/i2c/tvp514x.c @@ -746,35 +746,6 @@ static int tvp514x_s_ctrl(struct v4l2_ctrl *ctrl) return err; } -/** - * tvp514x_mbus_fmt() - V4L2 decoder interface handler for try/s/g_mbus_fmt - * @sd: pointer to standard V4L2 sub-device structure - * @f: pointer to the mediabus format structure - * - * Negotiates the image capture size and mediabus format. - */ -static int -tvp514x_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f) -{ - struct tvp514x_decoder *decoder = to_decoder(sd); - enum tvp514x_std current_std; - - if (f == NULL) - return -EINVAL; - - /* Calculate height and width based on current standard */ - current_std = decoder->current_std; - - f->code = MEDIA_BUS_FMT_YUYV8_2X8; - f->width = decoder->std_list[current_std].width; - f->height = decoder->std_list[current_std].height; - f->field = V4L2_FIELD_INTERLACED; - f->colorspace = V4L2_COLORSPACE_SMPTE170M; - v4l2_dbg(1, debug, sd, "MBUS_FMT: Width - %d, Height - %d\n", - f->width, f->height); - return 0; -} - /** * tvp514x_g_parm() - V4L2 decoder interface handler for g_parm * @sd: pointer to standard V4L2 sub-device structure @@ -943,6 +914,9 @@ static int tvp514x_get_pad_format(struct v4l2_subdev *sd, struct tvp514x_decoder *decoder = to_decoder(sd); __u32 which = format->which; + if (format->pad) + return -EINVAL; + if (which == V4L2_SUBDEV_FORMAT_ACTIVE) { format->format = decoder->format; return 0; @@ -997,9 +971,6 @@ static const struct v4l2_subdev_video_ops tvp514x_video_ops = { .s_std = tvp514x_s_std, .s_routing = tvp514x_s_routing, .querystd = tvp514x_querystd, - .g_mbus_fmt = tvp514x_mbus_fmt, - .try_mbus_fmt = tvp514x_mbus_fmt, - .s_mbus_fmt = tvp514x_mbus_fmt, .g_parm = tvp514x_g_parm, .s_parm = tvp514x_s_parm, .s_stream = tvp514x_s_stream, diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c index f2f87b73184c..e4fa0746f75e 100644 --- a/drivers/media/i2c/tvp5150.c +++ b/drivers/media/i2c/tvp5150.c @@ -828,14 +828,18 @@ static int tvp5150_enum_mbus_code(struct v4l2_subdev *sd, return 0; } -static int tvp5150_mbus_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *f) +static int tvp5150_fill_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *f; struct tvp5150 *decoder = to_tvp5150(sd); - if (f == NULL) + if (!format || format->pad) return -EINVAL; + f = &format->format; + tvp5150_reset(sd, 0); f->width = decoder->rect.width; @@ -1069,9 +1073,6 @@ static const struct v4l2_subdev_tuner_ops tvp5150_tuner_ops = { static const struct v4l2_subdev_video_ops tvp5150_video_ops = { .s_std = tvp5150_s_std, .s_routing = tvp5150_s_routing, - .s_mbus_fmt = tvp5150_mbus_fmt, - .try_mbus_fmt = tvp5150_mbus_fmt, - .g_mbus_fmt = tvp5150_mbus_fmt, .s_crop = tvp5150_s_crop, .g_crop = tvp5150_g_crop, .cropcap = tvp5150_cropcap, @@ -1086,6 +1087,8 @@ static const struct v4l2_subdev_vbi_ops tvp5150_vbi_ops = { static const struct v4l2_subdev_pad_ops tvp5150_pad_ops = { .enum_mbus_code = tvp5150_enum_mbus_code, + .set_fmt = tvp5150_fill_fmt, + .get_fmt = tvp5150_fill_fmt, }; static const struct v4l2_subdev_ops tvp5150_ops = { diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c index d21fa1a62e41..05077cffd235 100644 --- a/drivers/media/i2c/tvp7002.c +++ b/drivers/media/i2c/tvp7002.c @@ -610,31 +610,6 @@ static int tvp7002_s_ctrl(struct v4l2_ctrl *ctrl) return -EINVAL; } -/* - * tvp7002_mbus_fmt() - V4L2 decoder interface handler for try/s/g_mbus_fmt - * @sd: pointer to standard V4L2 sub-device structure - * @f: pointer to mediabus format structure - * - * Negotiate the image capture size and mediabus format. - * There is only one possible format, so this single function works for - * get, set and try. - */ -static int tvp7002_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f) -{ - struct tvp7002 *device = to_tvp7002(sd); - const struct v4l2_bt_timings *bt = &device->current_timings->timings.bt; - - f->width = bt->width; - f->height = bt->height; - f->code = MEDIA_BUS_FMT_YUYV10_1X20; - f->field = device->current_timings->scanmode; - f->colorspace = device->current_timings->color_space; - - v4l2_dbg(1, debug, sd, "MBUS_FMT: Width - %d, Height - %d", - f->width, f->height); - return 0; -} - /* * tvp7002_query_dv() - query DV timings * @sd: pointer to standard V4L2 sub-device structure @@ -905,9 +880,6 @@ static const struct v4l2_subdev_video_ops tvp7002_video_ops = { .s_dv_timings = tvp7002_s_dv_timings, .query_dv_timings = tvp7002_query_dv_timings, .s_stream = tvp7002_s_stream, - .g_mbus_fmt = tvp7002_mbus_fmt, - .try_mbus_fmt = tvp7002_mbus_fmt, - .s_mbus_fmt = tvp7002_mbus_fmt, }; /* media pad related operation handlers */ diff --git a/drivers/media/i2c/vs6624.c b/drivers/media/i2c/vs6624.c index b1d0a1b28ca8..59f733524620 100644 --- a/drivers/media/i2c/vs6624.c +++ b/drivers/media/i2c/vs6624.c @@ -649,12 +649,16 @@ static int vs6624_s_mbus_fmt(struct v4l2_subdev *sd, return 0; } -static int vs6624_g_mbus_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *fmt) +static int vs6624_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { struct vs6624 *sensor = to_vs6624(sd); - *fmt = sensor->fmt; + if (format->pad) + return -EINVAL; + + format->format = sensor->fmt; return 0; } @@ -741,7 +745,6 @@ static const struct v4l2_subdev_core_ops vs6624_core_ops = { static const struct v4l2_subdev_video_ops vs6624_video_ops = { .try_mbus_fmt = vs6624_try_mbus_fmt, .s_mbus_fmt = vs6624_s_mbus_fmt, - .g_mbus_fmt = vs6624_g_mbus_fmt, .s_parm = vs6624_s_parm, .g_parm = vs6624_g_parm, .s_stream = vs6624_s_stream, @@ -749,6 +752,7 @@ static const struct v4l2_subdev_video_ops vs6624_video_ops = { static const struct v4l2_subdev_pad_ops vs6624_pad_ops = { .enum_mbus_code = vs6624_enum_mbus_code, + .get_fmt = vs6624_get_fmt, }; static const struct v4l2_subdev_ops vs6624_ops = { diff --git a/drivers/media/pci/saa7134/saa7134-empress.c b/drivers/media/pci/saa7134/saa7134-empress.c index 594dc3ad4750..22632f9e34e6 100644 --- a/drivers/media/pci/saa7134/saa7134-empress.c +++ b/drivers/media/pci/saa7134/saa7134-empress.c @@ -121,11 +121,14 @@ static int empress_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct saa7134_dev *dev = video_drvdata(file); - struct v4l2_mbus_framefmt mbus_fmt; + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct v4l2_mbus_framefmt *mbus_fmt = &fmt.format; - saa_call_all(dev, video, g_mbus_fmt, &mbus_fmt); + saa_call_all(dev, pad, get_fmt, NULL, &fmt); - v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); + v4l2_fill_pix_format(&f->fmt.pix, mbus_fmt); f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; f->fmt.pix.bytesperline = 0; diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c index 73359652e486..88712f3247ab 100644 --- a/drivers/media/platform/am437x/am437x-vpfe.c +++ b/drivers/media/platform/am437x/am437x-vpfe.c @@ -1095,7 +1095,7 @@ static int vpfe_config_ccdc_image_format(struct vpfe_device *vpfe) * For a given standard, this functions sets up the default * pix format & crop values in the vpfe device and ccdc. It first * starts with defaults based values from the standard table. - * It then checks if sub device support g_mbus_fmt and then override the + * It then checks if sub device supports get_fmt and then override the * values based on that.Sets crop values to match with scan resolution * starting at 0,0. It calls vpfe_config_ccdc_image_format() set the * values in ccdc @@ -1432,8 +1432,8 @@ static int __vpfe_get_format(struct vpfe_device *vpfe, } else { ret = v4l2_device_call_until_err(&vpfe->v4l2_dev, sdinfo->grp_id, - video, g_mbus_fmt, - &mbus_fmt); + pad, get_fmt, + NULL, &fmt); if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) return ret; v4l2_fill_pix_format(&format->fmt.pix, &mbus_fmt); diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index ccfcf3f528d3..7767e072d623 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -370,7 +370,7 @@ static int vpfe_config_ccdc_image_format(struct vpfe_device *vpfe_dev) * For a given standard, this functions sets up the default * pix format & crop values in the vpfe device and ccdc. It first * starts with defaults based values from the standard table. - * It then checks if sub device support g_mbus_fmt and then override the + * It then checks if sub device supports get_fmt and then override the * values based on that.Sets crop values to match with scan resolution * starting at 0,0. It calls vpfe_config_ccdc_image_format() set the * values in ccdc @@ -379,7 +379,10 @@ static int vpfe_config_image_format(struct vpfe_device *vpfe_dev, v4l2_std_id std_id) { struct vpfe_subdev_info *sdinfo = vpfe_dev->current_subdev; - struct v4l2_mbus_framefmt mbus_fmt; + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct v4l2_mbus_framefmt *mbus_fmt = &fmt.format; struct v4l2_pix_format *pix = &vpfe_dev->fmt.fmt.pix; int i, ret = 0; @@ -413,26 +416,26 @@ static int vpfe_config_image_format(struct vpfe_device *vpfe_dev, pix->field = V4L2_FIELD_INTERLACED; /* assume V4L2_PIX_FMT_UYVY as default */ pix->pixelformat = V4L2_PIX_FMT_UYVY; - v4l2_fill_mbus_format(&mbus_fmt, pix, + v4l2_fill_mbus_format(mbus_fmt, pix, MEDIA_BUS_FMT_YUYV10_2X10); } else { pix->field = V4L2_FIELD_NONE; /* assume V4L2_PIX_FMT_SBGGR8 */ pix->pixelformat = V4L2_PIX_FMT_SBGGR8; - v4l2_fill_mbus_format(&mbus_fmt, pix, + v4l2_fill_mbus_format(mbus_fmt, pix, MEDIA_BUS_FMT_SBGGR8_1X8); } - /* if sub device supports g_mbus_fmt, override the defaults */ + /* if sub device supports get_fmt, override the defaults */ ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, - sdinfo->grp_id, video, g_mbus_fmt, &mbus_fmt); + sdinfo->grp_id, pad, get_fmt, NULL, &fmt); if (ret && ret != -ENOIOCTLCMD) { v4l2_err(&vpfe_dev->v4l2_dev, - "error in getting g_mbus_fmt from sub device\n"); + "error in getting get_fmt from sub device\n"); return ret; } - v4l2_fill_pix_format(pix, &mbus_fmt); + v4l2_fill_pix_format(pix, mbus_fmt); pix->bytesperline = pix->width * 2; pix->sizeimage = pix->bytesperline * pix->height; diff --git a/drivers/media/platform/s5p-tv/hdmi_drv.c b/drivers/media/platform/s5p-tv/hdmi_drv.c index 0e74aabf5f9a..618ecd1d5b27 100644 --- a/drivers/media/platform/s5p-tv/hdmi_drv.c +++ b/drivers/media/platform/s5p-tv/hdmi_drv.c @@ -648,15 +648,20 @@ static int hdmi_g_dv_timings(struct v4l2_subdev *sd, return 0; } -static int hdmi_g_mbus_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *fmt) +static int hdmi_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *fmt = &format->format; struct hdmi_device *hdev = sd_to_hdmi_dev(sd); const struct hdmi_timings *t = hdev->cur_conf; dev_dbg(hdev->dev, "%s\n", __func__); if (!hdev->cur_conf) return -EINVAL; + if (format->pad) + return -EINVAL; + memset(fmt, 0, sizeof(*fmt)); fmt->width = t->hact.end - t->hact.beg; fmt->height = t->vact[0].end - t->vact[0].beg; @@ -712,18 +717,19 @@ static const struct v4l2_subdev_core_ops hdmi_sd_core_ops = { static const struct v4l2_subdev_video_ops hdmi_sd_video_ops = { .s_dv_timings = hdmi_s_dv_timings, .g_dv_timings = hdmi_g_dv_timings, - .g_mbus_fmt = hdmi_g_mbus_fmt, .s_stream = hdmi_s_stream, }; static const struct v4l2_subdev_pad_ops hdmi_sd_pad_ops = { .enum_dv_timings = hdmi_enum_dv_timings, .dv_timings_cap = hdmi_dv_timings_cap, + .get_fmt = hdmi_get_fmt, }; static const struct v4l2_subdev_ops hdmi_sd_ops = { .core = &hdmi_sd_core_ops, .video = &hdmi_sd_video_ops, + .pad = &hdmi_sd_pad_ops, }; static int hdmi_runtime_suspend(struct device *dev) diff --git a/drivers/media/platform/s5p-tv/mixer_drv.c b/drivers/media/platform/s5p-tv/mixer_drv.c index 2a9501d7e7c8..5ef67774971d 100644 --- a/drivers/media/platform/s5p-tv/mixer_drv.c +++ b/drivers/media/platform/s5p-tv/mixer_drv.c @@ -46,11 +46,15 @@ void mxr_get_mbus_fmt(struct mxr_device *mdev, struct v4l2_mbus_framefmt *mbus_fmt) { struct v4l2_subdev *sd; + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; int ret; mutex_lock(&mdev->mutex); sd = to_outsd(mdev); - ret = v4l2_subdev_call(sd, video, g_mbus_fmt, mbus_fmt); + ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt); + *mbus_fmt = fmt.format; WARN(ret, "failed to get mbus_fmt for output %s\n", sd->name); mutex_unlock(&mdev->mutex); } @@ -62,7 +66,10 @@ void mxr_streamer_get(struct mxr_device *mdev) mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_streamer); if (mdev->n_streamer == 1) { struct v4l2_subdev *sd = to_outsd(mdev); - struct v4l2_mbus_framefmt mbus_fmt; + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct v4l2_mbus_framefmt *mbus_fmt = &fmt.format; struct mxr_resources *res = &mdev->res; int ret; @@ -72,12 +79,12 @@ void mxr_streamer_get(struct mxr_device *mdev) clk_set_parent(res->sclk_mixer, res->sclk_hdmi); mxr_reg_s_output(mdev, to_output(mdev)->cookie); - ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mbus_fmt); + ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt); WARN(ret, "failed to get mbus_fmt for output %s\n", sd->name); ret = v4l2_subdev_call(sd, video, s_stream, 1); WARN(ret, "starting stream failed for output %s\n", sd->name); - mxr_reg_set_mbus_fmt(mdev, &mbus_fmt); + mxr_reg_set_mbus_fmt(mdev, mbus_fmt); mxr_reg_streamon(mdev); ret = mxr_reg_wait4vsync(mdev); WARN(ret, "failed to get vsync (%d) from output\n", ret); diff --git a/drivers/media/platform/s5p-tv/sdo_drv.c b/drivers/media/platform/s5p-tv/sdo_drv.c index 3621af91d460..c75d4354d182 100644 --- a/drivers/media/platform/s5p-tv/sdo_drv.c +++ b/drivers/media/platform/s5p-tv/sdo_drv.c @@ -160,13 +160,17 @@ static int sdo_g_std_output(struct v4l2_subdev *sd, v4l2_std_id *std) return 0; } -static int sdo_g_mbus_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *fmt) +static int sdo_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *fmt = &format->format; struct sdo_device *sdev = sd_to_sdev(sd); if (!sdev->fmt) return -ENXIO; + if (format->pad) + return -EINVAL; /* all modes are 720 pixels wide */ fmt->width = 720; fmt->height = sdev->fmt->height; @@ -256,13 +260,17 @@ static const struct v4l2_subdev_video_ops sdo_sd_video_ops = { .s_std_output = sdo_s_std_output, .g_std_output = sdo_g_std_output, .g_tvnorms_output = sdo_g_tvnorms_output, - .g_mbus_fmt = sdo_g_mbus_fmt, .s_stream = sdo_s_stream, }; +static const struct v4l2_subdev_pad_ops sdo_sd_pad_ops = { + .get_fmt = sdo_get_fmt, +}; + static const struct v4l2_subdev_ops sdo_sd_ops = { .core = &sdo_sd_core_ops, .video = &sdo_sd_video_ops, + .pad = &sdo_sd_pad_ops, }; static int sdo_runtime_suspend(struct device *dev) diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c index b891b7f2b7e9..a1b426458719 100644 --- a/drivers/media/platform/soc_camera/mx2_camera.c +++ b/drivers/media/platform/soc_camera/mx2_camera.c @@ -912,7 +912,10 @@ static int mx2_camera_set_crop(struct soc_camera_device *icd, struct v4l2_crop a_writable = *a; struct v4l2_rect *rect = &a_writable.c; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - struct v4l2_mbus_framefmt mf; + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct v4l2_mbus_framefmt *mf = &fmt.format; int ret; soc_camera_limit_side(&rect->left, &rect->width, 0, 2, 4096); @@ -923,15 +926,15 @@ static int mx2_camera_set_crop(struct soc_camera_device *icd, return ret; /* The capture device might have changed its output */ - ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); + ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt); if (ret < 0) return ret; dev_dbg(icd->parent, "Sensor cropped %dx%d\n", - mf.width, mf.height); + mf->width, mf->height); - icd->user_width = mf.width; - icd->user_height = mf.height; + icd->user_width = mf->width; + icd->user_height = mf->height; return ret; } diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c index a29848976f92..6c34dbb878b2 100644 --- a/drivers/media/platform/soc_camera/mx3_camera.c +++ b/drivers/media/platform/soc_camera/mx3_camera.c @@ -804,7 +804,10 @@ static int mx3_camera_set_crop(struct soc_camera_device *icd, struct soc_camera_host *ici = to_soc_camera_host(icd->parent); struct mx3_camera_dev *mx3_cam = ici->priv; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - struct v4l2_mbus_framefmt mf; + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct v4l2_mbus_framefmt *mf = &fmt.format; int ret; soc_camera_limit_side(&rect->left, &rect->width, 0, 2, 4096); @@ -815,30 +818,30 @@ static int mx3_camera_set_crop(struct soc_camera_device *icd, return ret; /* The capture device might have changed its output sizes */ - ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); + ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt); if (ret < 0) return ret; - if (mf.code != icd->current_fmt->code) + if (mf->code != icd->current_fmt->code) return -EINVAL; - if (mf.width & 7) { + if (mf->width & 7) { /* Ouch! We can only handle 8-byte aligned width... */ - stride_align(&mf.width); - ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); + stride_align(&mf->width); + ret = v4l2_subdev_call(sd, video, s_mbus_fmt, mf); if (ret < 0) return ret; } - if (mf.width != icd->user_width || mf.height != icd->user_height) - configure_geometry(mx3_cam, mf.width, mf.height, + if (mf->width != icd->user_width || mf->height != icd->user_height) + configure_geometry(mx3_cam, mf->width, mf->height, icd->current_fmt->host_fmt); dev_dbg(icd->parent, "Sensor cropped %dx%d\n", - mf.width, mf.height); + mf->width, mf->height); - icd->user_width = mf.width; - icd->user_height = mf.height; + icd->user_width = mf->width; + icd->user_height = mf->height; return ret; } diff --git a/drivers/media/platform/soc_camera/omap1_camera.c b/drivers/media/platform/soc_camera/omap1_camera.c index 3f250767d162..6663645d1be4 100644 --- a/drivers/media/platform/soc_camera/omap1_camera.c +++ b/drivers/media/platform/soc_camera/omap1_camera.c @@ -1224,7 +1224,10 @@ static int omap1_cam_set_crop(struct soc_camera_device *icd, struct device *dev = icd->parent; struct soc_camera_host *ici = to_soc_camera_host(dev); struct omap1_cam_dev *pcdev = ici->priv; - struct v4l2_mbus_framefmt mf; + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct v4l2_mbus_framefmt *mf = &fmt.format; int ret; ret = subdev_call_with_sense(pcdev, dev, icd, sd, s_crop, crop); @@ -1234,32 +1237,32 @@ static int omap1_cam_set_crop(struct soc_camera_device *icd, return ret; } - ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); + ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt); if (ret < 0) { dev_warn(dev, "%s: failed to fetch current format\n", __func__); return ret; } - ret = dma_align(&mf.width, &mf.height, xlate->host_fmt, pcdev->vb_mode, + ret = dma_align(&mf->width, &mf->height, xlate->host_fmt, pcdev->vb_mode, false); if (ret < 0) { dev_err(dev, "%s: failed to align %ux%u %s with DMA\n", - __func__, mf.width, mf.height, + __func__, mf->width, mf->height, xlate->host_fmt->name); return ret; } if (!ret) { /* sensor returned geometry not DMA aligned, trying to fix */ - ret = set_mbus_format(pcdev, dev, icd, sd, &mf, xlate); + ret = set_mbus_format(pcdev, dev, icd, sd, mf, xlate); if (ret < 0) { dev_err(dev, "%s: failed to set format\n", __func__); return ret; } } - icd->user_width = mf.width; - icd->user_height = mf.height; + icd->user_width = mf->width; + icd->user_height = mf->height; return 0; } diff --git a/drivers/media/platform/soc_camera/pxa_camera.c b/drivers/media/platform/soc_camera/pxa_camera.c index f6fa0acc5251..48999f3cb2bb 100644 --- a/drivers/media/platform/soc_camera/pxa_camera.c +++ b/drivers/media/platform/soc_camera/pxa_camera.c @@ -1349,7 +1349,10 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd, .master_clock = pcdev->mclk, .pixel_clock_max = pcdev->ciclk / 4, }; - struct v4l2_mbus_framefmt mf; + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct v4l2_mbus_framefmt *mf = &fmt.format; struct pxa_cam *cam = icd->host_priv; u32 fourcc = icd->current_fmt->host_fmt->fourcc; int ret; @@ -1368,23 +1371,23 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd, return ret; } - ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); + ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt); if (ret < 0) return ret; - if (pxa_camera_check_frame(mf.width, mf.height)) { + if (pxa_camera_check_frame(mf->width, mf->height)) { /* * Camera cropping produced a frame beyond our capabilities. * FIXME: just extract a subframe, that we can process. */ - v4l_bound_align_image(&mf.width, 48, 2048, 1, - &mf.height, 32, 2048, 0, + v4l_bound_align_image(&mf->width, 48, 2048, 1, + &mf->height, 32, 2048, 0, fourcc == V4L2_PIX_FMT_YUV422P ? 4 : 0); - ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); + ret = v4l2_subdev_call(sd, video, s_mbus_fmt, mf); if (ret < 0) return ret; - if (pxa_camera_check_frame(mf.width, mf.height)) { + if (pxa_camera_check_frame(mf->width, mf->height)) { dev_warn(icd->parent, "Inconsistent state. Use S_FMT to repair\n"); return -EINVAL; @@ -1401,8 +1404,8 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd, recalculate_fifo_timeout(pcdev, sense.pixel_clock); } - icd->user_width = mf.width; - icd->user_height = mf.height; + icd->user_width = mf->width; + icd->user_height = mf->height; pxa_camera_setup_cicr(icd, cam->flags, fourcc); diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c index 8796bdce671f..08fa61099dde 100644 --- a/drivers/media/platform/soc_camera/rcar_vin.c +++ b/drivers/media/platform/soc_camera/rcar_vin.c @@ -1339,12 +1339,15 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx, return 0; if (!icd->host_priv) { - struct v4l2_mbus_framefmt mf; + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct v4l2_mbus_framefmt *mf = &fmt.format; struct v4l2_rect rect; struct device *dev = icd->parent; int shift; - ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); + ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt); if (ret < 0) return ret; @@ -1354,8 +1357,8 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx, /* Sensor driver doesn't support cropping */ rect.left = 0; rect.top = 0; - rect.width = mf.width; - rect.height = mf.height; + rect.width = mf->width; + rect.height = mf->height; } else if (ret < 0) { return ret; } @@ -1365,16 +1368,16 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx, * 1280x960, 640x480, 320x240 */ for (shift = 0; shift < 3; shift++) { - if (mf.width <= VIN_MAX_WIDTH && - mf.height <= VIN_MAX_HEIGHT) + if (mf->width <= VIN_MAX_WIDTH && + mf->height <= VIN_MAX_HEIGHT) break; - mf.width = 1280 >> shift; - mf.height = 960 >> shift; + mf->width = 1280 >> shift; + mf->height = 960 >> shift; ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd), video, s_mbus_fmt, - &mf); + mf); if (ret < 0) return ret; } @@ -1382,11 +1385,11 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx, if (shift == 3) { dev_err(dev, "Failed to configure the client below %ux%u\n", - mf.width, mf.height); + mf->width, mf->height); return -EIO; } - dev_dbg(dev, "camera fmt %ux%u\n", mf.width, mf.height); + dev_dbg(dev, "camera fmt %ux%u\n", mf->width, mf->height); cam = kzalloc(sizeof(*cam), GFP_KERNEL); if (!cam) @@ -1397,10 +1400,10 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx, */ cam->rect = rect; cam->subrect = rect; - cam->width = mf.width; - cam->height = mf.height; - cam->out_width = mf.width; - cam->out_height = mf.height; + cam->width = mf->width; + cam->height = mf->height; + cam->out_width = mf->width; + cam->out_height = mf->height; icd->host_priv = cam; } else { @@ -1468,7 +1471,10 @@ static int rcar_vin_set_crop(struct soc_camera_device *icd, struct v4l2_rect *cam_rect = &cam_crop.c; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct device *dev = icd->parent; - struct v4l2_mbus_framefmt mf; + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct v4l2_mbus_framefmt *mf = &fmt.format; u32 vnmc; int ret, i; @@ -1492,16 +1498,16 @@ static int rcar_vin_set_crop(struct soc_camera_device *icd, /* On success cam_crop contains current camera crop */ /* Retrieve camera output window */ - ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); + ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt); if (ret < 0) return ret; - if (mf.width > VIN_MAX_WIDTH || mf.height > VIN_MAX_HEIGHT) + if (mf->width > VIN_MAX_WIDTH || mf->height > VIN_MAX_HEIGHT) return -EINVAL; /* Cache camera output window */ - cam->width = mf.width; - cam->height = mf.height; + cam->width = mf->width; + cam->height = mf->height; icd->user_width = cam->width; icd->user_height = cam->height; diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index b4faf8f1fd15..566fd74c4639 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -1073,7 +1073,10 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int } if (!icd->host_priv) { - struct v4l2_mbus_framefmt mf; + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct v4l2_mbus_framefmt *mf = &fmt.format; struct v4l2_rect rect; int shift = 0; @@ -1091,7 +1094,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int return ret; /* First time */ - ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); + ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt); if (ret < 0) return ret; @@ -1102,14 +1105,14 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int * sizes, just try VGA multiples. If needed, this can be * adjusted in the future. */ - while ((mf.width > pcdev->max_width || - mf.height > pcdev->max_height) && shift < 4) { + while ((mf->width > pcdev->max_width || + mf->height > pcdev->max_height) && shift < 4) { /* Try 2560x1920, 1280x960, 640x480, 320x240 */ - mf.width = 2560 >> shift; - mf.height = 1920 >> shift; + mf->width = 2560 >> shift; + mf->height = 1920 >> shift; ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd), video, - s_mbus_fmt, &mf); + s_mbus_fmt, mf); if (ret < 0) return ret; shift++; @@ -1117,11 +1120,11 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int if (shift == 4) { dev_err(dev, "Failed to configure the client below %ux%x\n", - mf.width, mf.height); + mf->width, mf->height); return -EIO; } - dev_geo(dev, "camera fmt %ux%u\n", mf.width, mf.height); + dev_geo(dev, "camera fmt %ux%u\n", mf->width, mf->height); cam = kzalloc(sizeof(*cam), GFP_KERNEL); if (!cam) @@ -1131,8 +1134,8 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int cam->rect = rect; cam->subrect = rect; - cam->width = mf.width; - cam->height = mf.height; + cam->width = mf->width; + cam->height = mf->height; icd->host_priv = cam; } else { @@ -1217,7 +1220,10 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, struct sh_mobile_ceu_cam *cam = icd->host_priv; struct v4l2_rect *cam_rect = &cam_crop.c; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - struct v4l2_mbus_framefmt mf; + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct v4l2_mbus_framefmt *mf = &fmt.format; unsigned int scale_cam_h, scale_cam_v, scale_ceu_h, scale_ceu_v, out_width, out_height; int interm_width, interm_height; @@ -1247,16 +1253,16 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, /* On success cam_crop contains current camera crop */ /* 3. Retrieve camera output window */ - ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); + ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt); if (ret < 0) return ret; - if (mf.width > pcdev->max_width || mf.height > pcdev->max_height) + if (mf->width > pcdev->max_width || mf->height > pcdev->max_height) return -EINVAL; /* 4. Calculate camera scales */ - scale_cam_h = calc_generic_scale(cam_rect->width, mf.width); - scale_cam_v = calc_generic_scale(cam_rect->height, mf.height); + scale_cam_h = calc_generic_scale(cam_rect->width, mf->width); + scale_cam_v = calc_generic_scale(cam_rect->height, mf->height); /* Calculate intermediate window */ interm_width = scale_down(rect->width, scale_cam_h); @@ -1267,7 +1273,7 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, new_scale_h = calc_generic_scale(rect->width, icd->user_width); - mf.width = scale_down(cam_rect->width, new_scale_h); + mf->width = scale_down(cam_rect->width, new_scale_h); } if (interm_height < icd->user_height) { @@ -1275,26 +1281,26 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, new_scale_v = calc_generic_scale(rect->height, icd->user_height); - mf.height = scale_down(cam_rect->height, new_scale_v); + mf->height = scale_down(cam_rect->height, new_scale_v); } if (interm_width < icd->user_width || interm_height < icd->user_height) { ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd), video, - s_mbus_fmt, &mf); + s_mbus_fmt, mf); if (ret < 0) return ret; - dev_geo(dev, "New camera output %ux%u\n", mf.width, mf.height); - scale_cam_h = calc_generic_scale(cam_rect->width, mf.width); - scale_cam_v = calc_generic_scale(cam_rect->height, mf.height); + dev_geo(dev, "New camera output %ux%u\n", mf->width, mf->height); + scale_cam_h = calc_generic_scale(cam_rect->width, mf->width); + scale_cam_v = calc_generic_scale(cam_rect->height, mf->height); interm_width = scale_down(rect->width, scale_cam_h); interm_height = scale_down(rect->height, scale_cam_v); } /* Cache camera output window */ - cam->width = mf.width; - cam->height = mf.height; + cam->width = mf->width; + cam->height = mf->height; if (pcdev->image_mode) { out_width = min(interm_width, icd->user_width); diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index 7fd49cb009d3..d708df410f74 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -1289,7 +1289,10 @@ static struct soc_camera_device *soc_camera_add_pdev(struct soc_camera_async_cli static int soc_camera_probe_finish(struct soc_camera_device *icd) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - struct v4l2_mbus_framefmt mf; + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct v4l2_mbus_framefmt *mf = &fmt.format; int ret; sd->grp_id = soc_camera_grp_id(icd); @@ -1319,11 +1322,11 @@ static int soc_camera_probe_finish(struct soc_camera_device *icd) goto evidstart; /* Try to improve our guess of a reasonable window format */ - if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) { - icd->user_width = mf.width; - icd->user_height = mf.height; - icd->colorspace = mf.colorspace; - icd->field = mf.field; + if (!v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt)) { + icd->user_width = mf->width; + icd->user_height = mf->height; + icd->colorspace = mf->colorspace; + icd->field = mf->field; } soc_camera_remove_device(icd); diff --git a/drivers/media/platform/soc_camera/soc_camera_platform.c b/drivers/media/platform/soc_camera/soc_camera_platform.c index 934b9183cea8..cc8eb0758219 100644 --- a/drivers/media/platform/soc_camera/soc_camera_platform.c +++ b/drivers/media/platform/soc_camera/soc_camera_platform.c @@ -37,9 +37,11 @@ static int soc_camera_platform_s_stream(struct v4l2_subdev *sd, int enable) } static int soc_camera_platform_fill_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt *mf = &format->format; mf->width = p->format.width; mf->height = p->format.height; @@ -120,14 +122,13 @@ static struct v4l2_subdev_video_ops platform_subdev_video_ops = { .s_stream = soc_camera_platform_s_stream, .cropcap = soc_camera_platform_cropcap, .g_crop = soc_camera_platform_g_crop, - .try_mbus_fmt = soc_camera_platform_fill_fmt, - .g_mbus_fmt = soc_camera_platform_fill_fmt, - .s_mbus_fmt = soc_camera_platform_fill_fmt, .g_mbus_config = soc_camera_platform_g_mbus_config, }; static const struct v4l2_subdev_pad_ops platform_subdev_pad_ops = { .enum_mbus_code = soc_camera_platform_enum_mbus_code, + .get_fmt = soc_camera_platform_fill_fmt, + .set_fmt = soc_camera_platform_fill_fmt, }; static struct v4l2_subdev_ops platform_subdev_ops = { diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index c2eed99ebc78..67a8e4e58d9a 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -293,8 +293,6 @@ struct v4l2_mbus_frame_desc { g_dv_timings(): Get custom dv timings in the sub device. - g_mbus_fmt: get the current pixel format, provided by a video data source - try_mbus_fmt: try to set a pixel format on a video data source s_mbus_fmt: set a pixel format on a video data source @@ -336,8 +334,6 @@ struct v4l2_subdev_video_ops { struct v4l2_dv_timings *timings); int (*query_dv_timings)(struct v4l2_subdev *sd, struct v4l2_dv_timings *timings); - int (*g_mbus_fmt)(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *fmt); int (*try_mbus_fmt)(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt); int (*s_mbus_fmt)(struct v4l2_subdev *sd, -- cgit v1.2.3-59-g8ed1b From 717fd5b4907ada90ceb069d484068aaa01c58bb0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 9 Apr 2015 06:24:36 -0300 Subject: [media] v4l2: replace try_mbus_fmt by set_fmt The try_mbus_fmt video op is a duplicate of the pad op. Replace all uses in sub-devices by the set_fmt() pad op. Since try_mbus_fmt and s_mbus_fmt both map to the set_fmt pad op (but with a different 'which' argument), this patch will replace both try_mbus_fmt and s_mbus_fmt by set_fmt. Signed-off-by: Hans Verkuil Cc: Guennadi Liakhovetski Cc: Jonathan Corbet Cc: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7183.c | 36 ++++++++-------- drivers/media/i2c/mt9v011.c | 38 ++++++++--------- drivers/media/i2c/ov7670.c | 27 +++++++----- drivers/media/i2c/saa6752hs.c | 28 +++++++------ drivers/media/i2c/soc_camera/imx074.c | 39 ++++++++---------- drivers/media/i2c/soc_camera/mt9m001.c | 17 +++++--- drivers/media/i2c/soc_camera/mt9m111.c | 31 ++++++-------- drivers/media/i2c/soc_camera/mt9t031.c | 48 +++++++++++----------- drivers/media/i2c/soc_camera/mt9t112.c | 15 +++++-- drivers/media/i2c/soc_camera/mt9v022.c | 17 +++++--- drivers/media/i2c/soc_camera/ov2640.c | 36 +++++----------- drivers/media/i2c/soc_camera/ov5642.c | 34 +++++++-------- drivers/media/i2c/soc_camera/ov6650.c | 17 +++++--- drivers/media/i2c/soc_camera/ov772x.c | 15 +++++-- drivers/media/i2c/soc_camera/ov9640.c | 17 ++++++-- drivers/media/i2c/soc_camera/ov9740.c | 16 ++++++-- drivers/media/i2c/soc_camera/rj54n1cb0c.c | 40 +++++++----------- drivers/media/i2c/soc_camera/tw9910.c | 15 +++++-- drivers/media/i2c/sr030pc30.c | 38 ++++++++--------- drivers/media/i2c/vs6624.c | 28 ++++++------- drivers/media/platform/soc_camera/sh_mobile_csi2.c | 35 ++++++++-------- 21 files changed, 304 insertions(+), 283 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/adv7183.c b/drivers/media/i2c/adv7183.c index 9d58b750ef1e..e2dd1617662f 100644 --- a/drivers/media/i2c/adv7183.c +++ b/drivers/media/i2c/adv7183.c @@ -431,10 +431,15 @@ static int adv7183_enum_mbus_code(struct v4l2_subdev *sd, return 0; } -static int adv7183_try_mbus_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *fmt) +static int adv7183_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { struct adv7183 *decoder = to_adv7183(sd); + struct v4l2_mbus_framefmt *fmt = &format->format; + + if (format->pad) + return -EINVAL; fmt->code = MEDIA_BUS_FMT_UYVY8_2X8; fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; @@ -447,16 +452,10 @@ static int adv7183_try_mbus_fmt(struct v4l2_subdev *sd, fmt->width = 720; fmt->height = 576; } - return 0; -} - -static int adv7183_s_mbus_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *fmt) -{ - struct adv7183 *decoder = to_adv7183(sd); - - adv7183_try_mbus_fmt(sd, fmt); - decoder->fmt = *fmt; + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + decoder->fmt = *fmt; + else + cfg->try_fmt = *fmt; return 0; } @@ -519,14 +518,13 @@ static const struct v4l2_subdev_video_ops adv7183_video_ops = { .s_routing = adv7183_s_routing, .querystd = adv7183_querystd, .g_input_status = adv7183_g_input_status, - .try_mbus_fmt = adv7183_try_mbus_fmt, - .s_mbus_fmt = adv7183_s_mbus_fmt, .s_stream = adv7183_s_stream, }; static const struct v4l2_subdev_pad_ops adv7183_pad_ops = { .enum_mbus_code = adv7183_enum_mbus_code, .get_fmt = adv7183_get_fmt, + .set_fmt = adv7183_set_fmt, }; static const struct v4l2_subdev_ops adv7183_ops = { @@ -542,7 +540,9 @@ static int adv7183_probe(struct i2c_client *client, struct v4l2_subdev *sd; struct v4l2_ctrl_handler *hdl; int ret; - struct v4l2_mbus_framefmt fmt; + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; const unsigned *pin_array; /* Check if the adapter supports the needed features */ @@ -612,9 +612,9 @@ static int adv7183_probe(struct i2c_client *client, adv7183_writeregs(sd, adv7183_init_regs, ARRAY_SIZE(adv7183_init_regs)); adv7183_s_std(sd, decoder->std); - fmt.width = 720; - fmt.height = 576; - adv7183_s_mbus_fmt(sd, &fmt); + fmt.format.width = 720; + fmt.format.height = 576; + adv7183_set_fmt(sd, NULL, &fmt); /* initialize the hardware to the default control values */ ret = v4l2_ctrl_handler_setup(hdl); diff --git a/drivers/media/i2c/mt9v011.c b/drivers/media/i2c/mt9v011.c index 6fae8fce4617..57132cdba5ea 100644 --- a/drivers/media/i2c/mt9v011.c +++ b/drivers/media/i2c/mt9v011.c @@ -335,9 +335,14 @@ static int mt9v011_enum_mbus_code(struct v4l2_subdev *sd, return 0; } -static int mt9v011_try_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) +static int mt9v011_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { - if (fmt->code != MEDIA_BUS_FMT_SGRBG8_1X8) + struct v4l2_mbus_framefmt *fmt = &format->format; + struct mt9v011 *core = to_mt9v011(sd); + + if (format->pad || fmt->code != MEDIA_BUS_FMT_SGRBG8_1X8) return -EINVAL; v4l_bound_align_image(&fmt->width, 48, 639, 1, @@ -345,6 +350,15 @@ static int mt9v011_try_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefm fmt->field = V4L2_FIELD_NONE; fmt->colorspace = V4L2_COLORSPACE_SRGB; + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) { + core->width = fmt->width; + core->height = fmt->height; + + set_res(sd); + } else { + cfg->try_fmt = *fmt; + } + return 0; } @@ -386,23 +400,6 @@ static int mt9v011_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) return 0; } -static int mt9v011_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) -{ - struct mt9v011 *core = to_mt9v011(sd); - int rc; - - rc = mt9v011_try_mbus_fmt(sd, fmt); - if (rc < 0) - return -EINVAL; - - core->width = fmt->width; - core->height = fmt->height; - - set_res(sd); - - return 0; -} - #ifdef CONFIG_VIDEO_ADV_DEBUG static int mt9v011_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) @@ -470,14 +467,13 @@ static const struct v4l2_subdev_core_ops mt9v011_core_ops = { }; static const struct v4l2_subdev_video_ops mt9v011_video_ops = { - .try_mbus_fmt = mt9v011_try_mbus_fmt, - .s_mbus_fmt = mt9v011_s_mbus_fmt, .g_parm = mt9v011_g_parm, .s_parm = mt9v011_s_parm, }; static const struct v4l2_subdev_pad_ops mt9v011_pad_ops = { .enum_mbus_code = mt9v011_enum_mbus_code, + .set_fmt = mt9v011_set_fmt, }; static const struct v4l2_subdev_ops mt9v011_ops = { diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c index 5511208c8308..2d1e25f10973 100644 --- a/drivers/media/i2c/ov7670.c +++ b/drivers/media/i2c/ov7670.c @@ -971,17 +971,12 @@ static int ov7670_try_fmt_internal(struct v4l2_subdev *sd, return 0; } -static int ov7670_try_mbus_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *fmt) -{ - return ov7670_try_fmt_internal(sd, fmt, NULL, NULL); -} - /* * Set a format. */ -static int ov7670_s_mbus_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *fmt) +static int ov7670_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { struct ov7670_format_struct *ovfmt; struct ov7670_win_size *wsize; @@ -989,7 +984,18 @@ static int ov7670_s_mbus_fmt(struct v4l2_subdev *sd, unsigned char com7; int ret; - ret = ov7670_try_fmt_internal(sd, fmt, &ovfmt, &wsize); + if (format->pad) + return -EINVAL; + + if (format->which == V4L2_SUBDEV_FORMAT_TRY) { + ret = ov7670_try_fmt_internal(sd, &format->format, NULL, NULL); + if (ret) + return ret; + cfg->try_fmt = format->format; + return 0; + } + + ret = ov7670_try_fmt_internal(sd, &format->format, &ovfmt, &wsize); if (ret) return ret; @@ -1509,8 +1515,6 @@ static const struct v4l2_subdev_core_ops ov7670_core_ops = { }; static const struct v4l2_subdev_video_ops ov7670_video_ops = { - .try_mbus_fmt = ov7670_try_mbus_fmt, - .s_mbus_fmt = ov7670_s_mbus_fmt, .s_parm = ov7670_s_parm, .g_parm = ov7670_g_parm, }; @@ -1519,6 +1523,7 @@ static const struct v4l2_subdev_pad_ops ov7670_pad_ops = { .enum_frame_interval = ov7670_enum_frame_interval, .enum_frame_size = ov7670_enum_frame_size, .enum_mbus_code = ov7670_enum_mbus_code, + .set_fmt = ov7670_set_fmt, }; static const struct v4l2_subdev_ops ov7670_ops = { diff --git a/drivers/media/i2c/saa6752hs.c b/drivers/media/i2c/saa6752hs.c index b3829078d646..ba3c4156644d 100644 --- a/drivers/media/i2c/saa6752hs.c +++ b/drivers/media/i2c/saa6752hs.c @@ -574,10 +574,17 @@ static int saa6752hs_get_fmt(struct v4l2_subdev *sd, return 0; } -static int saa6752hs_try_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f) +static int saa6752hs_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *f = &format->format; + struct saa6752hs_state *h = to_state(sd); int dist_352, dist_480, dist_720; + if (format->pad) + return -EINVAL; + f->code = MEDIA_BUS_FMT_FIXED; dist_352 = abs(f->width - 352); @@ -598,15 +605,11 @@ static int saa6752hs_try_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_frame } f->field = V4L2_FIELD_INTERLACED; f->colorspace = V4L2_COLORSPACE_SMPTE170M; - return 0; -} -static int saa6752hs_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f) -{ - struct saa6752hs_state *h = to_state(sd); - - if (f->code != MEDIA_BUS_FMT_FIXED) - return -EINVAL; + if (format->which == V4L2_SUBDEV_FORMAT_TRY) { + cfg->try_fmt = *f; + return 0; + } /* FIXME: translate and round width/height into EMPRESS @@ -620,7 +623,9 @@ static int saa6752hs_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefm D1 | 720x576 | 720x480 */ - saa6752hs_try_mbus_fmt(sd, f); + if (f->code != MEDIA_BUS_FMT_FIXED) + return -EINVAL; + if (f->width == 720) h->video_format = SAA6752HS_VF_D1; else if (f->width == 480) @@ -653,12 +658,11 @@ static const struct v4l2_subdev_core_ops saa6752hs_core_ops = { static const struct v4l2_subdev_video_ops saa6752hs_video_ops = { .s_std = saa6752hs_s_std, - .s_mbus_fmt = saa6752hs_s_mbus_fmt, - .try_mbus_fmt = saa6752hs_try_mbus_fmt, }; static const struct v4l2_subdev_pad_ops saa6752hs_pad_ops = { .get_fmt = saa6752hs_get_fmt, + .set_fmt = saa6752hs_set_fmt, }; static const struct v4l2_subdev_ops saa6752hs_ops = { diff --git a/drivers/media/i2c/soc_camera/imx074.c b/drivers/media/i2c/soc_camera/imx074.c index ba60ccfffa4f..f68c2352c63c 100644 --- a/drivers/media/i2c/soc_camera/imx074.c +++ b/drivers/media/i2c/soc_camera/imx074.c @@ -153,14 +153,24 @@ static int reg_read(struct i2c_client *client, const u16 addr) return buf[0] & 0xff; /* no sign-extension */ } -static int imx074_try_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int imx074_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; const struct imx074_datafmt *fmt = imx074_find_datafmt(mf->code); + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct imx074 *priv = to_imx074(client); + + if (format->pad) + return -EINVAL; dev_dbg(sd->v4l2_dev->dev, "%s(%u)\n", __func__, mf->code); if (!fmt) { + /* MIPI CSI could have changed the format, double-check */ + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; mf->code = imx074_colour_fmts[0].code; mf->colorspace = imx074_colour_fmts[0].colorspace; } @@ -169,24 +179,10 @@ static int imx074_try_fmt(struct v4l2_subdev *sd, mf->height = IMX074_HEIGHT; mf->field = V4L2_FIELD_NONE; - return 0; -} - -static int imx074_s_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct imx074 *priv = to_imx074(client); - - dev_dbg(sd->v4l2_dev->dev, "%s(%u)\n", __func__, mf->code); - - /* MIPI CSI could have changed the format, double-check */ - if (!imx074_find_datafmt(mf->code)) - return -EINVAL; - - imx074_try_fmt(sd, mf); - - priv->fmt = imx074_find_datafmt(mf->code); + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + priv->fmt = imx074_find_datafmt(mf->code); + else + cfg->try_fmt = *mf; return 0; } @@ -282,8 +278,6 @@ static int imx074_g_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops imx074_subdev_video_ops = { .s_stream = imx074_s_stream, - .s_mbus_fmt = imx074_s_fmt, - .try_mbus_fmt = imx074_try_fmt, .g_crop = imx074_g_crop, .cropcap = imx074_cropcap, .g_mbus_config = imx074_g_mbus_config, @@ -296,6 +290,7 @@ static struct v4l2_subdev_core_ops imx074_subdev_core_ops = { static const struct v4l2_subdev_pad_ops imx074_subdev_pad_ops = { .enum_mbus_code = imx074_enum_mbus_code, .get_fmt = imx074_get_fmt, + .set_fmt = imx074_set_fmt, }; static struct v4l2_subdev_ops imx074_subdev_ops = { diff --git a/drivers/media/i2c/soc_camera/mt9m001.c b/drivers/media/i2c/soc_camera/mt9m001.c index 06f4e116978d..4fbdd1e9f7ee 100644 --- a/drivers/media/i2c/soc_camera/mt9m001.c +++ b/drivers/media/i2c/soc_camera/mt9m001.c @@ -205,7 +205,7 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) /* * The caller provides a supported format, as verified per - * call to .try_mbus_fmt() + * call to .set_fmt(FORMAT_TRY). */ if (!ret) ret = reg_write(client, MT9M001_COLUMN_START, rect.left); @@ -298,13 +298,18 @@ static int mt9m001_s_fmt(struct v4l2_subdev *sd, return ret; } -static int mt9m001_try_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int mt9m001_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9m001 *mt9m001 = to_mt9m001(client); const struct mt9m001_datafmt *fmt; + if (format->pad) + return -EINVAL; + v4l_bound_align_image(&mf->width, MT9M001_MIN_WIDTH, MT9M001_MAX_WIDTH, 1, &mf->height, MT9M001_MIN_HEIGHT + mt9m001->y_skip_top, @@ -322,6 +327,9 @@ static int mt9m001_try_fmt(struct v4l2_subdev *sd, mf->colorspace = fmt->colorspace; + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + return mt9m001_s_fmt(sd, mf); + cfg->try_fmt = *mf; return 0; } @@ -617,8 +625,6 @@ static int mt9m001_s_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = { .s_stream = mt9m001_s_stream, - .s_mbus_fmt = mt9m001_s_fmt, - .try_mbus_fmt = mt9m001_try_fmt, .s_crop = mt9m001_s_crop, .g_crop = mt9m001_g_crop, .cropcap = mt9m001_cropcap, @@ -633,6 +639,7 @@ static struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = { static const struct v4l2_subdev_pad_ops mt9m001_subdev_pad_ops = { .enum_mbus_code = mt9m001_enum_mbus_code, .get_fmt = mt9m001_get_fmt, + .set_fmt = mt9m001_set_fmt, }; static struct v4l2_subdev_ops mt9m001_subdev_ops = { diff --git a/drivers/media/i2c/soc_camera/mt9m111.c b/drivers/media/i2c/soc_camera/mt9m111.c index 7ac87b112a11..6dfaead6aaa8 100644 --- a/drivers/media/i2c/soc_camera/mt9m111.c +++ b/drivers/media/i2c/soc_camera/mt9m111.c @@ -536,14 +536,20 @@ static int mt9m111_set_pixfmt(struct mt9m111 *mt9m111, return ret; } -static int mt9m111_try_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int mt9m111_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev); const struct mt9m111_datafmt *fmt; struct v4l2_rect *rect = &mt9m111->rect; bool bayer; + int ret; + + if (format->pad) + return -EINVAL; fmt = mt9m111_find_datafmt(mt9m111, mf->code); @@ -577,20 +583,10 @@ static int mt9m111_try_fmt(struct v4l2_subdev *sd, mf->code = fmt->code; mf->colorspace = fmt->colorspace; - return 0; -} - -static int mt9m111_s_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) -{ - const struct mt9m111_datafmt *fmt; - struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev); - struct v4l2_rect *rect = &mt9m111->rect; - int ret; - - mt9m111_try_fmt(sd, mf); - fmt = mt9m111_find_datafmt(mt9m111, mf->code); - /* try_fmt() guarantees fmt != NULL && fmt->code == mf->code */ + if (format->which == V4L2_SUBDEV_FORMAT_TRY) { + cfg->try_fmt = *mf; + return 0; + } ret = mt9m111_setup_geometry(mt9m111, rect, mf->width, mf->height, mf->code); if (!ret) @@ -871,8 +867,6 @@ static int mt9m111_g_mbus_config(struct v4l2_subdev *sd, } static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = { - .s_mbus_fmt = mt9m111_s_fmt, - .try_mbus_fmt = mt9m111_try_fmt, .s_crop = mt9m111_s_crop, .g_crop = mt9m111_g_crop, .cropcap = mt9m111_cropcap, @@ -882,6 +876,7 @@ static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = { static const struct v4l2_subdev_pad_ops mt9m111_subdev_pad_ops = { .enum_mbus_code = mt9m111_enum_mbus_code, .get_fmt = mt9m111_get_fmt, + .set_fmt = mt9m111_set_fmt, }; static struct v4l2_subdev_ops mt9m111_subdev_ops = { diff --git a/drivers/media/i2c/soc_camera/mt9t031.c b/drivers/media/i2c/soc_camera/mt9t031.c index 97193e471ab5..3b6eeed2e2b9 100644 --- a/drivers/media/i2c/soc_camera/mt9t031.c +++ b/drivers/media/i2c/soc_camera/mt9t031.c @@ -264,7 +264,7 @@ static int mt9t031_set_params(struct i2c_client *client, /* * The caller provides a supported format, as guaranteed by - * .try_mbus_fmt(), soc_camera_s_crop() and soc_camera_cropcap() + * .set_fmt(FORMAT_TRY), soc_camera_s_crop() and soc_camera_cropcap() */ if (ret >= 0) ret = reg_write(client, MT9T031_COLUMN_START, rect->left); @@ -357,16 +357,36 @@ static int mt9t031_get_fmt(struct v4l2_subdev *sd, return 0; } -static int mt9t031_s_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +/* + * If a user window larger than sensor window is requested, we'll increase the + * sensor window. + */ +static int mt9t031_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9t031 *mt9t031 = to_mt9t031(client); u16 xskip, yskip; struct v4l2_rect rect = mt9t031->rect; + if (format->pad) + return -EINVAL; + + mf->code = MEDIA_BUS_FMT_SBGGR10_1X10; + mf->colorspace = V4L2_COLORSPACE_SRGB; + v4l_bound_align_image( + &mf->width, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH, 1, + &mf->height, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT, 1, 0); + + if (format->which == V4L2_SUBDEV_FORMAT_TRY) { + cfg->try_fmt = *mf; + return 0; + } + /* - * try_fmt has put width and height within limits. + * Width and height are within limits. * S_FMT: use binning and skipping for scaling */ xskip = mt9t031_skip(&rect.width, mf->width, MT9T031_MAX_WIDTH); @@ -379,23 +399,6 @@ static int mt9t031_s_fmt(struct v4l2_subdev *sd, return mt9t031_set_params(client, &rect, xskip, yskip); } -/* - * If a user window larger than sensor window is requested, we'll increase the - * sensor window. - */ -static int mt9t031_try_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) -{ - v4l_bound_align_image( - &mf->width, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH, 1, - &mf->height, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT, 1, 0); - - mf->code = MEDIA_BUS_FMT_SBGGR10_1X10; - mf->colorspace = V4L2_COLORSPACE_SRGB; - - return 0; -} - #ifdef CONFIG_VIDEO_ADV_DEBUG static int mt9t031_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) @@ -718,8 +721,6 @@ static int mt9t031_s_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = { .s_stream = mt9t031_s_stream, - .s_mbus_fmt = mt9t031_s_fmt, - .try_mbus_fmt = mt9t031_try_fmt, .s_crop = mt9t031_s_crop, .g_crop = mt9t031_g_crop, .cropcap = mt9t031_cropcap, @@ -734,6 +735,7 @@ static struct v4l2_subdev_sensor_ops mt9t031_subdev_sensor_ops = { static const struct v4l2_subdev_pad_ops mt9t031_subdev_pad_ops = { .enum_mbus_code = mt9t031_enum_mbus_code, .get_fmt = mt9t031_get_fmt, + .set_fmt = mt9t031_set_fmt, }; static struct v4l2_subdev_ops mt9t031_subdev_ops = { diff --git a/drivers/media/i2c/soc_camera/mt9t112.c b/drivers/media/i2c/soc_camera/mt9t112.c index 889e98ee8c62..de10a76ba6df 100644 --- a/drivers/media/i2c/soc_camera/mt9t112.c +++ b/drivers/media/i2c/soc_camera/mt9t112.c @@ -945,14 +945,19 @@ static int mt9t112_s_fmt(struct v4l2_subdev *sd, return ret; } -static int mt9t112_try_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int mt9t112_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9t112_priv *priv = to_mt9t112(client); unsigned int top, left; int i; + if (format->pad) + return -EINVAL; + for (i = 0; i < priv->num_formats; i++) if (mt9t112_cfmts[i].code == mf->code) break; @@ -968,6 +973,9 @@ static int mt9t112_try_fmt(struct v4l2_subdev *sd, mf->field = V4L2_FIELD_NONE; + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + return mt9t112_s_fmt(sd, mf); + cfg->try_fmt = *mf; return 0; } @@ -1016,8 +1024,6 @@ static int mt9t112_s_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = { .s_stream = mt9t112_s_stream, - .s_mbus_fmt = mt9t112_s_fmt, - .try_mbus_fmt = mt9t112_try_fmt, .cropcap = mt9t112_cropcap, .g_crop = mt9t112_g_crop, .s_crop = mt9t112_s_crop, @@ -1028,6 +1034,7 @@ static struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = { static const struct v4l2_subdev_pad_ops mt9t112_subdev_pad_ops = { .enum_mbus_code = mt9t112_enum_mbus_code, .get_fmt = mt9t112_get_fmt, + .set_fmt = mt9t112_set_fmt, }; /************************************************************************ diff --git a/drivers/media/i2c/soc_camera/mt9v022.c b/drivers/media/i2c/soc_camera/mt9v022.c index b4ba3c5930e3..f31377408550 100644 --- a/drivers/media/i2c/soc_camera/mt9v022.c +++ b/drivers/media/i2c/soc_camera/mt9v022.c @@ -412,7 +412,7 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd, /* * The caller provides a supported format, as verified per call to - * .try_mbus_fmt(), datawidth is from our supported format list + * .set_fmt(FORMAT_TRY), datawidth is from our supported format list */ switch (mf->code) { case MEDIA_BUS_FMT_Y8_1X8: @@ -442,15 +442,20 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd, return ret; } -static int mt9v022_try_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int mt9v022_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9v022 *mt9v022 = to_mt9v022(client); const struct mt9v022_datafmt *fmt; int align = mf->code == MEDIA_BUS_FMT_SBGGR8_1X8 || mf->code == MEDIA_BUS_FMT_SBGGR10_1X10; + if (format->pad) + return -EINVAL; + v4l_bound_align_image(&mf->width, MT9V022_MIN_WIDTH, MT9V022_MAX_WIDTH, align, &mf->height, MT9V022_MIN_HEIGHT + mt9v022->y_skip_top, @@ -465,6 +470,9 @@ static int mt9v022_try_fmt(struct v4l2_subdev *sd, mf->colorspace = fmt->colorspace; + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + return mt9v022_s_fmt(sd, mf); + cfg->try_fmt = *mf; return 0; } @@ -845,8 +853,6 @@ static int mt9v022_s_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = { .s_stream = mt9v022_s_stream, - .s_mbus_fmt = mt9v022_s_fmt, - .try_mbus_fmt = mt9v022_try_fmt, .s_crop = mt9v022_s_crop, .g_crop = mt9v022_g_crop, .cropcap = mt9v022_cropcap, @@ -861,6 +867,7 @@ static struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = { static const struct v4l2_subdev_pad_ops mt9v022_subdev_pad_ops = { .enum_mbus_code = mt9v022_enum_mbus_code, .get_fmt = mt9v022_get_fmt, + .set_fmt = mt9v022_set_fmt, }; static struct v4l2_subdev_ops mt9v022_subdev_ops = { diff --git a/drivers/media/i2c/soc_camera/ov2640.c b/drivers/media/i2c/soc_camera/ov2640.c index 0dffc63ee83f..9b4f5deec748 100644 --- a/drivers/media/i2c/soc_camera/ov2640.c +++ b/drivers/media/i2c/soc_camera/ov2640.c @@ -881,33 +881,16 @@ static int ov2640_get_fmt(struct v4l2_subdev *sd, return 0; } -static int ov2640_s_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int ov2640_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - - switch (mf->code) { - case MEDIA_BUS_FMT_RGB565_2X8_BE: - case MEDIA_BUS_FMT_RGB565_2X8_LE: - mf->colorspace = V4L2_COLORSPACE_SRGB; - break; - default: - mf->code = MEDIA_BUS_FMT_UYVY8_2X8; - case MEDIA_BUS_FMT_YUYV8_2X8: - case MEDIA_BUS_FMT_UYVY8_2X8: - mf->colorspace = V4L2_COLORSPACE_JPEG; - } - - ret = ov2640_set_params(client, &mf->width, &mf->height, mf->code); - - return ret; -} + if (format->pad) + return -EINVAL; -static int ov2640_try_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) -{ /* * select suitable win, but don't store it */ @@ -927,6 +910,10 @@ static int ov2640_try_fmt(struct v4l2_subdev *sd, mf->colorspace = V4L2_COLORSPACE_JPEG; } + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + return ov2640_set_params(client, &mf->width, + &mf->height, mf->code); + cfg->try_fmt = *mf; return 0; } @@ -1037,8 +1024,6 @@ static int ov2640_g_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = { .s_stream = ov2640_s_stream, - .s_mbus_fmt = ov2640_s_fmt, - .try_mbus_fmt = ov2640_try_fmt, .cropcap = ov2640_cropcap, .g_crop = ov2640_g_crop, .g_mbus_config = ov2640_g_mbus_config, @@ -1047,6 +1032,7 @@ static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = { static const struct v4l2_subdev_pad_ops ov2640_subdev_pad_ops = { .enum_mbus_code = ov2640_enum_mbus_code, .get_fmt = ov2640_get_fmt, + .set_fmt = ov2640_set_fmt, }; static struct v4l2_subdev_ops ov2640_subdev_ops = { diff --git a/drivers/media/i2c/soc_camera/ov5642.c b/drivers/media/i2c/soc_camera/ov5642.c index a88397f60b8c..bab9ac0c1764 100644 --- a/drivers/media/i2c/soc_camera/ov5642.c +++ b/drivers/media/i2c/soc_camera/ov5642.c @@ -786,39 +786,34 @@ static int ov5642_set_resolution(struct v4l2_subdev *sd) return ret; } -static int ov5642_try_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int ov5642_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; struct i2c_client *client = v4l2_get_subdevdata(sd); struct ov5642 *priv = to_ov5642(client); const struct ov5642_datafmt *fmt = ov5642_find_datafmt(mf->code); + if (format->pad) + return -EINVAL; + mf->width = priv->crop_rect.width; mf->height = priv->crop_rect.height; if (!fmt) { + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; mf->code = ov5642_colour_fmts[0].code; mf->colorspace = ov5642_colour_fmts[0].colorspace; } mf->field = V4L2_FIELD_NONE; - return 0; -} - -static int ov5642_s_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct ov5642 *priv = to_ov5642(client); - - /* MIPI CSI could have changed the format, double-check */ - if (!ov5642_find_datafmt(mf->code)) - return -EINVAL; - - ov5642_try_fmt(sd, mf); - priv->fmt = ov5642_find_datafmt(mf->code); - + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + priv->fmt = ov5642_find_datafmt(mf->code); + else + cfg->try_fmt = *mf; return 0; } @@ -945,8 +940,6 @@ static int ov5642_s_power(struct v4l2_subdev *sd, int on) } static struct v4l2_subdev_video_ops ov5642_subdev_video_ops = { - .s_mbus_fmt = ov5642_s_fmt, - .try_mbus_fmt = ov5642_try_fmt, .s_crop = ov5642_s_crop, .g_crop = ov5642_g_crop, .cropcap = ov5642_cropcap, @@ -956,6 +949,7 @@ static struct v4l2_subdev_video_ops ov5642_subdev_video_ops = { static const struct v4l2_subdev_pad_ops ov5642_subdev_pad_ops = { .enum_mbus_code = ov5642_enum_mbus_code, .get_fmt = ov5642_get_fmt, + .set_fmt = ov5642_set_fmt, }; static struct v4l2_subdev_core_ops ov5642_subdev_core_ops = { diff --git a/drivers/media/i2c/soc_camera/ov6650.c b/drivers/media/i2c/soc_camera/ov6650.c index 29f73a55a312..1f8af1ee8352 100644 --- a/drivers/media/i2c/soc_camera/ov6650.c +++ b/drivers/media/i2c/soc_camera/ov6650.c @@ -685,16 +685,20 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) mf->width = priv->rect.width >> half_scale; mf->height = priv->rect.height >> half_scale; } - return ret; } -static int ov6650_try_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int ov6650_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; struct i2c_client *client = v4l2_get_subdevdata(sd); struct ov6650 *priv = to_ov6650(client); + if (format->pad) + return -EINVAL; + if (is_unscaled_ok(mf->width, mf->height, &priv->rect)) v4l_bound_align_image(&mf->width, 2, W_CIF, 1, &mf->height, 2, H_CIF, 1, 0); @@ -718,6 +722,10 @@ static int ov6650_try_fmt(struct v4l2_subdev *sd, break; } + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + return ov6650_s_fmt(sd, mf); + cfg->try_fmt = *mf; + return 0; } @@ -935,8 +943,6 @@ static int ov6650_s_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops ov6650_video_ops = { .s_stream = ov6650_s_stream, - .s_mbus_fmt = ov6650_s_fmt, - .try_mbus_fmt = ov6650_try_fmt, .cropcap = ov6650_cropcap, .g_crop = ov6650_g_crop, .s_crop = ov6650_s_crop, @@ -949,6 +955,7 @@ static struct v4l2_subdev_video_ops ov6650_video_ops = { static const struct v4l2_subdev_pad_ops ov6650_pad_ops = { .enum_mbus_code = ov6650_enum_mbus_code, .get_fmt = ov6650_get_fmt, + .set_fmt = ov6650_set_fmt, }; static struct v4l2_subdev_ops ov6650_subdev_ops = { diff --git a/drivers/media/i2c/soc_camera/ov772x.c b/drivers/media/i2c/soc_camera/ov772x.c index 1db204451384..f150a8bd94dc 100644 --- a/drivers/media/i2c/soc_camera/ov772x.c +++ b/drivers/media/i2c/soc_camera/ov772x.c @@ -920,12 +920,17 @@ static int ov772x_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) return 0; } -static int ov772x_try_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int ov772x_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; const struct ov772x_color_format *cfmt; const struct ov772x_win_size *win; + if (format->pad) + return -EINVAL; + ov772x_select_params(mf, &cfmt, &win); mf->code = cfmt->code; @@ -934,6 +939,9 @@ static int ov772x_try_fmt(struct v4l2_subdev *sd, mf->field = V4L2_FIELD_NONE; mf->colorspace = cfmt->colorspace; + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + return ov772x_s_fmt(sd, mf); + cfg->try_fmt = *mf; return 0; } @@ -1022,8 +1030,6 @@ static int ov772x_g_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = { .s_stream = ov772x_s_stream, - .s_mbus_fmt = ov772x_s_fmt, - .try_mbus_fmt = ov772x_try_fmt, .cropcap = ov772x_cropcap, .g_crop = ov772x_g_crop, .g_mbus_config = ov772x_g_mbus_config, @@ -1032,6 +1038,7 @@ static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = { static const struct v4l2_subdev_pad_ops ov772x_subdev_pad_ops = { .enum_mbus_code = ov772x_enum_mbus_code, .get_fmt = ov772x_get_fmt, + .set_fmt = ov772x_set_fmt, }; static struct v4l2_subdev_ops ov772x_subdev_ops = { diff --git a/drivers/media/i2c/soc_camera/ov9640.c b/drivers/media/i2c/soc_camera/ov9640.c index 899b4d9352fe..8caae1c07541 100644 --- a/drivers/media/i2c/soc_camera/ov9640.c +++ b/drivers/media/i2c/soc_camera/ov9640.c @@ -519,9 +519,15 @@ static int ov9640_s_fmt(struct v4l2_subdev *sd, return ret; } -static int ov9640_try_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int ov9640_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; + + if (format->pad) + return -EINVAL; + ov9640_res_roundup(&mf->width, &mf->height); mf->field = V4L2_FIELD_NONE; @@ -537,6 +543,10 @@ static int ov9640_try_fmt(struct v4l2_subdev *sd, mf->colorspace = V4L2_COLORSPACE_JPEG; } + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + return ov9640_s_fmt(sd, mf); + + cfg->try_fmt = *mf; return 0; } @@ -657,8 +667,6 @@ static int ov9640_g_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops ov9640_video_ops = { .s_stream = ov9640_s_stream, - .s_mbus_fmt = ov9640_s_fmt, - .try_mbus_fmt = ov9640_try_fmt, .cropcap = ov9640_cropcap, .g_crop = ov9640_g_crop, .g_mbus_config = ov9640_g_mbus_config, @@ -666,6 +674,7 @@ static struct v4l2_subdev_video_ops ov9640_video_ops = { static const struct v4l2_subdev_pad_ops ov9640_pad_ops = { .enum_mbus_code = ov9640_enum_mbus_code, + .set_fmt = ov9640_set_fmt, }; static struct v4l2_subdev_ops ov9640_subdev_ops = { diff --git a/drivers/media/i2c/soc_camera/ov9740.c b/drivers/media/i2c/soc_camera/ov9740.c index 5d9b2492b7d2..03a7fc7316ae 100644 --- a/drivers/media/i2c/soc_camera/ov9740.c +++ b/drivers/media/i2c/soc_camera/ov9740.c @@ -704,15 +704,24 @@ static int ov9740_s_fmt(struct v4l2_subdev *sd, return ret; } -static int ov9740_try_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int ov9740_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; + + if (format->pad) + return -EINVAL; + ov9740_res_roundup(&mf->width, &mf->height); mf->field = V4L2_FIELD_NONE; mf->code = MEDIA_BUS_FMT_YUYV8_2X8; mf->colorspace = V4L2_COLORSPACE_SRGB; + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + return ov9740_s_fmt(sd, mf); + cfg->try_fmt = *mf; return 0; } @@ -905,8 +914,6 @@ static int ov9740_g_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops ov9740_video_ops = { .s_stream = ov9740_s_stream, - .s_mbus_fmt = ov9740_s_fmt, - .try_mbus_fmt = ov9740_try_fmt, .cropcap = ov9740_cropcap, .g_crop = ov9740_g_crop, .g_mbus_config = ov9740_g_mbus_config, @@ -922,6 +929,7 @@ static struct v4l2_subdev_core_ops ov9740_core_ops = { static const struct v4l2_subdev_pad_ops ov9740_pad_ops = { .enum_mbus_code = ov9740_enum_mbus_code, + .set_fmt = ov9740_set_fmt, }; static struct v4l2_subdev_ops ov9740_subdev_ops = { diff --git a/drivers/media/i2c/soc_camera/rj54n1cb0c.c b/drivers/media/i2c/soc_camera/rj54n1cb0c.c index 8787142493cc..c769cf663f84 100644 --- a/drivers/media/i2c/soc_camera/rj54n1cb0c.c +++ b/drivers/media/i2c/soc_camera/rj54n1cb0c.c @@ -965,17 +965,25 @@ static int rj54n1_reg_init(struct i2c_client *client) return ret; } -static int rj54n1_try_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int rj54n1_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; struct i2c_client *client = v4l2_get_subdevdata(sd); struct rj54n1 *rj54n1 = to_rj54n1(client); const struct rj54n1_datafmt *fmt; + int output_w, output_h, max_w, max_h, + input_w = rj54n1->rect.width, input_h = rj54n1->rect.height; int align = mf->code == MEDIA_BUS_FMT_SBGGR10_1X10 || mf->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE || mf->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE || mf->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE || mf->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE; + int ret; + + if (format->pad) + return -EINVAL; dev_dbg(&client->dev, "%s: code = %d, width = %u, height = %u\n", __func__, mf->code, mf->width, mf->height); @@ -993,24 +1001,10 @@ static int rj54n1_try_fmt(struct v4l2_subdev *sd, v4l_bound_align_image(&mf->width, 112, RJ54N1_MAX_WIDTH, align, &mf->height, 84, RJ54N1_MAX_HEIGHT, align, 0); - return 0; -} - -static int rj54n1_s_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct rj54n1 *rj54n1 = to_rj54n1(client); - const struct rj54n1_datafmt *fmt; - int output_w, output_h, max_w, max_h, - input_w = rj54n1->rect.width, input_h = rj54n1->rect.height; - int ret; - - /* - * The host driver can call us without .try_fmt(), so, we have to take - * care ourseleves - */ - rj54n1_try_fmt(sd, mf); + if (format->which == V4L2_SUBDEV_FORMAT_TRY) { + cfg->try_fmt = *mf; + return 0; + } /* * Verify if the sensor has just been powered on. TODO: replace this @@ -1026,9 +1020,6 @@ static int rj54n1_s_fmt(struct v4l2_subdev *sd, return ret; } - dev_dbg(&client->dev, "%s: code = %d, width = %u, height = %u\n", - __func__, mf->code, mf->width, mf->height); - /* RA_SEL_UL is only relevant for raw modes, ignored otherwise. */ switch (mf->code) { case MEDIA_BUS_FMT_YUYV8_2X8: @@ -1255,8 +1246,6 @@ static int rj54n1_s_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = { .s_stream = rj54n1_s_stream, - .s_mbus_fmt = rj54n1_s_fmt, - .try_mbus_fmt = rj54n1_try_fmt, .g_crop = rj54n1_g_crop, .s_crop = rj54n1_s_crop, .cropcap = rj54n1_cropcap, @@ -1267,6 +1256,7 @@ static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = { static const struct v4l2_subdev_pad_ops rj54n1_subdev_pad_ops = { .enum_mbus_code = rj54n1_enum_mbus_code, .get_fmt = rj54n1_get_fmt, + .set_fmt = rj54n1_set_fmt, }; static struct v4l2_subdev_ops rj54n1_subdev_ops = { diff --git a/drivers/media/i2c/soc_camera/tw9910.c b/drivers/media/i2c/soc_camera/tw9910.c index 95837959f409..42bec9bf1892 100644 --- a/drivers/media/i2c/soc_camera/tw9910.c +++ b/drivers/media/i2c/soc_camera/tw9910.c @@ -742,13 +742,18 @@ static int tw9910_s_fmt(struct v4l2_subdev *sd, return ret; } -static int tw9910_try_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int tw9910_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; struct i2c_client *client = v4l2_get_subdevdata(sd); struct tw9910_priv *priv = to_tw9910(client); const struct tw9910_scale_ctrl *scale; + if (format->pad) + return -EINVAL; + if (V4L2_FIELD_ANY == mf->field) { mf->field = V4L2_FIELD_INTERLACED_BT; } else if (V4L2_FIELD_INTERLACED_BT != mf->field) { @@ -769,6 +774,9 @@ static int tw9910_try_fmt(struct v4l2_subdev *sd, mf->width = scale->width; mf->height = scale->height; + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + return tw9910_s_fmt(sd, mf); + cfg->try_fmt = *mf; return 0; } @@ -886,8 +894,6 @@ static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = { .s_std = tw9910_s_std, .g_std = tw9910_g_std, .s_stream = tw9910_s_stream, - .s_mbus_fmt = tw9910_s_fmt, - .try_mbus_fmt = tw9910_try_fmt, .cropcap = tw9910_cropcap, .g_crop = tw9910_g_crop, .g_mbus_config = tw9910_g_mbus_config, @@ -898,6 +904,7 @@ static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = { static const struct v4l2_subdev_pad_ops tw9910_subdev_pad_ops = { .enum_mbus_code = tw9910_enum_mbus_code, .get_fmt = tw9910_get_fmt, + .set_fmt = tw9910_set_fmt, }; static struct v4l2_subdev_ops tw9910_subdev_ops = { diff --git a/drivers/media/i2c/sr030pc30.c b/drivers/media/i2c/sr030pc30.c index c0fa94570c4f..b62b6ddc4356 100644 --- a/drivers/media/i2c/sr030pc30.c +++ b/drivers/media/i2c/sr030pc30.c @@ -529,25 +529,28 @@ static const struct sr030pc30_format *try_fmt(struct v4l2_subdev *sd, } /* Return nearest media bus frame format. */ -static int sr030pc30_try_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int sr030pc30_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { - if (!sd || !mf) - return -EINVAL; - - try_fmt(sd, mf); - return 0; -} + struct sr030pc30_info *info = sd ? to_sr030pc30(sd) : NULL; + const struct sr030pc30_format *fmt; + struct v4l2_mbus_framefmt *mf; -static int sr030pc30_s_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) -{ - struct sr030pc30_info *info = to_sr030pc30(sd); + if (!sd || !format) + return -EINVAL; - if (!sd || !mf) + mf = &format->format; + if (format->pad) return -EINVAL; - info->curr_fmt = try_fmt(sd, mf); + fmt = try_fmt(sd, mf); + if (format->which == V4L2_SUBDEV_FORMAT_TRY) { + cfg->try_fmt = *mf; + return 0; + } + + info->curr_fmt = fmt; return sr030pc30_set_params(sd); } @@ -642,19 +645,14 @@ static const struct v4l2_subdev_core_ops sr030pc30_core_ops = { .querymenu = v4l2_subdev_querymenu, }; -static const struct v4l2_subdev_video_ops sr030pc30_video_ops = { - .s_mbus_fmt = sr030pc30_s_fmt, - .try_mbus_fmt = sr030pc30_try_fmt, -}; - static const struct v4l2_subdev_pad_ops sr030pc30_pad_ops = { .enum_mbus_code = sr030pc30_enum_mbus_code, .get_fmt = sr030pc30_get_fmt, + .set_fmt = sr030pc30_set_fmt, }; static const struct v4l2_subdev_ops sr030pc30_ops = { .core = &sr030pc30_core_ops, - .video = &sr030pc30_video_ops, .pad = &sr030pc30_pad_ops, }; diff --git a/drivers/media/i2c/vs6624.c b/drivers/media/i2c/vs6624.c index 59f733524620..4c72a18c0b8c 100644 --- a/drivers/media/i2c/vs6624.c +++ b/drivers/media/i2c/vs6624.c @@ -568,11 +568,17 @@ static int vs6624_enum_mbus_code(struct v4l2_subdev *sd, return 0; } -static int vs6624_try_mbus_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *fmt) +static int vs6624_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *fmt = &format->format; + struct vs6624 *sensor = to_vs6624(sd); int index; + if (format->pad) + return -EINVAL; + for (index = 0; index < ARRAY_SIZE(vs6624_formats); index++) if (vs6624_formats[index].mbus_code == fmt->code) break; @@ -591,18 +597,11 @@ static int vs6624_try_mbus_fmt(struct v4l2_subdev *sd, fmt->height = fmt->height & (~3); fmt->field = V4L2_FIELD_NONE; fmt->colorspace = vs6624_formats[index].colorspace; - return 0; -} -static int vs6624_s_mbus_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *fmt) -{ - struct vs6624 *sensor = to_vs6624(sd); - int ret; - - ret = vs6624_try_mbus_fmt(sd, fmt); - if (ret) - return ret; + if (format->which == V4L2_SUBDEV_FORMAT_TRY) { + cfg->try_fmt = *fmt; + return 0; + } /* set image format */ switch (fmt->code) { @@ -743,8 +742,6 @@ static const struct v4l2_subdev_core_ops vs6624_core_ops = { }; static const struct v4l2_subdev_video_ops vs6624_video_ops = { - .try_mbus_fmt = vs6624_try_mbus_fmt, - .s_mbus_fmt = vs6624_s_mbus_fmt, .s_parm = vs6624_s_parm, .g_parm = vs6624_g_parm, .s_stream = vs6624_s_stream, @@ -753,6 +750,7 @@ static const struct v4l2_subdev_video_ops vs6624_video_ops = { static const struct v4l2_subdev_pad_ops vs6624_pad_ops = { .enum_mbus_code = vs6624_enum_mbus_code, .get_fmt = vs6624_get_fmt, + .set_fmt = vs6624_set_fmt, }; static const struct v4l2_subdev_ops vs6624_ops = { diff --git a/drivers/media/platform/soc_camera/sh_mobile_csi2.c b/drivers/media/platform/soc_camera/sh_mobile_csi2.c index cd93241eb497..12d3626ecf22 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_csi2.c +++ b/drivers/media/platform/soc_camera/sh_mobile_csi2.c @@ -45,11 +45,17 @@ struct sh_csi2 { static void sh_csi2_hwinit(struct sh_csi2 *priv); -static int sh_csi2_try_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int sh_csi2_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev); struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data; + struct v4l2_mbus_framefmt *mf = &format->format; + u32 tmp = (priv->client->channel & 3) << 8; + + if (format->pad) + return -EINVAL; if (mf->width > 8188) mf->width = 8188; @@ -85,21 +91,11 @@ static int sh_csi2_try_fmt(struct v4l2_subdev *sd, break; } - return 0; -} - -/* - * We have done our best in try_fmt to try and tell the sensor, which formats - * we support. If now the configuration is unsuitable for us we can only - * error out. - */ -static int sh_csi2_s_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) -{ - struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev); - u32 tmp = (priv->client->channel & 3) << 8; + if (format->which == V4L2_SUBDEV_FORMAT_TRY) { + cfg->try_fmt = *mf; + return 0; + } - dev_dbg(sd->v4l2_dev->dev, "%s(%u)\n", __func__, mf->code); if (mf->width > 8188 || mf->width & 1) return -EINVAL; @@ -211,12 +207,14 @@ static int sh_csi2_s_mbus_config(struct v4l2_subdev *sd, } static struct v4l2_subdev_video_ops sh_csi2_subdev_video_ops = { - .s_mbus_fmt = sh_csi2_s_fmt, - .try_mbus_fmt = sh_csi2_try_fmt, .g_mbus_config = sh_csi2_g_mbus_config, .s_mbus_config = sh_csi2_s_mbus_config, }; +static struct v4l2_subdev_pad_ops sh_csi2_subdev_pad_ops = { + .set_fmt = sh_csi2_set_fmt, +}; + static void sh_csi2_hwinit(struct sh_csi2 *priv) { struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data; @@ -313,6 +311,7 @@ static struct v4l2_subdev_core_ops sh_csi2_subdev_core_ops = { static struct v4l2_subdev_ops sh_csi2_subdev_ops = { .core = &sh_csi2_subdev_core_ops, .video = &sh_csi2_subdev_video_ops, + .pad = &sh_csi2_subdev_pad_ops, }; static int sh_csi2_probe(struct platform_device *pdev) -- cgit v1.2.3-59-g8ed1b From 6e80c4738aa12701a5714cb3e4a685f95c1ffe5f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 21 Mar 2015 09:39:09 -0300 Subject: [media] v4l2: replace s_mbus_fmt by set_fmt The s_mbus_fmt video op is a duplicate of the pad op. Replace all uses in sub-devices by the set_fmt() pad op. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7170.c | 16 +++++++++++----- drivers/media/i2c/adv7175.c | 16 +++++++++++----- drivers/media/i2c/cx25840/cx25840-core.c | 15 ++++++++++++--- drivers/media/i2c/saa7115.c | 16 +++++++++++++--- drivers/media/i2c/saa717x.c | 16 +++++++++++++--- drivers/media/pci/cx18/cx18-av-core.c | 16 +++++++++++++--- drivers/media/usb/go7007/s2250-board.c | 18 +++++++++++++++--- 7 files changed, 88 insertions(+), 25 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/adv7170.c b/drivers/media/i2c/adv7170.c index 58d0a3cc0759..f0d3f5a2da46 100644 --- a/drivers/media/i2c/adv7170.c +++ b/drivers/media/i2c/adv7170.c @@ -296,11 +296,16 @@ static int adv7170_get_fmt(struct v4l2_subdev *sd, return 0; } -static int adv7170_s_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int adv7170_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; u8 val = adv7170_read(sd, 0x7); - int ret; + int ret = 0; + + if (format->pad) + return -EINVAL; switch (mf->code) { case MEDIA_BUS_FMT_UYVY8_2X8: @@ -317,7 +322,8 @@ static int adv7170_s_fmt(struct v4l2_subdev *sd, return -EINVAL; } - ret = adv7170_write(sd, 0x7, val); + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + ret = adv7170_write(sd, 0x7, val); return ret; } @@ -327,12 +333,12 @@ static int adv7170_s_fmt(struct v4l2_subdev *sd, static const struct v4l2_subdev_video_ops adv7170_video_ops = { .s_std_output = adv7170_s_std_output, .s_routing = adv7170_s_routing, - .s_mbus_fmt = adv7170_s_fmt, }; static const struct v4l2_subdev_pad_ops adv7170_pad_ops = { .enum_mbus_code = adv7170_enum_mbus_code, .get_fmt = adv7170_get_fmt, + .set_fmt = adv7170_set_fmt, }; static const struct v4l2_subdev_ops adv7170_ops = { diff --git a/drivers/media/i2c/adv7175.c b/drivers/media/i2c/adv7175.c index f7443454f682..321834ba8f57 100644 --- a/drivers/media/i2c/adv7175.c +++ b/drivers/media/i2c/adv7175.c @@ -334,11 +334,16 @@ static int adv7175_get_fmt(struct v4l2_subdev *sd, return 0; } -static int adv7175_s_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int adv7175_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; u8 val = adv7175_read(sd, 0x7); - int ret; + int ret = 0; + + if (format->pad) + return -EINVAL; switch (mf->code) { case MEDIA_BUS_FMT_UYVY8_2X8: @@ -355,7 +360,8 @@ static int adv7175_s_fmt(struct v4l2_subdev *sd, return -EINVAL; } - ret = adv7175_write(sd, 0x7, val); + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + ret = adv7175_write(sd, 0x7, val); return ret; } @@ -380,12 +386,12 @@ static const struct v4l2_subdev_core_ops adv7175_core_ops = { static const struct v4l2_subdev_video_ops adv7175_video_ops = { .s_std_output = adv7175_s_std_output, .s_routing = adv7175_s_routing, - .s_mbus_fmt = adv7175_s_fmt, }; static const struct v4l2_subdev_pad_ops adv7175_pad_ops = { .enum_mbus_code = adv7175_enum_mbus_code, .get_fmt = adv7175_get_fmt, + .set_fmt = adv7175_set_fmt, }; static const struct v4l2_subdev_ops adv7175_ops = { diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c index 18e3615737f2..e15a789ad596 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.c +++ b/drivers/media/i2c/cx25840/cx25840-core.c @@ -1366,14 +1366,17 @@ static int cx25840_s_ctrl(struct v4l2_ctrl *ctrl) /* ----------------------------------------------------------------------- */ -static int cx25840_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) +static int cx25840_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *fmt = &format->format; struct cx25840_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); int HSC, VSC, Vsrc, Hsrc, filter, Vlines; int is_50Hz = !(state->std & V4L2_STD_525_60); - if (fmt->code != MEDIA_BUS_FMT_FIXED) + if (format->pad || fmt->code != MEDIA_BUS_FMT_FIXED) return -EINVAL; fmt->field = V4L2_FIELD_INTERLACED; @@ -1403,6 +1406,8 @@ static int cx25840_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt fmt->width, fmt->height); return -ERANGE; } + if (format->which == V4L2_SUBDEV_FORMAT_TRY) + return 0; HSC = (Hsrc * (1 << 20)) / fmt->width - (1 << 20); VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9)); @@ -5068,7 +5073,6 @@ static const struct v4l2_subdev_video_ops cx25840_video_ops = { .s_std = cx25840_s_std, .g_std = cx25840_g_std, .s_routing = cx25840_s_video_routing, - .s_mbus_fmt = cx25840_s_mbus_fmt, .s_stream = cx25840_s_stream, .g_input_status = cx25840_g_input_status, }; @@ -5080,12 +5084,17 @@ static const struct v4l2_subdev_vbi_ops cx25840_vbi_ops = { .g_sliced_fmt = cx25840_g_sliced_fmt, }; +static const struct v4l2_subdev_pad_ops cx25840_pad_ops = { + .set_fmt = cx25840_set_fmt, +}; + static const struct v4l2_subdev_ops cx25840_ops = { .core = &cx25840_core_ops, .tuner = &cx25840_tuner_ops, .audio = &cx25840_audio_ops, .video = &cx25840_video_ops, .vbi = &cx25840_vbi_ops, + .pad = &cx25840_pad_ops, .ir = &cx25840_ir_ops, }; diff --git a/drivers/media/i2c/saa7115.c b/drivers/media/i2c/saa7115.c index 7147c8b68fac..0eae5f4471e2 100644 --- a/drivers/media/i2c/saa7115.c +++ b/drivers/media/i2c/saa7115.c @@ -1170,12 +1170,18 @@ static int saa711x_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f return 0; } -static int saa711x_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) +static int saa711x_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { - if (fmt->code != MEDIA_BUS_FMT_FIXED) + struct v4l2_mbus_framefmt *fmt = &format->format; + + if (format->pad || fmt->code != MEDIA_BUS_FMT_FIXED) return -EINVAL; fmt->field = V4L2_FIELD_INTERLACED; fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; + if (format->which == V4L2_SUBDEV_FORMAT_TRY) + return 0; return saa711x_set_size(sd, fmt->width, fmt->height); } @@ -1603,7 +1609,6 @@ static const struct v4l2_subdev_video_ops saa711x_video_ops = { .s_std = saa711x_s_std, .s_routing = saa711x_s_routing, .s_crystal_freq = saa711x_s_crystal_freq, - .s_mbus_fmt = saa711x_s_mbus_fmt, .s_stream = saa711x_s_stream, .querystd = saa711x_querystd, .g_input_status = saa711x_g_input_status, @@ -1617,12 +1622,17 @@ static const struct v4l2_subdev_vbi_ops saa711x_vbi_ops = { .s_raw_fmt = saa711x_s_raw_fmt, }; +static const struct v4l2_subdev_pad_ops saa711x_pad_ops = { + .set_fmt = saa711x_set_fmt, +}; + static const struct v4l2_subdev_ops saa711x_ops = { .core = &saa711x_core_ops, .tuner = &saa711x_tuner_ops, .audio = &saa711x_audio_ops, .video = &saa711x_video_ops, .vbi = &saa711x_vbi_ops, + .pad = &saa711x_pad_ops, }; #define CHIP_VER_SIZE 16 diff --git a/drivers/media/i2c/saa717x.c b/drivers/media/i2c/saa717x.c index 17557b2f1b09..7d517361e419 100644 --- a/drivers/media/i2c/saa717x.c +++ b/drivers/media/i2c/saa717x.c @@ -992,13 +992,16 @@ static int saa717x_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_regi } #endif -static int saa717x_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) +static int saa717x_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *fmt = &format->format; int prescale, h_scale, v_scale; v4l2_dbg(1, debug, sd, "decoder set size\n"); - if (fmt->code != MEDIA_BUS_FMT_FIXED) + if (format->pad || fmt->code != MEDIA_BUS_FMT_FIXED) return -EINVAL; /* FIXME need better bounds checking here */ @@ -1010,6 +1013,9 @@ static int saa717x_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt fmt->field = V4L2_FIELD_INTERLACED; fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; + if (format->which == V4L2_SUBDEV_FORMAT_TRY) + return 0; + /* scaling setting */ /* NTSC and interlace only */ prescale = SAA717X_NTSC_WIDTH / fmt->width; @@ -1217,7 +1223,6 @@ static const struct v4l2_subdev_tuner_ops saa717x_tuner_ops = { static const struct v4l2_subdev_video_ops saa717x_video_ops = { .s_std = saa717x_s_std, .s_routing = saa717x_s_video_routing, - .s_mbus_fmt = saa717x_s_mbus_fmt, .s_stream = saa717x_s_stream, }; @@ -1225,11 +1230,16 @@ static const struct v4l2_subdev_audio_ops saa717x_audio_ops = { .s_routing = saa717x_s_audio_routing, }; +static const struct v4l2_subdev_pad_ops saa717x_pad_ops = { + .set_fmt = saa717x_set_fmt, +}; + static const struct v4l2_subdev_ops saa717x_ops = { .core = &saa717x_core_ops, .tuner = &saa717x_tuner_ops, .audio = &saa717x_audio_ops, .video = &saa717x_video_ops, + .pad = &saa717x_pad_ops, }; /* ----------------------------------------------------------------------- */ diff --git a/drivers/media/pci/cx18/cx18-av-core.c b/drivers/media/pci/cx18/cx18-av-core.c index 5a55630d09db..30bbe8d1ea55 100644 --- a/drivers/media/pci/cx18/cx18-av-core.c +++ b/drivers/media/pci/cx18/cx18-av-core.c @@ -945,14 +945,17 @@ static int cx18_av_s_ctrl(struct v4l2_ctrl *ctrl) return 0; } -static int cx18_av_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) +static int cx18_av_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *fmt = &format->format; struct cx18_av_state *state = to_cx18_av_state(sd); struct cx18 *cx = v4l2_get_subdevdata(sd); int HSC, VSC, Vsrc, Hsrc, filter, Vlines; int is_50Hz = !(state->std & V4L2_STD_525_60); - if (fmt->code != MEDIA_BUS_FMT_FIXED) + if (format->pad || fmt->code != MEDIA_BUS_FMT_FIXED) return -EINVAL; fmt->field = V4L2_FIELD_INTERLACED; @@ -987,6 +990,9 @@ static int cx18_av_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt return -ERANGE; } + if (format->which == V4L2_SUBDEV_FORMAT_TRY) + return 0; + HSC = (Hsrc * (1 << 20)) / fmt->width - (1 << 20); VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9)); VSC &= 0x1fff; @@ -1285,7 +1291,6 @@ static const struct v4l2_subdev_video_ops cx18_av_video_ops = { .s_std = cx18_av_s_std, .s_routing = cx18_av_s_video_routing, .s_stream = cx18_av_s_stream, - .s_mbus_fmt = cx18_av_s_mbus_fmt, }; static const struct v4l2_subdev_vbi_ops cx18_av_vbi_ops = { @@ -1295,12 +1300,17 @@ static const struct v4l2_subdev_vbi_ops cx18_av_vbi_ops = { .s_raw_fmt = cx18_av_s_raw_fmt, }; +static const struct v4l2_subdev_pad_ops cx18_av_pad_ops = { + .set_fmt = cx18_av_set_fmt, +}; + static const struct v4l2_subdev_ops cx18_av_ops = { .core = &cx18_av_general_ops, .tuner = &cx18_av_tuner_ops, .audio = &cx18_av_audio_ops, .video = &cx18_av_video_ops, .vbi = &cx18_av_vbi_ops, + .pad = &cx18_av_pad_ops, }; int cx18_av_probe(struct cx18 *cx) diff --git a/drivers/media/usb/go7007/s2250-board.c b/drivers/media/usb/go7007/s2250-board.c index bb846680bcd4..5c2a49534d2b 100644 --- a/drivers/media/usb/go7007/s2250-board.c +++ b/drivers/media/usb/go7007/s2250-board.c @@ -405,12 +405,20 @@ static int s2250_s_ctrl(struct v4l2_ctrl *ctrl) return 0; } -static int s2250_s_mbus_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *fmt) +static int s2250_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *fmt = &format->format; struct s2250 *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); + if (format->pad) + return -EINVAL; + + if (format->which == V4L2_SUBDEV_FORMAT_TRY) + return 0; + if (fmt->height < 640) { write_reg_fp(client, 0x12b, state->reg12b_val | 0x400); write_reg_fp(client, 0x140, 0x060); @@ -479,13 +487,17 @@ static const struct v4l2_subdev_audio_ops s2250_audio_ops = { static const struct v4l2_subdev_video_ops s2250_video_ops = { .s_std = s2250_s_std, .s_routing = s2250_s_video_routing, - .s_mbus_fmt = s2250_s_mbus_fmt, +}; + +static const struct v4l2_subdev_pad_ops s2250_pad_ops = { + .set_fmt = s2250_set_fmt, }; static const struct v4l2_subdev_ops s2250_ops = { .core = &s2250_core_ops, .audio = &s2250_audio_ops, .video = &s2250_video_ops, + .pad = &s2250_pad_ops, }; /* --------------------------------------------------------------------------*/ -- cgit v1.2.3-59-g8ed1b From 5eab4983777ba913efb42dd0f177b0dcdbd4f3d9 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 9 Apr 2015 04:05:35 -0300 Subject: [media] v4l2: replace try_mbus_fmt by set_fmt in bridge drivers Replace all calls to try_mbus_fmt in bridge drivers by calls to the set_fmt pad op. [mchehab@osg.samsung.com: fix a merge conflict at mcam-core.c] Signed-off-by: Hans Verkuil Cc: Guennadi Liakhovetski Acked-by: Scott Jiang Cc: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-empress.c | 11 +++--- drivers/media/platform/blackfin/bfin_capture.c | 15 ++++---- drivers/media/platform/marvell-ccic/mcam-core.c | 11 +++--- drivers/media/platform/soc_camera/atmel-isi.c | 28 ++++++++------- drivers/media/platform/soc_camera/mx2_camera.c | 38 +++++++++++--------- drivers/media/platform/soc_camera/mx3_camera.c | 28 ++++++++------- drivers/media/platform/soc_camera/omap1_camera.c | 26 ++++++++------ drivers/media/platform/soc_camera/pxa_camera.c | 28 ++++++++------- drivers/media/platform/soc_camera/rcar_vin.c | 42 ++++++++++++---------- .../platform/soc_camera/sh_mobile_ceu_camera.c | 38 +++++++++++--------- drivers/media/platform/via-camera.c | 11 +++--- 11 files changed, 158 insertions(+), 118 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7134/saa7134-empress.c b/drivers/media/pci/saa7134/saa7134-empress.c index 22632f9e34e6..dc14930be909 100644 --- a/drivers/media/pci/saa7134/saa7134-empress.c +++ b/drivers/media/pci/saa7134/saa7134-empress.c @@ -157,11 +157,14 @@ static int empress_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct saa7134_dev *dev = video_drvdata(file); - struct v4l2_mbus_framefmt mbus_fmt; + struct v4l2_subdev_pad_config pad_cfg; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_TRY, + }; - v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, MEDIA_BUS_FMT_FIXED); - saa_call_all(dev, video, try_mbus_fmt, &mbus_fmt); - v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); + v4l2_fill_mbus_format(&format.format, &f->fmt.pix, MEDIA_BUS_FMT_FIXED); + saa_call_all(dev, pad, set_fmt, &pad_cfg, &format); + v4l2_fill_pix_format(&f->fmt.pix, &format.format); f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; diff --git a/drivers/media/platform/blackfin/bfin_capture.c b/drivers/media/platform/blackfin/bfin_capture.c index 6ea11b1e755e..aa50eba623c3 100644 --- a/drivers/media/platform/blackfin/bfin_capture.c +++ b/drivers/media/platform/blackfin/bfin_capture.c @@ -602,7 +602,10 @@ static int bcap_try_format(struct bcap_device *bcap, { struct bcap_format *sf = bcap->sensor_formats; struct bcap_format *fmt = NULL; - struct v4l2_mbus_framefmt mbus_fmt; + struct v4l2_subdev_pad_config pad_cfg; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_TRY, + }; int ret, i; for (i = 0; i < bcap->num_sensor_formats; i++) { @@ -613,16 +616,16 @@ static int bcap_try_format(struct bcap_device *bcap, if (i == bcap->num_sensor_formats) fmt = &sf[0]; - v4l2_fill_mbus_format(&mbus_fmt, pixfmt, fmt->mbus_code); - ret = v4l2_subdev_call(bcap->sd, video, - try_mbus_fmt, &mbus_fmt); + v4l2_fill_mbus_format(&format.format, pixfmt, fmt->mbus_code); + ret = v4l2_subdev_call(bcap->sd, pad, set_fmt, &pad_cfg, + &format); if (ret < 0) return ret; - v4l2_fill_pix_format(pixfmt, &mbus_fmt); + v4l2_fill_pix_format(pixfmt, &format.format); if (bcap_fmt) { for (i = 0; i < bcap->num_sensor_formats; i++) { fmt = &sf[i]; - if (mbus_fmt.code == fmt->mbus_code) + if (format.format.code == fmt->mbus_code) break; } *bcap_fmt = *fmt; diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index 42f63974592c..c2ebc12917a7 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -1351,14 +1351,17 @@ static int mcam_vidioc_try_fmt_vid_cap(struct file *filp, void *priv, struct mcam_camera *cam = video_drvdata(filp); struct mcam_format_struct *f; struct v4l2_pix_format *pix = &fmt->fmt.pix; - struct v4l2_mbus_framefmt mbus_fmt; + struct v4l2_subdev_pad_config pad_cfg; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_TRY, + }; int ret; f = mcam_find_format(pix->pixelformat); pix->pixelformat = f->pixelformat; - v4l2_fill_mbus_format(&mbus_fmt, pix, f->mbus_code); - ret = sensor_call(cam, video, try_mbus_fmt, &mbus_fmt); - v4l2_fill_pix_format(pix, &mbus_fmt); + v4l2_fill_mbus_format(&format.format, pix, f->mbus_code); + ret = sensor_call(cam, pad, set_fmt, &pad_cfg, &format); + v4l2_fill_pix_format(pix, &format.format); pix->bytesperline = pix->width * f->bpp; switch (f->pixelformat) { case V4L2_PIX_FMT_YUV420: diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index cbb7e22cab40..903dbf27d0e0 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -535,7 +535,11 @@ static int isi_camera_try_fmt(struct soc_camera_device *icd, struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = &f->fmt.pix; - struct v4l2_mbus_framefmt mf; + struct v4l2_subdev_pad_config pad_cfg; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_TRY, + }; + struct v4l2_mbus_framefmt *mf = &format.format; u32 pixfmt = pix->pixelformat; int ret; @@ -552,21 +556,21 @@ static int isi_camera_try_fmt(struct soc_camera_device *icd, pix->width = MAX_SUPPORT_WIDTH; /* limit to sensor capabilities */ - mf.width = pix->width; - mf.height = pix->height; - mf.field = pix->field; - mf.colorspace = pix->colorspace; - mf.code = xlate->code; + mf->width = pix->width; + mf->height = pix->height; + mf->field = pix->field; + mf->colorspace = pix->colorspace; + mf->code = xlate->code; - ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); + ret = v4l2_subdev_call(sd, pad, set_fmt, &pad_cfg, &format); if (ret < 0) return ret; - pix->width = mf.width; - pix->height = mf.height; - pix->colorspace = mf.colorspace; + pix->width = mf->width; + pix->height = mf->height; + pix->colorspace = mf->colorspace; - switch (mf.field) { + switch (mf->field) { case V4L2_FIELD_ANY: pix->field = V4L2_FIELD_NONE; break; @@ -574,7 +578,7 @@ static int isi_camera_try_fmt(struct soc_camera_device *icd, break; default: dev_err(icd->parent, "Field type %d unsupported.\n", - mf.field); + mf->field); ret = -EINVAL; } diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c index a1b426458719..d45f50a3a9eb 100644 --- a/drivers/media/platform/soc_camera/mx2_camera.c +++ b/drivers/media/platform/soc_camera/mx2_camera.c @@ -1187,7 +1187,11 @@ static int mx2_camera_try_fmt(struct soc_camera_device *icd, struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = &f->fmt.pix; - struct v4l2_mbus_framefmt mf; + struct v4l2_subdev_pad_config pad_cfg; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_TRY, + }; + struct v4l2_mbus_framefmt *mf = &format.format; __u32 pixfmt = pix->pixelformat; struct soc_camera_host *ici = to_soc_camera_host(icd->parent); struct mx2_camera_dev *pcdev = ici->priv; @@ -1210,13 +1214,13 @@ static int mx2_camera_try_fmt(struct soc_camera_device *icd, pix->width &= ~0x7; /* limit to sensor capabilities */ - mf.width = pix->width; - mf.height = pix->height; - mf.field = pix->field; - mf.colorspace = pix->colorspace; - mf.code = xlate->code; + mf->width = pix->width; + mf->height = pix->height; + mf->field = pix->field; + mf->colorspace = pix->colorspace; + mf->code = xlate->code; - ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); + ret = v4l2_subdev_call(sd, pad, set_fmt, &pad_cfg, &format); if (ret < 0) return ret; @@ -1227,29 +1231,29 @@ static int mx2_camera_try_fmt(struct soc_camera_device *icd, emma_prp = mx27_emma_prp_get_format(xlate->code, xlate->host_fmt->fourcc); - if ((mf.width != pix->width || mf.height != pix->height) && + if ((mf->width != pix->width || mf->height != pix->height) && emma_prp->cfg.in_fmt == PRP_CNTL_DATA_IN_YUV422) { - if (mx2_emmaprp_resize(pcdev, &mf, pix, false) < 0) + if (mx2_emmaprp_resize(pcdev, mf, pix, false) < 0) dev_dbg(icd->parent, "%s: can't resize\n", __func__); } - if (mf.field == V4L2_FIELD_ANY) - mf.field = V4L2_FIELD_NONE; + if (mf->field == V4L2_FIELD_ANY) + mf->field = V4L2_FIELD_NONE; /* * Driver supports interlaced images provided they have * both fields so that they can be processed as if they * were progressive. */ - if (mf.field != V4L2_FIELD_NONE && !V4L2_FIELD_HAS_BOTH(mf.field)) { + if (mf->field != V4L2_FIELD_NONE && !V4L2_FIELD_HAS_BOTH(mf->field)) { dev_err(icd->parent, "Field type %d unsupported.\n", - mf.field); + mf->field); return -EINVAL; } - pix->width = mf.width; - pix->height = mf.height; - pix->field = mf.field; - pix->colorspace = mf.colorspace; + pix->width = mf->width; + pix->height = mf->height; + pix->field = mf->field; + pix->colorspace = mf->colorspace; dev_dbg(icd->parent, "%s: returned params: width = %d, height = %d\n", __func__, pix->width, pix->height); diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c index 6c34dbb878b2..f63501771072 100644 --- a/drivers/media/platform/soc_camera/mx3_camera.c +++ b/drivers/media/platform/soc_camera/mx3_camera.c @@ -912,7 +912,11 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd, struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = &f->fmt.pix; - struct v4l2_mbus_framefmt mf; + struct v4l2_subdev_pad_config pad_cfg; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_TRY, + }; + struct v4l2_mbus_framefmt *mf = &format.format; __u32 pixfmt = pix->pixelformat; int ret; @@ -929,21 +933,21 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd, pix->width = 4096; /* limit to sensor capabilities */ - mf.width = pix->width; - mf.height = pix->height; - mf.field = pix->field; - mf.colorspace = pix->colorspace; - mf.code = xlate->code; + mf->width = pix->width; + mf->height = pix->height; + mf->field = pix->field; + mf->colorspace = pix->colorspace; + mf->code = xlate->code; - ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); + ret = v4l2_subdev_call(sd, pad, set_fmt, &pad_cfg, &format); if (ret < 0) return ret; - pix->width = mf.width; - pix->height = mf.height; - pix->colorspace = mf.colorspace; + pix->width = mf->width; + pix->height = mf->height; + pix->colorspace = mf->colorspace; - switch (mf.field) { + switch (mf->field) { case V4L2_FIELD_ANY: pix->field = V4L2_FIELD_NONE; break; @@ -951,7 +955,7 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd, break; default: dev_err(icd->parent, "Field type %d unsupported.\n", - mf.field); + mf->field); ret = -EINVAL; } diff --git a/drivers/media/platform/soc_camera/omap1_camera.c b/drivers/media/platform/soc_camera/omap1_camera.c index 6663645d1be4..2a715e1e22de 100644 --- a/drivers/media/platform/soc_camera/omap1_camera.c +++ b/drivers/media/platform/soc_camera/omap1_camera.c @@ -1322,7 +1322,11 @@ static int omap1_cam_try_fmt(struct soc_camera_device *icd, struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = &f->fmt.pix; - struct v4l2_mbus_framefmt mf; + struct v4l2_subdev_pad_config pad_cfg; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_TRY, + }; + struct v4l2_mbus_framefmt *mf = &format.format; int ret; /* TODO: limit to mx1 hardware capabilities */ @@ -1333,21 +1337,21 @@ static int omap1_cam_try_fmt(struct soc_camera_device *icd, return -EINVAL; } - mf.width = pix->width; - mf.height = pix->height; - mf.field = pix->field; - mf.colorspace = pix->colorspace; - mf.code = xlate->code; + mf->width = pix->width; + mf->height = pix->height; + mf->field = pix->field; + mf->colorspace = pix->colorspace; + mf->code = xlate->code; /* limit to sensor capabilities */ - ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); + ret = v4l2_subdev_call(sd, pad, set_fmt, &pad_cfg, &format); if (ret < 0) return ret; - pix->width = mf.width; - pix->height = mf.height; - pix->field = mf.field; - pix->colorspace = mf.colorspace; + pix->width = mf->width; + pix->height = mf->height; + pix->field = mf->field; + pix->colorspace = mf->colorspace; return 0; } diff --git a/drivers/media/platform/soc_camera/pxa_camera.c b/drivers/media/platform/soc_camera/pxa_camera.c index 48999f3cb2bb..7ccd76f7ca1a 100644 --- a/drivers/media/platform/soc_camera/pxa_camera.c +++ b/drivers/media/platform/soc_camera/pxa_camera.c @@ -1488,7 +1488,11 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd, struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = &f->fmt.pix; - struct v4l2_mbus_framefmt mf; + struct v4l2_subdev_pad_config pad_cfg; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_TRY, + }; + struct v4l2_mbus_framefmt *mf = &format.format; __u32 pixfmt = pix->pixelformat; int ret; @@ -1509,22 +1513,22 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd, pixfmt == V4L2_PIX_FMT_YUV422P ? 4 : 0); /* limit to sensor capabilities */ - mf.width = pix->width; - mf.height = pix->height; + mf->width = pix->width; + mf->height = pix->height; /* Only progressive video supported so far */ - mf.field = V4L2_FIELD_NONE; - mf.colorspace = pix->colorspace; - mf.code = xlate->code; + mf->field = V4L2_FIELD_NONE; + mf->colorspace = pix->colorspace; + mf->code = xlate->code; - ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); + ret = v4l2_subdev_call(sd, pad, set_fmt, &pad_cfg, &format); if (ret < 0) return ret; - pix->width = mf.width; - pix->height = mf.height; - pix->colorspace = mf.colorspace; + pix->width = mf->width; + pix->height = mf->height; + pix->colorspace = mf->colorspace; - switch (mf.field) { + switch (mf->field) { case V4L2_FIELD_ANY: case V4L2_FIELD_NONE: pix->field = V4L2_FIELD_NONE; @@ -1532,7 +1536,7 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd, default: /* TODO: support interlaced at least in pass-through mode */ dev_err(icd->parent, "Field type %d unsupported.\n", - mf.field); + mf->field); return -EINVAL; } diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c index 08fa61099dde..063285a8dcf5 100644 --- a/drivers/media/platform/soc_camera/rcar_vin.c +++ b/drivers/media/platform/soc_camera/rcar_vin.c @@ -1683,7 +1683,11 @@ static int rcar_vin_try_fmt(struct soc_camera_device *icd, const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = &f->fmt.pix; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - struct v4l2_mbus_framefmt mf; + struct v4l2_subdev_pad_config pad_cfg; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_TRY, + }; + struct v4l2_mbus_framefmt *mf = &format.format; __u32 pixfmt = pix->pixelformat; int width, height; int ret; @@ -1710,25 +1714,25 @@ static int rcar_vin_try_fmt(struct soc_camera_device *icd, pix->sizeimage = 0; /* limit to sensor capabilities */ - mf.width = pix->width; - mf.height = pix->height; - mf.field = pix->field; - mf.code = xlate->code; - mf.colorspace = pix->colorspace; + mf->width = pix->width; + mf->height = pix->height; + mf->field = pix->field; + mf->code = xlate->code; + mf->colorspace = pix->colorspace; ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd), - video, try_mbus_fmt, &mf); + pad, set_fmt, &pad_cfg, &format); if (ret < 0) return ret; /* Adjust only if VIN cannot scale */ - if (pix->width > mf.width * 2) - pix->width = mf.width * 2; - if (pix->height > mf.height * 3) - pix->height = mf.height * 3; + if (pix->width > mf->width * 2) + pix->width = mf->width * 2; + if (pix->height > mf->height * 3) + pix->height = mf->height * 3; - pix->field = mf.field; - pix->colorspace = mf.colorspace; + pix->field = mf->field; + pix->colorspace = mf->colorspace; if (pixfmt == V4L2_PIX_FMT_NV16) { /* FIXME: check against rect_max after converting soc-camera */ @@ -1739,12 +1743,12 @@ static int rcar_vin_try_fmt(struct soc_camera_device *icd, * requested a bigger rectangle, it will not return a * smaller one. */ - mf.width = VIN_MAX_WIDTH; - mf.height = VIN_MAX_HEIGHT; + mf->width = VIN_MAX_WIDTH; + mf->height = VIN_MAX_HEIGHT; ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd), - video, try_mbus_fmt, - &mf); + pad, set_fmt, &pad_cfg, + &format); if (ret < 0) { dev_err(icd->parent, "client try_fmt() = %d\n", ret); @@ -1752,9 +1756,9 @@ static int rcar_vin_try_fmt(struct soc_camera_device *icd, } } /* We will scale exactly */ - if (mf.width > width) + if (mf->width > width) pix->width = width; - if (mf.height > height) + if (mf->height > height) pix->height = height; } diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 566fd74c4639..91c48ab6cd13 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -1499,7 +1499,11 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = &f->fmt.pix; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - struct v4l2_mbus_framefmt mf; + struct v4l2_subdev_pad_config pad_cfg; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_TRY, + }; + struct v4l2_mbus_framefmt *mf = &format.format; __u32 pixfmt = pix->pixelformat; int width, height; int ret; @@ -1527,21 +1531,21 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, height = pix->height; /* limit to sensor capabilities */ - mf.width = pix->width; - mf.height = pix->height; - mf.field = pix->field; - mf.code = xlate->code; - mf.colorspace = pix->colorspace; + mf->width = pix->width; + mf->height = pix->height; + mf->field = pix->field; + mf->code = xlate->code; + mf->colorspace = pix->colorspace; ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd), - video, try_mbus_fmt, &mf); + pad, set_fmt, &pad_cfg, &format); if (ret < 0) return ret; - pix->width = mf.width; - pix->height = mf.height; - pix->field = mf.field; - pix->colorspace = mf.colorspace; + pix->width = mf->width; + pix->height = mf->height; + pix->field = mf->field; + pix->colorspace = mf->colorspace; switch (pixfmt) { case V4L2_PIX_FMT_NV12: @@ -1556,11 +1560,11 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, * requested a bigger rectangle, it will not return a * smaller one. */ - mf.width = pcdev->max_width; - mf.height = pcdev->max_height; + mf->width = pcdev->max_width; + mf->height = pcdev->max_height; ret = v4l2_device_call_until_err(sd->v4l2_dev, - soc_camera_grp_id(icd), video, - try_mbus_fmt, &mf); + soc_camera_grp_id(icd), pad, + set_fmt, &pad_cfg, &format); if (ret < 0) { /* Shouldn't actually happen... */ dev_err(icd->parent, @@ -1569,9 +1573,9 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, } } /* We will scale exactly */ - if (mf.width > width) + if (mf->width > width) pix->width = width; - if (mf.height > height) + if (mf->height > height) pix->height = height; pix->bytesperline = max(pix->bytesperline, pix->width); diff --git a/drivers/media/platform/via-camera.c b/drivers/media/platform/via-camera.c index 678ed9f353cb..6331d6b99d23 100644 --- a/drivers/media/platform/via-camera.c +++ b/drivers/media/platform/via-camera.c @@ -903,14 +903,17 @@ static int viacam_do_try_fmt(struct via_camera *cam, struct v4l2_pix_format *upix, struct v4l2_pix_format *spix) { int ret; - struct v4l2_mbus_framefmt mbus_fmt; + struct v4l2_subdev_pad_config pad_cfg; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_TRY, + }; struct via_format *f = via_find_format(upix->pixelformat); upix->pixelformat = f->pixelformat; viacam_fmt_pre(upix, spix); - v4l2_fill_mbus_format(&mbus_fmt, spix, f->mbus_code); - ret = sensor_call(cam, video, try_mbus_fmt, &mbus_fmt); - v4l2_fill_pix_format(spix, &mbus_fmt); + v4l2_fill_mbus_format(&format.format, spix, f->mbus_code); + ret = sensor_call(cam, pad, set_fmt, &pad_cfg, &format); + v4l2_fill_pix_format(spix, &format.format); viacam_fmt_post(upix, spix); return ret; } -- cgit v1.2.3-59-g8ed1b From ebf984bb151e9952cccd060d3aba0b4d30a87e81 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 9 Apr 2015 04:05:59 -0300 Subject: [media] v4l2: replace s_mbus_fmt by set_fmt in bridge drivers Replace all calls to s_mbus_fmt in bridge drivers by calls to the set_fmt pad op. Remove the old try/s_mbus_fmt video ops since they are now no longer used. Signed-off-by: Hans Verkuil Cc: Guennadi Liakhovetski Acked-by: Prabhakar Lad Acked-by: Scott Jiang Cc: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx18/cx18-controls.c | 13 +++-- drivers/media/pci/cx18/cx18-ioctl.c | 12 +++-- drivers/media/pci/cx23885/cx23885-video.c | 12 +++-- drivers/media/pci/ivtv/ivtv-controls.c | 12 +++-- drivers/media/pci/ivtv/ivtv-ioctl.c | 12 +++-- drivers/media/pci/saa7134/saa7134-empress.c | 10 ++-- drivers/media/platform/am437x/am437x-vpfe.c | 19 ++----- drivers/media/platform/blackfin/bfin_capture.c | 8 +-- drivers/media/platform/marvell-ccic/mcam-core.c | 8 +-- drivers/media/platform/sh_vou.c | 61 ++++++++++++---------- drivers/media/platform/soc_camera/atmel-isi.c | 27 +++++----- drivers/media/platform/soc_camera/mx2_camera.c | 35 +++++++------ drivers/media/platform/soc_camera/mx3_camera.c | 31 ++++++----- drivers/media/platform/soc_camera/omap1_camera.c | 44 +++++++++------- drivers/media/platform/soc_camera/pxa_camera.c | 33 ++++++------ drivers/media/platform/soc_camera/rcar_vin.c | 4 +- .../platform/soc_camera/sh_mobile_ceu_camera.c | 8 +-- drivers/media/platform/soc_camera/soc_scale_crop.c | 37 +++++++------ drivers/media/platform/via-camera.c | 8 +-- drivers/media/usb/cx231xx/cx231xx-417.c | 12 +++-- drivers/media/usb/cx231xx/cx231xx-video.c | 23 ++++---- drivers/media/usb/em28xx/em28xx-camera.c | 12 +++-- drivers/media/usb/go7007/go7007-v4l2.c | 12 +++-- drivers/media/usb/pvrusb2/pvrusb2-hdw.c | 17 +++--- include/media/v4l2-subdev.h | 8 --- 25 files changed, 256 insertions(+), 222 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/cx18/cx18-controls.c b/drivers/media/pci/cx18/cx18-controls.c index 4aeb7c6b8ce1..71227a155cba 100644 --- a/drivers/media/pci/cx18/cx18-controls.c +++ b/drivers/media/pci/cx18/cx18-controls.c @@ -93,13 +93,16 @@ static int cx18_s_video_encoding(struct cx2341x_handler *cxhdl, u32 val) { struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl); int is_mpeg1 = val == V4L2_MPEG_VIDEO_ENCODING_MPEG_1; - struct v4l2_mbus_framefmt fmt; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct v4l2_mbus_framefmt *fmt = &format.format; /* fix videodecoder resolution */ - fmt.width = cxhdl->width / (is_mpeg1 ? 2 : 1); - fmt.height = cxhdl->height; - fmt.code = MEDIA_BUS_FMT_FIXED; - v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &fmt); + fmt->width = cxhdl->width / (is_mpeg1 ? 2 : 1); + fmt->height = cxhdl->height; + fmt->code = MEDIA_BUS_FMT_FIXED; + v4l2_subdev_call(cx->sd_av, pad, set_fmt, NULL, &format); return 0; } diff --git a/drivers/media/pci/cx18/cx18-ioctl.c b/drivers/media/pci/cx18/cx18-ioctl.c index 79aee30d5fd8..55525af1f482 100644 --- a/drivers/media/pci/cx18/cx18-ioctl.c +++ b/drivers/media/pci/cx18/cx18-ioctl.c @@ -267,7 +267,9 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh, { struct cx18_open_id *id = fh2id(fh); struct cx18 *cx = id->cx; - struct v4l2_mbus_framefmt mbus_fmt; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; struct cx18_stream *s = &cx->streams[id->type]; int ret; int w, h; @@ -296,10 +298,10 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh, s->vb_bytes_per_line = 1440; /* Packed */ } - mbus_fmt.width = cx->cxhdl.width = w; - mbus_fmt.height = cx->cxhdl.height = h; - mbus_fmt.code = MEDIA_BUS_FMT_FIXED; - v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &mbus_fmt); + format.format.width = cx->cxhdl.width = w; + format.format.height = cx->cxhdl.height = h; + format.format.code = MEDIA_BUS_FMT_FIXED; + v4l2_subdev_call(cx->sd_av, pad, set_fmt, NULL, &format); return cx18_g_fmt_vid_cap(file, fh, fmt); } diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c index 2232b389c441..ec76470d12a4 100644 --- a/drivers/media/pci/cx23885/cx23885-video.c +++ b/drivers/media/pci/cx23885/cx23885-video.c @@ -581,7 +581,9 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct cx23885_dev *dev = video_drvdata(file); - struct v4l2_mbus_framefmt mbus_fmt; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; int err; dprintk(2, "%s()\n", __func__); @@ -600,10 +602,10 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, dev->field = f->fmt.pix.field; dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, dev->width, dev->height, dev->field); - v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, MEDIA_BUS_FMT_FIXED); - call_all(dev, video, s_mbus_fmt, &mbus_fmt); - v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); - /* s_mbus_fmt overwrites f->fmt.pix.field, restore it */ + v4l2_fill_mbus_format(&format.format, &f->fmt.pix, MEDIA_BUS_FMT_FIXED); + call_all(dev, pad, set_fmt, NULL, &format); + v4l2_fill_pix_format(&f->fmt.pix, &format.format); + /* set_fmt overwrites f->fmt.pix.field, restore it */ f->fmt.pix.field = dev->field; return 0; } diff --git a/drivers/media/pci/ivtv/ivtv-controls.c b/drivers/media/pci/ivtv/ivtv-controls.c index ccf548c255f1..8a55ccb8f0c9 100644 --- a/drivers/media/pci/ivtv/ivtv-controls.c +++ b/drivers/media/pci/ivtv/ivtv-controls.c @@ -64,13 +64,15 @@ static int ivtv_s_video_encoding(struct cx2341x_handler *cxhdl, u32 val) { struct ivtv *itv = container_of(cxhdl, struct ivtv, cxhdl); int is_mpeg1 = val == V4L2_MPEG_VIDEO_ENCODING_MPEG_1; - struct v4l2_mbus_framefmt fmt; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; /* fix videodecoder resolution */ - fmt.width = cxhdl->width / (is_mpeg1 ? 2 : 1); - fmt.height = cxhdl->height; - fmt.code = MEDIA_BUS_FMT_FIXED; - v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &fmt); + format.format.width = cxhdl->width / (is_mpeg1 ? 2 : 1); + format.format.height = cxhdl->height; + format.format.code = MEDIA_BUS_FMT_FIXED; + v4l2_subdev_call(itv->sd_video, pad, set_fmt, NULL, &format); return 0; } diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.c b/drivers/media/pci/ivtv/ivtv-ioctl.c index 6fe6c4a0e858..10c31cd43e03 100644 --- a/drivers/media/pci/ivtv/ivtv-ioctl.c +++ b/drivers/media/pci/ivtv/ivtv-ioctl.c @@ -581,7 +581,9 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f { struct ivtv_open_id *id = fh2id(fh); struct ivtv *itv = id->itv; - struct v4l2_mbus_framefmt mbus_fmt; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; int ret = ivtv_try_fmt_vid_cap(file, fh, fmt); int w = fmt->fmt.pix.width; int h = fmt->fmt.pix.height; @@ -599,10 +601,10 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f itv->cxhdl.height = h; if (v4l2_ctrl_g_ctrl(itv->cxhdl.video_encoding) == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) fmt->fmt.pix.width /= 2; - mbus_fmt.width = fmt->fmt.pix.width; - mbus_fmt.height = h; - mbus_fmt.code = MEDIA_BUS_FMT_FIXED; - v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &mbus_fmt); + format.format.width = fmt->fmt.pix.width; + format.format.height = h; + format.format.code = MEDIA_BUS_FMT_FIXED; + v4l2_subdev_call(itv->sd_video, pad, set_fmt, NULL, &format); return ivtv_g_fmt_vid_cap(file, fh, fmt); } diff --git a/drivers/media/pci/saa7134/saa7134-empress.c b/drivers/media/pci/saa7134/saa7134-empress.c index dc14930be909..c9118e0cbe00 100644 --- a/drivers/media/pci/saa7134/saa7134-empress.c +++ b/drivers/media/pci/saa7134/saa7134-empress.c @@ -140,11 +140,13 @@ static int empress_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct saa7134_dev *dev = video_drvdata(file); - struct v4l2_mbus_framefmt mbus_fmt; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; - v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, MEDIA_BUS_FMT_FIXED); - saa_call_all(dev, video, s_mbus_fmt, &mbus_fmt); - v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); + v4l2_fill_mbus_format(&format.format, &f->fmt.pix, MEDIA_BUS_FMT_FIXED); + saa_call_all(dev, pad, set_fmt, NULL, &format); + v4l2_fill_pix_format(&f->fmt.pix, &format.format); f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c index 88712f3247ab..ea971bb0d9c6 100644 --- a/drivers/media/platform/am437x/am437x-vpfe.c +++ b/drivers/media/platform/am437x/am437x-vpfe.c @@ -1455,7 +1455,6 @@ static int __vpfe_get_format(struct vpfe_device *vpfe, static int __vpfe_set_format(struct vpfe_device *vpfe, struct v4l2_format *format, unsigned int *bpp) { - struct v4l2_mbus_framefmt mbus_fmt; struct vpfe_subdev_info *sdinfo; struct v4l2_subdev_format fmt; int ret; @@ -1472,23 +1471,11 @@ static int __vpfe_set_format(struct vpfe_device *vpfe, pix_to_mbus(vpfe, &format->fmt.pix, &fmt.format); ret = v4l2_subdev_call(sdinfo->sd, pad, set_fmt, NULL, &fmt); - if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) + if (ret) return ret; - if (!ret) { - v4l2_fill_pix_format(&format->fmt.pix, &fmt.format); - mbus_to_pix(vpfe, &fmt.format, &format->fmt.pix, bpp); - } else { - ret = v4l2_device_call_until_err(&vpfe->v4l2_dev, - sdinfo->grp_id, - video, s_mbus_fmt, - &mbus_fmt); - if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) - return ret; - - v4l2_fill_pix_format(&format->fmt.pix, &mbus_fmt); - mbus_to_pix(vpfe, &mbus_fmt, &format->fmt.pix, bpp); - } + v4l2_fill_pix_format(&format->fmt.pix, &fmt.format); + mbus_to_pix(vpfe, &fmt.format, &format->fmt.pix, bpp); format->type = vpfe->fmt.type; diff --git a/drivers/media/platform/blackfin/bfin_capture.c b/drivers/media/platform/blackfin/bfin_capture.c index aa50eba623c3..b7e70fb05eb8 100644 --- a/drivers/media/platform/blackfin/bfin_capture.c +++ b/drivers/media/platform/blackfin/bfin_capture.c @@ -674,7 +674,9 @@ static int bcap_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *fmt) { struct bcap_device *bcap_dev = video_drvdata(file); - struct v4l2_mbus_framefmt mbus_fmt; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; struct bcap_format bcap_fmt; struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; int ret; @@ -687,8 +689,8 @@ static int bcap_s_fmt_vid_cap(struct file *file, void *priv, if (ret < 0) return ret; - v4l2_fill_mbus_format(&mbus_fmt, pixfmt, bcap_fmt.mbus_code); - ret = v4l2_subdev_call(bcap_dev->sd, video, s_mbus_fmt, &mbus_fmt); + v4l2_fill_mbus_format(&format.format, pixfmt, bcap_fmt.mbus_code); + ret = v4l2_subdev_call(bcap_dev->sd, pad, set_fmt, NULL, &format); if (ret < 0) return ret; bcap_dev->fmt = *pixfmt; diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index c2ebc12917a7..2707de8f6245 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -979,13 +979,15 @@ static int mcam_cam_set_flip(struct mcam_camera *cam) static int mcam_cam_configure(struct mcam_camera *cam) { - struct v4l2_mbus_framefmt mbus_fmt; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; int ret; - v4l2_fill_mbus_format(&mbus_fmt, &cam->pix_format, cam->mbus_code); + v4l2_fill_mbus_format(&format.format, &cam->pix_format, cam->mbus_code); ret = sensor_call(cam, core, init, 0); if (ret == 0) - ret = sensor_call(cam, video, s_mbus_fmt, &mbus_fmt); + ret = sensor_call(cam, pad, set_fmt, NULL, &format); /* * OV7670 does weird things if flip is set *before* format... */ diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c index dde1ccc730be..829e85c26610 100644 --- a/drivers/media/platform/sh_vou.c +++ b/drivers/media/platform/sh_vou.c @@ -679,12 +679,14 @@ static int sh_vou_s_fmt_vid_out(struct file *file, void *priv, unsigned int img_height_max; int pix_idx; struct sh_vou_geometry geo; - struct v4l2_mbus_framefmt mbfmt = { + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, /* Revisit: is this the correct code? */ - .code = MEDIA_BUS_FMT_YUYV8_2X8, - .field = V4L2_FIELD_INTERLACED, - .colorspace = V4L2_COLORSPACE_SMPTE170M, + .format.code = MEDIA_BUS_FMT_YUYV8_2X8, + .format.field = V4L2_FIELD_INTERLACED, + .format.colorspace = V4L2_COLORSPACE_SMPTE170M, }; + struct v4l2_mbus_framefmt *mbfmt = &format.format; int ret; dev_dbg(vou_dev->v4l2_dev.dev, "%s(): %ux%u -> %ux%u\n", __func__, @@ -720,27 +722,27 @@ static int sh_vou_s_fmt_vid_out(struct file *file, void *priv, vou_adjust_output(&geo, vou_dev->std); - mbfmt.width = geo.output.width; - mbfmt.height = geo.output.height; - ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video, - s_mbus_fmt, &mbfmt); + mbfmt->width = geo.output.width; + mbfmt->height = geo.output.height; + ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, pad, + set_fmt, NULL, &format); /* Must be implemented, so, don't check for -ENOIOCTLCMD */ if (ret < 0) return ret; dev_dbg(vou_dev->v4l2_dev.dev, "%s(): %ux%u -> %ux%u\n", __func__, - geo.output.width, geo.output.height, mbfmt.width, mbfmt.height); + geo.output.width, geo.output.height, mbfmt->width, mbfmt->height); /* Sanity checks */ - if ((unsigned)mbfmt.width > VOU_MAX_IMAGE_WIDTH || - (unsigned)mbfmt.height > img_height_max || - mbfmt.code != MEDIA_BUS_FMT_YUYV8_2X8) + if ((unsigned)mbfmt->width > VOU_MAX_IMAGE_WIDTH || + (unsigned)mbfmt->height > img_height_max || + mbfmt->code != MEDIA_BUS_FMT_YUYV8_2X8) return -EIO; - if (mbfmt.width != geo.output.width || - mbfmt.height != geo.output.height) { - geo.output.width = mbfmt.width; - geo.output.height = mbfmt.height; + if (mbfmt->width != geo.output.width || + mbfmt->height != geo.output.height) { + geo.output.width = mbfmt->width; + geo.output.height = mbfmt->height; vou_adjust_input(&geo, vou_dev->std); } @@ -942,11 +944,12 @@ static int sh_vou_s_crop(struct file *file, void *fh, const struct v4l2_crop *a) struct v4l2_crop sd_crop = {.type = V4L2_BUF_TYPE_VIDEO_OUTPUT}; struct v4l2_pix_format *pix = &vou_dev->pix; struct sh_vou_geometry geo; - struct v4l2_mbus_framefmt mbfmt = { + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, /* Revisit: is this the correct code? */ - .code = MEDIA_BUS_FMT_YUYV8_2X8, - .field = V4L2_FIELD_INTERLACED, - .colorspace = V4L2_COLORSPACE_SMPTE170M, + .format.code = MEDIA_BUS_FMT_YUYV8_2X8, + .format.field = V4L2_FIELD_INTERLACED, + .format.colorspace = V4L2_COLORSPACE_SMPTE170M, }; unsigned int img_height_max; int ret; @@ -984,22 +987,22 @@ static int sh_vou_s_crop(struct file *file, void *fh, const struct v4l2_crop *a) */ v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video, s_crop, &sd_crop); - mbfmt.width = geo.output.width; - mbfmt.height = geo.output.height; - ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video, - s_mbus_fmt, &mbfmt); + format.format.width = geo.output.width; + format.format.height = geo.output.height; + ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, pad, + set_fmt, NULL, &format); /* Must be implemented, so, don't check for -ENOIOCTLCMD */ if (ret < 0) return ret; /* Sanity checks */ - if ((unsigned)mbfmt.width > VOU_MAX_IMAGE_WIDTH || - (unsigned)mbfmt.height > img_height_max || - mbfmt.code != MEDIA_BUS_FMT_YUYV8_2X8) + if ((unsigned)format.format.width > VOU_MAX_IMAGE_WIDTH || + (unsigned)format.format.height > img_height_max || + format.format.code != MEDIA_BUS_FMT_YUYV8_2X8) return -EIO; - geo.output.width = mbfmt.width; - geo.output.height = mbfmt.height; + geo.output.width = format.format.width; + geo.output.height = format.format.height; /* * No down-scaling. According to the API, current call has precedence: diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 903dbf27d0e0..287902681164 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -487,7 +487,10 @@ static int isi_camera_set_fmt(struct soc_camera_device *icd, struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = &f->fmt.pix; - struct v4l2_mbus_framefmt mf; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct v4l2_mbus_framefmt *mf = &format.format; int ret; xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); @@ -500,27 +503,27 @@ static int isi_camera_set_fmt(struct soc_camera_device *icd, dev_dbg(icd->parent, "Plan to set format %dx%d\n", pix->width, pix->height); - mf.width = pix->width; - mf.height = pix->height; - mf.field = pix->field; - mf.colorspace = pix->colorspace; - mf.code = xlate->code; + mf->width = pix->width; + mf->height = pix->height; + mf->field = pix->field; + mf->colorspace = pix->colorspace; + mf->code = xlate->code; - ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); + ret = v4l2_subdev_call(sd, pad, set_fmt, NULL, &format); if (ret < 0) return ret; - if (mf.code != xlate->code) + if (mf->code != xlate->code) return -EINVAL; ret = configure_geometry(isi, pix->width, pix->height, xlate->code); if (ret < 0) return ret; - pix->width = mf.width; - pix->height = mf.height; - pix->field = mf.field; - pix->colorspace = mf.colorspace; + pix->width = mf->width; + pix->height = mf->height; + pix->field = mf->field; + pix->colorspace = mf->colorspace; icd->current_fmt = xlate; dev_dbg(icd->parent, "Finally set format %dx%d\n", diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c index d45f50a3a9eb..ea4c423f0cf8 100644 --- a/drivers/media/platform/soc_camera/mx2_camera.c +++ b/drivers/media/platform/soc_camera/mx2_camera.c @@ -1127,7 +1127,10 @@ static int mx2_camera_set_fmt(struct soc_camera_device *icd, struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = &f->fmt.pix; - struct v4l2_mbus_framefmt mf; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct v4l2_mbus_framefmt *mf = &format.format; int ret; dev_dbg(icd->parent, "%s: requested params: width = %d, height = %d\n", @@ -1140,19 +1143,19 @@ static int mx2_camera_set_fmt(struct soc_camera_device *icd, return -EINVAL; } - mf.width = pix->width; - mf.height = pix->height; - mf.field = pix->field; - mf.colorspace = pix->colorspace; - mf.code = xlate->code; + mf->width = pix->width; + mf->height = pix->height; + mf->field = pix->field; + mf->colorspace = pix->colorspace; + mf->code = xlate->code; - ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); + ret = v4l2_subdev_call(sd, pad, set_fmt, NULL, &format); if (ret < 0 && ret != -ENOIOCTLCMD) return ret; /* Store width and height returned by the sensor for resizing */ - pcdev->s_width = mf.width; - pcdev->s_height = mf.height; + pcdev->s_width = mf->width; + pcdev->s_height = mf->height; dev_dbg(icd->parent, "%s: sensor params: width = %d, height = %d\n", __func__, pcdev->s_width, pcdev->s_height); @@ -1160,19 +1163,19 @@ static int mx2_camera_set_fmt(struct soc_camera_device *icd, xlate->host_fmt->fourcc); memset(pcdev->resizing, 0, sizeof(pcdev->resizing)); - if ((mf.width != pix->width || mf.height != pix->height) && + if ((mf->width != pix->width || mf->height != pix->height) && pcdev->emma_prp->cfg.in_fmt == PRP_CNTL_DATA_IN_YUV422) { - if (mx2_emmaprp_resize(pcdev, &mf, pix, true) < 0) + if (mx2_emmaprp_resize(pcdev, mf, pix, true) < 0) dev_dbg(icd->parent, "%s: can't resize\n", __func__); } - if (mf.code != xlate->code) + if (mf->code != xlate->code) return -EINVAL; - pix->width = mf.width; - pix->height = mf.height; - pix->field = mf.field; - pix->colorspace = mf.colorspace; + pix->width = mf->width; + pix->height = mf->height; + pix->field = mf->field; + pix->colorspace = mf->colorspace; icd->current_fmt = xlate; dev_dbg(icd->parent, "%s: returned params: width = %d, height = %d\n", diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c index f63501771072..ace41f53caca 100644 --- a/drivers/media/platform/soc_camera/mx3_camera.c +++ b/drivers/media/platform/soc_camera/mx3_camera.c @@ -828,7 +828,7 @@ static int mx3_camera_set_crop(struct soc_camera_device *icd, if (mf->width & 7) { /* Ouch! We can only handle 8-byte aligned width... */ stride_align(&mf->width); - ret = v4l2_subdev_call(sd, video, s_mbus_fmt, mf); + ret = v4l2_subdev_call(sd, pad, set_fmt, NULL, &fmt); if (ret < 0) return ret; } @@ -854,7 +854,10 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd, struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = &f->fmt.pix; - struct v4l2_mbus_framefmt mf; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct v4l2_mbus_framefmt *mf = &format.format; int ret; xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); @@ -875,17 +878,17 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd, configure_geometry(mx3_cam, pix->width, pix->height, xlate->host_fmt); - mf.width = pix->width; - mf.height = pix->height; - mf.field = pix->field; - mf.colorspace = pix->colorspace; - mf.code = xlate->code; + mf->width = pix->width; + mf->height = pix->height; + mf->field = pix->field; + mf->colorspace = pix->colorspace; + mf->code = xlate->code; - ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); + ret = v4l2_subdev_call(sd, pad, set_fmt, NULL, &format); if (ret < 0) return ret; - if (mf.code != xlate->code) + if (mf->code != xlate->code) return -EINVAL; if (!mx3_cam->idmac_channel[0]) { @@ -894,11 +897,11 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd, return ret; } - pix->width = mf.width; - pix->height = mf.height; - pix->field = mf.field; - mx3_cam->field = mf.field; - pix->colorspace = mf.colorspace; + pix->width = mf->width; + pix->height = mf->height; + pix->field = mf->field; + mx3_cam->field = mf->field; + pix->colorspace = mf->colorspace; icd->current_fmt = xlate; dev_dbg(icd->parent, "Sensor set %dx%d\n", pix->width, pix->height); diff --git a/drivers/media/platform/soc_camera/omap1_camera.c b/drivers/media/platform/soc_camera/omap1_camera.c index 2a715e1e22de..ba8dcd11ae0e 100644 --- a/drivers/media/platform/soc_camera/omap1_camera.c +++ b/drivers/media/platform/soc_camera/omap1_camera.c @@ -1157,7 +1157,7 @@ static int dma_align(int *width, int *height, return 1; } -#define subdev_call_with_sense(pcdev, dev, icd, sd, function, args...) \ +#define subdev_call_with_sense(pcdev, dev, icd, sd, op, function, args...) \ ({ \ struct soc_camera_sense sense = { \ .master_clock = pcdev->camexclk, \ @@ -1168,7 +1168,7 @@ static int dma_align(int *width, int *height, if (pcdev->pdata) \ sense.pixel_clock_max = pcdev->pdata->lclk_khz_max * 1000; \ icd->sense = &sense; \ - __ret = v4l2_subdev_call(sd, video, function, ##args); \ + __ret = v4l2_subdev_call(sd, op, function, ##args); \ icd->sense = NULL; \ \ if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { \ @@ -1182,16 +1182,17 @@ static int dma_align(int *width, int *height, __ret; \ }) -static int set_mbus_format(struct omap1_cam_dev *pcdev, struct device *dev, +static int set_format(struct omap1_cam_dev *pcdev, struct device *dev, struct soc_camera_device *icd, struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf, + struct v4l2_subdev_format *format, const struct soc_camera_format_xlate *xlate) { s32 bytes_per_line; - int ret = subdev_call_with_sense(pcdev, dev, icd, sd, s_mbus_fmt, mf); + struct v4l2_mbus_framefmt *mf = &format->format; + int ret = subdev_call_with_sense(pcdev, dev, icd, sd, pad, set_fmt, NULL, format); if (ret < 0) { - dev_err(dev, "%s: s_mbus_fmt failed\n", __func__); + dev_err(dev, "%s: set_fmt failed\n", __func__); return ret; } @@ -1230,7 +1231,7 @@ static int omap1_cam_set_crop(struct soc_camera_device *icd, struct v4l2_mbus_framefmt *mf = &fmt.format; int ret; - ret = subdev_call_with_sense(pcdev, dev, icd, sd, s_crop, crop); + ret = subdev_call_with_sense(pcdev, dev, icd, sd, video, s_crop, crop); if (ret < 0) { dev_warn(dev, "%s: failed to crop to %ux%u@%u:%u\n", __func__, rect->width, rect->height, rect->left, rect->top); @@ -1254,7 +1255,7 @@ static int omap1_cam_set_crop(struct soc_camera_device *icd, if (!ret) { /* sensor returned geometry not DMA aligned, trying to fix */ - ret = set_mbus_format(pcdev, dev, icd, sd, mf, xlate); + ret = set_format(pcdev, dev, icd, sd, &fmt, xlate); if (ret < 0) { dev_err(dev, "%s: failed to set format\n", __func__); return ret; @@ -1276,7 +1277,10 @@ static int omap1_cam_set_fmt(struct soc_camera_device *icd, struct soc_camera_host *ici = to_soc_camera_host(dev); struct omap1_cam_dev *pcdev = ici->priv; struct v4l2_pix_format *pix = &f->fmt.pix; - struct v4l2_mbus_framefmt mf; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct v4l2_mbus_framefmt *mf = &format.format; int ret; xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); @@ -1286,13 +1290,13 @@ static int omap1_cam_set_fmt(struct soc_camera_device *icd, return -EINVAL; } - mf.width = pix->width; - mf.height = pix->height; - mf.field = pix->field; - mf.colorspace = pix->colorspace; - mf.code = xlate->code; + mf->width = pix->width; + mf->height = pix->height; + mf->field = pix->field; + mf->colorspace = pix->colorspace; + mf->code = xlate->code; - ret = dma_align(&mf.width, &mf.height, xlate->host_fmt, pcdev->vb_mode, + ret = dma_align(&mf->width, &mf->height, xlate->host_fmt, pcdev->vb_mode, true); if (ret < 0) { dev_err(dev, "%s: failed to align %ux%u %s with DMA\n", @@ -1301,16 +1305,16 @@ static int omap1_cam_set_fmt(struct soc_camera_device *icd, return ret; } - ret = set_mbus_format(pcdev, dev, icd, sd, &mf, xlate); + ret = set_format(pcdev, dev, icd, sd, &format, xlate); if (ret < 0) { dev_err(dev, "%s: failed to set format\n", __func__); return ret; } - pix->width = mf.width; - pix->height = mf.height; - pix->field = mf.field; - pix->colorspace = mf.colorspace; + pix->width = mf->width; + pix->height = mf->height; + pix->field = mf->field; + pix->colorspace = mf->colorspace; icd->current_fmt = xlate; return 0; diff --git a/drivers/media/platform/soc_camera/pxa_camera.c b/drivers/media/platform/soc_camera/pxa_camera.c index 7ccd76f7ca1a..fcb942de0c7f 100644 --- a/drivers/media/platform/soc_camera/pxa_camera.c +++ b/drivers/media/platform/soc_camera/pxa_camera.c @@ -1383,7 +1383,7 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd, v4l_bound_align_image(&mf->width, 48, 2048, 1, &mf->height, 32, 2048, 0, fourcc == V4L2_PIX_FMT_YUV422P ? 4 : 0); - ret = v4l2_subdev_call(sd, video, s_mbus_fmt, mf); + ret = v4l2_subdev_call(sd, pad, set_fmt, NULL, &fmt); if (ret < 0) return ret; @@ -1425,7 +1425,10 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, .pixel_clock_max = pcdev->ciclk / 4, }; struct v4l2_pix_format *pix = &f->fmt.pix; - struct v4l2_mbus_framefmt mf; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct v4l2_mbus_framefmt *mf = &format.format; int ret; xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); @@ -1439,15 +1442,15 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, /* The caller holds a mutex. */ icd->sense = &sense; - mf.width = pix->width; - mf.height = pix->height; - mf.field = pix->field; - mf.colorspace = pix->colorspace; - mf.code = xlate->code; + mf->width = pix->width; + mf->height = pix->height; + mf->field = pix->field; + mf->colorspace = pix->colorspace; + mf->code = xlate->code; - ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); + ret = v4l2_subdev_call(sd, pad, set_fmt, NULL, &format); - if (mf.code != xlate->code) + if (mf->code != xlate->code) return -EINVAL; icd->sense = NULL; @@ -1455,10 +1458,10 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, if (ret < 0) { dev_warn(dev, "Failed to configure for format %x\n", pix->pixelformat); - } else if (pxa_camera_check_frame(mf.width, mf.height)) { + } else if (pxa_camera_check_frame(mf->width, mf->height)) { dev_warn(dev, "Camera driver produced an unsupported frame %dx%d\n", - mf.width, mf.height); + mf->width, mf->height); ret = -EINVAL; } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { if (sense.pixel_clock > sense.pixel_clock_max) { @@ -1473,10 +1476,10 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, if (ret < 0) return ret; - pix->width = mf.width; - pix->height = mf.height; - pix->field = mf.field; - pix->colorspace = mf.colorspace; + pix->width = mf->width; + pix->height = mf->height; + pix->field = mf->field; + pix->colorspace = mf->colorspace; icd->current_fmt = xlate; return ret; diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c index 063285a8dcf5..35deed83582b 100644 --- a/drivers/media/platform/soc_camera/rcar_vin.c +++ b/drivers/media/platform/soc_camera/rcar_vin.c @@ -1376,8 +1376,8 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx, mf->height = 960 >> shift; ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd), - video, s_mbus_fmt, - mf); + pad, set_fmt, NULL, + &fmt); if (ret < 0) return ret; } diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 91c48ab6cd13..c5c6c4e91f7b 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -1111,8 +1111,8 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int mf->width = 2560 >> shift; mf->height = 1920 >> shift; ret = v4l2_device_call_until_err(sd->v4l2_dev, - soc_camera_grp_id(icd), video, - s_mbus_fmt, mf); + soc_camera_grp_id(icd), pad, + set_fmt, NULL, &fmt); if (ret < 0) return ret; shift++; @@ -1286,8 +1286,8 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, if (interm_width < icd->user_width || interm_height < icd->user_height) { ret = v4l2_device_call_until_err(sd->v4l2_dev, - soc_camera_grp_id(icd), video, - s_mbus_fmt, mf); + soc_camera_grp_id(icd), pad, + set_fmt, NULL, &fmt); if (ret < 0) return ret; diff --git a/drivers/media/platform/soc_camera/soc_scale_crop.c b/drivers/media/platform/soc_camera/soc_scale_crop.c index 8e74fb7f2a07..bda29bc1b933 100644 --- a/drivers/media/platform/soc_camera/soc_scale_crop.c +++ b/drivers/media/platform/soc_camera/soc_scale_crop.c @@ -211,22 +211,23 @@ int soc_camera_client_s_crop(struct v4l2_subdev *sd, } EXPORT_SYMBOL(soc_camera_client_s_crop); -/* Iterative s_mbus_fmt, also updates cached client crop on success */ -static int client_s_fmt(struct soc_camera_device *icd, +/* Iterative set_fmt, also updates cached client crop on success */ +static int client_set_fmt(struct soc_camera_device *icd, struct v4l2_rect *rect, struct v4l2_rect *subrect, unsigned int max_width, unsigned int max_height, - struct v4l2_mbus_framefmt *mf, bool host_can_scale) + struct v4l2_subdev_format *format, bool host_can_scale) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct device *dev = icd->parent; + struct v4l2_mbus_framefmt *mf = &format->format; unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h; struct v4l2_cropcap cap; bool host_1to1; int ret; ret = v4l2_device_call_until_err(sd->v4l2_dev, - soc_camera_grp_id(icd), video, - s_mbus_fmt, mf); + soc_camera_grp_id(icd), pad, + set_fmt, NULL, format); if (ret < 0) return ret; @@ -265,8 +266,8 @@ static int client_s_fmt(struct soc_camera_device *icd, mf->width = tmp_w; mf->height = tmp_h; ret = v4l2_device_call_until_err(sd->v4l2_dev, - soc_camera_grp_id(icd), video, - s_mbus_fmt, mf); + soc_camera_grp_id(icd), pad, + set_fmt, NULL, format); dev_geo(dev, "Camera scaled to %ux%u\n", mf->width, mf->height); if (ret < 0) { @@ -309,7 +310,11 @@ int soc_camera_client_scale(struct soc_camera_device *icd, bool host_can_scale, unsigned int shift) { struct device *dev = icd->parent; - struct v4l2_mbus_framefmt mf_tmp = *mf; + struct v4l2_subdev_format fmt_tmp = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .format = *mf, + }; + struct v4l2_mbus_framefmt *mf_tmp = &fmt_tmp.format; unsigned int scale_h, scale_v; int ret; @@ -317,25 +322,25 @@ int soc_camera_client_scale(struct soc_camera_device *icd, * 5. Apply iterative camera S_FMT for camera user window (also updates * client crop cache and the imaginary sub-rectangle). */ - ret = client_s_fmt(icd, rect, subrect, *width, *height, - &mf_tmp, host_can_scale); + ret = client_set_fmt(icd, rect, subrect, *width, *height, + &fmt_tmp, host_can_scale); if (ret < 0) return ret; dev_geo(dev, "5: camera scaled to %ux%u\n", - mf_tmp.width, mf_tmp.height); + mf_tmp->width, mf_tmp->height); /* 6. Retrieve camera output window (g_fmt) */ /* unneeded - it is already in "mf_tmp" */ /* 7. Calculate new client scales. */ - scale_h = soc_camera_calc_scale(rect->width, shift, mf_tmp.width); - scale_v = soc_camera_calc_scale(rect->height, shift, mf_tmp.height); + scale_h = soc_camera_calc_scale(rect->width, shift, mf_tmp->width); + scale_v = soc_camera_calc_scale(rect->height, shift, mf_tmp->height); - mf->width = mf_tmp.width; - mf->height = mf_tmp.height; - mf->colorspace = mf_tmp.colorspace; + mf->width = mf_tmp->width; + mf->height = mf_tmp->height; + mf->colorspace = mf_tmp->colorspace; /* * 8. Calculate new host crop - apply camera scales to previously diff --git a/drivers/media/platform/via-camera.c b/drivers/media/platform/via-camera.c index 6331d6b99d23..32e4ff46daf3 100644 --- a/drivers/media/platform/via-camera.c +++ b/drivers/media/platform/via-camera.c @@ -249,13 +249,15 @@ static int viacam_set_flip(struct via_camera *cam) */ static int viacam_configure_sensor(struct via_camera *cam) { - struct v4l2_mbus_framefmt mbus_fmt; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; int ret; - v4l2_fill_mbus_format(&mbus_fmt, &cam->sensor_format, cam->mbus_code); + v4l2_fill_mbus_format(&format.format, &cam->sensor_format, cam->mbus_code); ret = sensor_call(cam, core, init, 0); if (ret == 0) - ret = sensor_call(cam, video, s_mbus_fmt, &mbus_fmt); + ret = sensor_call(cam, pad, set_fmt, NULL, &format); /* * OV7670 does weird things if flip is set *before* format... */ diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index 3096e291735c..855a708387c6 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c @@ -1878,13 +1878,15 @@ static int cx231xx_s_video_encoding(struct cx2341x_handler *cxhdl, u32 val) { struct cx231xx *dev = container_of(cxhdl, struct cx231xx, mpeg_ctrl_handler); int is_mpeg1 = val == V4L2_MPEG_VIDEO_ENCODING_MPEG_1; - struct v4l2_mbus_framefmt fmt; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; /* fix videodecoder resolution */ - fmt.width = cxhdl->width / (is_mpeg1 ? 2 : 1); - fmt.height = cxhdl->height; - fmt.code = MEDIA_BUS_FMT_FIXED; - v4l2_subdev_call(dev->sd_cx25840, video, s_mbus_fmt, &fmt); + format.format.width = cxhdl->width / (is_mpeg1 ? 2 : 1); + format.format.height = cxhdl->height; + format.format.code = MEDIA_BUS_FMT_FIXED; + v4l2_subdev_call(dev->sd_cx25840, pad, set_fmt, NULL, &format); return 0; } diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index c261e160c158..af44f2d1c0a1 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -1013,7 +1013,9 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct cx231xx *dev = fh->dev; int rc; struct cx231xx_fmt *fmt; - struct v4l2_mbus_framefmt mbus_fmt; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; rc = check_dev(dev); if (rc < 0) @@ -1041,9 +1043,9 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, dev->height = f->fmt.pix.height; dev->format = fmt; - v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, MEDIA_BUS_FMT_FIXED); - call_all(dev, video, s_mbus_fmt, &mbus_fmt); - v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); + v4l2_fill_mbus_format(&format.format, &f->fmt.pix, MEDIA_BUS_FMT_FIXED); + call_all(dev, pad, set_fmt, NULL, &format); + v4l2_fill_pix_format(&f->fmt.pix, &format.format); return rc; } @@ -1061,7 +1063,9 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) { struct cx231xx_fh *fh = priv; struct cx231xx *dev = fh->dev; - struct v4l2_mbus_framefmt mbus_fmt; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; int rc; rc = check_dev(dev); @@ -1085,11 +1089,10 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) /* We need to reset basic properties in the decoder related to resolution (since a standard change effects things like the number of lines in VACT, etc) */ - memset(&mbus_fmt, 0, sizeof(mbus_fmt)); - mbus_fmt.code = MEDIA_BUS_FMT_FIXED; - mbus_fmt.width = dev->width; - mbus_fmt.height = dev->height; - call_all(dev, video, s_mbus_fmt, &mbus_fmt); + format.format.code = MEDIA_BUS_FMT_FIXED; + format.format.width = dev->width; + format.format.height = dev->height; + call_all(dev, pad, set_fmt, NULL, &format); /* do mode control overrides */ cx231xx_do_mode_ctrl_overrides(dev); diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index a4b22c2c3ba7..ed0b3a87983e 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c @@ -404,7 +404,9 @@ int em28xx_init_camera(struct em28xx *dev) .addr = client->addr, .platform_data = &camlink, }; - struct v4l2_mbus_framefmt fmt; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; /* * FIXME: sensor supports resolutions up to 1600x1200, but @@ -425,10 +427,10 @@ int em28xx_init_camera(struct em28xx *dev) break; } - fmt.code = MEDIA_BUS_FMT_YUYV8_2X8; - fmt.width = 640; - fmt.height = 480; - v4l2_subdev_call(subdev, video, s_mbus_fmt, &fmt); + format.format.code = MEDIA_BUS_FMT_YUYV8_2X8; + format.format.width = 640; + format.format.height = 480; + v4l2_subdev_call(subdev, pad, set_fmt, NULL, &format); /* NOTE: for UXGA=1600x1200 switch to 12MHz */ dev->board.xclk = EM28XX_XCLK_FREQUENCY_24MHZ; diff --git a/drivers/media/usb/go7007/go7007-v4l2.c b/drivers/media/usb/go7007/go7007-v4l2.c index d6bf982efa42..c57207e268c3 100644 --- a/drivers/media/usb/go7007/go7007-v4l2.c +++ b/drivers/media/usb/go7007/go7007-v4l2.c @@ -250,15 +250,17 @@ static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try) go->encoder_v_offset = go->board_info->sensor_v_offset; if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) { - struct v4l2_mbus_framefmt mbus_fmt; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; - mbus_fmt.code = MEDIA_BUS_FMT_FIXED; - mbus_fmt.width = fmt ? fmt->fmt.pix.width : width; - mbus_fmt.height = height; + format.format.code = MEDIA_BUS_FMT_FIXED; + format.format.width = fmt ? fmt->fmt.pix.width : width; + format.format.height = height; go->encoder_h_halve = 0; go->encoder_v_halve = 0; go->encoder_subsample = 0; - call_all(&go->v4l2_dev, video, s_mbus_fmt, &mbus_fmt); + call_all(&go->v4l2_dev, pad, set_fmt, NULL, &format); } else { if (width <= sensor_width / 4) { go->encoder_h_halve = 1; diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c index 775aa5ed92ee..0533ef20decf 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c @@ -2962,14 +2962,17 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw) } if (hdw->res_hor_dirty || hdw->res_ver_dirty || hdw->force_dirty) { - struct v4l2_mbus_framefmt fmt; - memset(&fmt, 0, sizeof(fmt)); - fmt.width = hdw->res_hor_val; - fmt.height = hdw->res_ver_val; - fmt.code = MEDIA_BUS_FMT_FIXED; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + + format.format.width = hdw->res_hor_val; + format.format.height = hdw->res_ver_val; + format.format.code = MEDIA_BUS_FMT_FIXED; pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_size(%dx%d)", - fmt.width, fmt.height); - v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_mbus_fmt, &fmt); + format.format.width, format.format.height); + v4l2_device_call_all(&hdw->v4l2_dev, 0, pad, set_fmt, + NULL, &format); } if (hdw->srate_dirty || hdw->force_dirty) { diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 67a8e4e58d9a..8f5da73dacff 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -293,10 +293,6 @@ struct v4l2_mbus_frame_desc { g_dv_timings(): Get custom dv timings in the sub device. - try_mbus_fmt: try to set a pixel format on a video data source - - s_mbus_fmt: set a pixel format on a video data source - g_mbus_config: get supported mediabus configurations s_mbus_config: set a certain mediabus configuration. This operation is added @@ -334,10 +330,6 @@ struct v4l2_subdev_video_ops { struct v4l2_dv_timings *timings); int (*query_dv_timings)(struct v4l2_subdev *sd, struct v4l2_dv_timings *timings); - int (*try_mbus_fmt)(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *fmt); - int (*s_mbus_fmt)(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *fmt); int (*g_mbus_config)(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg); int (*s_mbus_config)(struct v4l2_subdev *sd, -- cgit v1.2.3-59-g8ed1b From 1555f3bf5cc172e7d23c2b8db10d656d15bec13e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 1 May 2015 08:45:28 -0300 Subject: [media] saa7164: fix compiler warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/media/pci/saa7164/saa7164-dvb.c: In function ‘saa7164_dvb_register’: drivers/media/pci/saa7164/saa7164-dvb.c:701:7: warning: ‘client_tuner’ may be used uninitialized in this function [-Wmaybe-uninitialized] if (!client_tuner || !client_tuner->dev.driver) ^ Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7164/saa7164-dvb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7164/saa7164-dvb.c b/drivers/media/pci/saa7164/saa7164-dvb.c index c68ce2631e8f..99698002a808 100644 --- a/drivers/media/pci/saa7164/saa7164-dvb.c +++ b/drivers/media/pci/saa7164/saa7164-dvb.c @@ -698,7 +698,7 @@ int saa7164_dvb_register(struct saa7164_port *port) request_module(info.type); client_demod = i2c_new_device(&dev->i2c_bus[2].i2c_adap, &info); - if (!client_tuner || !client_tuner->dev.driver) + if (!client_demod || !client_demod->dev.driver) goto frontend_detach; if (!try_module_get(client_demod->dev.driver->owner)) { -- cgit v1.2.3-59-g8ed1b From 5a13e40b28486c3a755a0388767615f197f4ae07 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 8 May 2015 08:59:16 -0300 Subject: media: replace bellow -> below Bellow is yelling. Ok, sometimes the code is yells a lot, but but this is not the case there ;) Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsir.c | 2 +- drivers/media/dvb-frontends/drx39xyj/drxj.c | 2 +- drivers/media/dvb-frontends/drxk_hard.c | 2 +- drivers/media/dvb-frontends/tda10021.c | 2 +- drivers/media/dvb-frontends/tda10023.c | 2 +- drivers/media/i2c/tvaudio.c | 2 +- drivers/media/tuners/tuner-xc2028.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/siano/smsir.c b/drivers/media/common/siano/smsir.c index 1d60d200d9ab..41f2a3939979 100644 --- a/drivers/media/common/siano/smsir.c +++ b/drivers/media/common/siano/smsir.c @@ -78,7 +78,7 @@ int sms_ir_init(struct smscore_device_t *coredev) dev->dev.parent = coredev->device; #if 0 - /* TODO: properly initialize the parameters bellow */ + /* TODO: properly initialize the parameters below */ dev->input_id.bustype = BUS_USB; dev->input_id.version = 1; dev->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c index 61f76038442a..52245354bf04 100644 --- a/drivers/media/dvb-frontends/drx39xyj/drxj.c +++ b/drivers/media/dvb-frontends/drx39xyj/drxj.c @@ -9541,7 +9541,7 @@ ctrl_get_qam_sig_quality(struct drx_demod_instance *demod) /* ----------------------------------------- */ /* Pre Viterbi Symbol Error Rate Calculation */ /* ----------------------------------------- */ - /* pre viterbi SER is good if it is bellow 0.025 */ + /* pre viterbi SER is good if it is below 0.025 */ /* get the register value */ /* no of quadrature symbol errors */ diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c index d46cf5f7cd2e..ad35264a3819 100644 --- a/drivers/media/dvb-frontends/drxk_hard.c +++ b/drivers/media/dvb-frontends/drxk_hard.c @@ -544,7 +544,7 @@ error: static int init_state(struct drxk_state *state) { /* - * FIXME: most (all?) of the values bellow should be moved into + * FIXME: most (all?) of the values below should be moved into * struct drxk_config, as they are probably board-specific */ u32 ul_vsb_if_agc_mode = DRXK_AGC_CTRL_AUTO; diff --git a/drivers/media/dvb-frontends/tda10021.c b/drivers/media/dvb-frontends/tda10021.c index 1bff7f457e19..28d987068048 100644 --- a/drivers/media/dvb-frontends/tda10021.c +++ b/drivers/media/dvb-frontends/tda10021.c @@ -258,7 +258,7 @@ static int tda10021_set_parameters(struct dvb_frontend *fe) } /* - * gcc optimizes the code bellow the same way as it would code: + * gcc optimizes the code below the same way as it would code: * "if (qam > 5) return -EINVAL;" * Yet, the code is clearer, as it shows what QAM standards are * supported by the driver, and avoids the usage of magic numbers on diff --git a/drivers/media/dvb-frontends/tda10023.c b/drivers/media/dvb-frontends/tda10023.c index ca1e0d54b69a..f92fbbbb4a71 100644 --- a/drivers/media/dvb-frontends/tda10023.c +++ b/drivers/media/dvb-frontends/tda10023.c @@ -331,7 +331,7 @@ static int tda10023_set_parameters(struct dvb_frontend *fe) } /* - * gcc optimizes the code bellow the same way as it would code: + * gcc optimizes the code below the same way as it would code: * "if (qam > 5) return -EINVAL;" * Yet, the code is clearer, as it shows what QAM standards are * supported by the driver, and avoids the usage of magic numbers on diff --git a/drivers/media/i2c/tvaudio.c b/drivers/media/i2c/tvaudio.c index 070c152da95a..0c50e5285cf6 100644 --- a/drivers/media/i2c/tvaudio.c +++ b/drivers/media/i2c/tvaudio.c @@ -272,7 +272,7 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd) return -EINVAL; } - /* FIXME: it seems that the shadow bytes are wrong bellow !*/ + /* FIXME: it seems that the shadow bytes are wrong below !*/ /* update our shadow register set; print bytes if (debug > 0) */ v4l2_dbg(1, debug, sd, "chip_cmd(%s): reg=%d, data:", diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c index d12f5e4ad8bf..4e941f00b600 100644 --- a/drivers/media/tuners/tuner-xc2028.c +++ b/drivers/media/tuners/tuner-xc2028.c @@ -1094,7 +1094,7 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, * Still need tests for XC3028L (firmware 3.2 or upper) * So, for now, let's just comment the per-firmware * version of this change. Reports with xc3028l working - * with and without the lines bellow are welcome + * with and without the lines below are welcome */ if (priv->firm_version < 0x0302) { -- cgit v1.2.3-59-g8ed1b From c3f22501b52de17c6087b6fe6f2236e4183ac07c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 6 May 2015 11:26:13 -0300 Subject: media controller: add EXPERIMENTAL to Kconfig option for DVB support The Media Controller DVB support is still an experimental feature, as it is under heavy development. It is already said that it is an experimental feature at the help, but let make it even clearer and louder, as we may need to adjust some bits when we start using it on embedded drivers. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 3ef0f90b128f..8af89b084267 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -95,7 +95,7 @@ config MEDIA_CONTROLLER This API is mostly used by camera interfaces in embedded platforms. config MEDIA_CONTROLLER_DVB - bool "Enable Media controller for DVB" + bool "Enable Media controller for DVB (EXPERIMENTAL)" depends on MEDIA_CONTROLLER ---help--- Enable the media controller API support for DVB. -- cgit v1.2.3-59-g8ed1b From 40437e703feef873441769e74910fd309c1fb404 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 1 May 2015 12:51:00 -0300 Subject: [media] media: platform: exynos-gsc: Constify platform_device_id The platform_device_id is not modified by the driver and core uses it as const. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos-gsc/gsc-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index fd2891c886a3..9b9e423e4fc4 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -967,7 +967,7 @@ static struct gsc_driverdata gsc_v_100_drvdata = { .lclk_frequency = 266000000UL, }; -static struct platform_device_id gsc_driver_ids[] = { +static const struct platform_device_id gsc_driver_ids[] = { { .name = "exynos-gsc", .driver_data = (unsigned long)&gsc_v_100_drvdata, -- cgit v1.2.3-59-g8ed1b From c42639d8a6beb03e2725e8a1ae1d1c6b30cdde7b Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 1 May 2015 12:51:01 -0300 Subject: [media] media: platform: exynos4-is: Constify platform_device_id The platform_device_id is not modified by the driver and core uses it as const. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos4-is/media-dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index f315ef946cd4..4f5586a4cbff 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -1451,7 +1451,7 @@ static int fimc_md_remove(struct platform_device *pdev) return 0; } -static struct platform_device_id fimc_driver_ids[] __always_unused = { +static const struct platform_device_id fimc_driver_ids[] __always_unused = { { .name = "s5p-fimc-md" }, { }, }; -- cgit v1.2.3-59-g8ed1b From ef00b7ae68dfcbf8ccd81c5caf26337fc920b563 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 1 May 2015 12:51:02 -0300 Subject: [media] media: platform: s3c-camif: Constify platform_device_id The platform_device_id is not modified by the driver and core uses it as const. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s3c-camif/camif-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c index 2d5bd3ac7f81..f47b332f0418 100644 --- a/drivers/media/platform/s3c-camif/camif-core.c +++ b/drivers/media/platform/s3c-camif/camif-core.c @@ -628,7 +628,7 @@ static struct s3c_camif_drvdata s3c6410_camif_drvdata = { .bus_clk_freq = 133000000UL, }; -static struct platform_device_id s3c_camif_driver_ids[] = { +static const struct platform_device_id s3c_camif_driver_ids[] = { { .name = "s3c2440-camif", .driver_data = (unsigned long)&s3c244x_camif_drvdata, -- cgit v1.2.3-59-g8ed1b From 6425f646ffb1da577501098331da38df91d6aa6d Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 1 May 2015 12:51:03 -0300 Subject: [media] media: platform: s5p: Constify platform_device_id The platform_device_id is not modified by the driver and core uses it as const. Signed-off-by: Krzysztof Kozlowski [k.debski@samsung.com: Fix misspelling in title (s/sp5/s5p/)] Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-g2d/g2d.c | 2 +- drivers/media/platform/s5p-mfc/s5p_mfc.c | 2 +- drivers/media/platform/s5p-tv/hdmi_drv.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c index ec3e1248923d..421a7c3b595b 100644 --- a/drivers/media/platform/s5p-g2d/g2d.c +++ b/drivers/media/platform/s5p-g2d/g2d.c @@ -787,7 +787,7 @@ static const struct of_device_id exynos_g2d_match[] = { }; MODULE_DEVICE_TABLE(of, exynos_g2d_match); -static struct platform_device_id g2d_driver_ids[] = { +static const struct platform_device_id g2d_driver_ids[] = { { .name = "s5p-g2d", .driver_data = (unsigned long)&g2d_drvdata_v3x, diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 1263d99d638e..684a3363d1b8 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -1461,7 +1461,7 @@ static struct s5p_mfc_variant mfc_drvdata_v8 = { .fw_name[0] = "s5p-mfc-v8.fw", }; -static struct platform_device_id mfc_driver_ids[] = { +static const struct platform_device_id mfc_driver_ids[] = { { .name = "s5p-mfc", .driver_data = (unsigned long)&mfc_drvdata_v5, diff --git a/drivers/media/platform/s5p-tv/hdmi_drv.c b/drivers/media/platform/s5p-tv/hdmi_drv.c index 618ecd1d5b27..79940757b34f 100644 --- a/drivers/media/platform/s5p-tv/hdmi_drv.c +++ b/drivers/media/platform/s5p-tv/hdmi_drv.c @@ -96,7 +96,7 @@ struct hdmi_device { struct hdmi_resources res; }; -static struct platform_device_id hdmi_driver_types[] = { +static const struct platform_device_id hdmi_driver_types[] = { { .name = "s5pv210-hdmi", }, { -- cgit v1.2.3-59-g8ed1b From c16218402a000bb25c1277c43ae98c11bcb59bd1 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 4 May 2015 07:51:06 -0300 Subject: [media] videobuf2: return -EPIPE from DQBUF after the last buffer If the last buffer was dequeued from a capture queue, let poll return immediately and let DQBUF return -EPIPE to signal there will no more buffers to dequeue until STREAMOFF. The driver signals the last buffer by setting the V4L2_BUF_FLAG_LAST. To reenable dequeuing on the capture queue, the driver must explicitly call vb2_clear_last_buffer_queued. The last buffer queued flag is cleared automatically during STREAMOFF. Signed-off-by: Philipp Zabel Acked-by: Hans Verkuil Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-mem2mem.c | 10 +++++++++- drivers/media/v4l2-core/videobuf2-core.c | 19 ++++++++++++++++++- include/media/videobuf2-core.h | 13 +++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index 73824a5ada83..cbef15c07e53 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -564,8 +564,16 @@ unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, if (list_empty(&src_q->done_list)) poll_wait(file, &src_q->done_wq, wait); - if (list_empty(&dst_q->done_list)) + if (list_empty(&dst_q->done_list)) { + /* + * If the last buffer was dequeued from the capture queue, + * return immediately. DQBUF will return -EPIPE. + */ + if (dst_q->last_buffer_dequeued) + return rc | POLLIN | POLLRDNORM; + poll_wait(file, &dst_q->done_wq, wait); + } if (m2m_ctx->m2m_dev->m2m_ops->lock) m2m_ctx->m2m_dev->m2m_ops->lock(m2m_ctx->priv); diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 20cdbc0900ea..552d7e127c39 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -1943,6 +1943,11 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking) return -EIO; } + if (q->last_buffer_dequeued) { + dprintk(3, "last buffer dequeued already, will not wait for buffers\n"); + return -EPIPE; + } + if (!list_empty(&q->done_list)) { /* * Found a buffer that we were waiting for. @@ -2098,6 +2103,9 @@ static int vb2_internal_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool n /* Remove from videobuf queue */ list_del(&vb->queued_entry); q->queued_count--; + if (!V4L2_TYPE_IS_OUTPUT(q->type) && + vb->v4l2_buf.flags & V4L2_BUF_FLAG_LAST) + q->last_buffer_dequeued = true; /* go back to dequeued state */ __vb2_dqbuf(vb); @@ -2311,6 +2319,7 @@ static int vb2_internal_streamoff(struct vb2_queue *q, enum v4l2_buf_type type) */ __vb2_queue_cancel(q); q->waiting_for_buffers = !V4L2_TYPE_IS_OUTPUT(q->type); + q->last_buffer_dequeued = false; dprintk(3, "successful\n"); return 0; @@ -2653,8 +2662,16 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait) if (V4L2_TYPE_IS_OUTPUT(q->type) && q->queued_count < q->num_buffers) return res | POLLOUT | POLLWRNORM; - if (list_empty(&q->done_list)) + if (list_empty(&q->done_list)) { + /* + * If the last buffer was dequeued from a capture queue, + * return immediately. DQBUF will return -EPIPE. + */ + if (q->last_buffer_dequeued) + return res | POLLIN | POLLRDNORM; + poll_wait(file, &q->done_wq, wait); + } /* * Take first buffer available for dequeuing. diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index a5790fd5d125..22a44c2f5963 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -381,6 +381,9 @@ struct v4l2_fh; * @waiting_for_buffers: used in poll() to check if vb2 is still waiting for * buffers. Only set for capture queues if qbuf has not yet been * called since poll() needs to return POLLERR in that situation. + * @last_buffer_dequeued: used in poll() and DQBUF to immediately return if the + * last decoded buffer was already dequeued. Set for capture queues + * when a buffer with the V4L2_BUF_FLAG_LAST is dequeued. * @fileio: file io emulator internal data, used only if emulator is active * @threadio: thread io internal data, used only if thread is active */ @@ -423,6 +426,7 @@ struct vb2_queue { unsigned int start_streaming_called:1; unsigned int error:1; unsigned int waiting_for_buffers:1; + unsigned int last_buffer_dequeued:1; struct vb2_fileio_data *fileio; struct vb2_threadio_data *threadio; @@ -603,6 +607,15 @@ static inline bool vb2_start_streaming_called(struct vb2_queue *q) return q->start_streaming_called; } +/** + * vb2_clear_last_buffer_dequeued() - clear last buffer dequeued flag of queue + * @q: videobuf queue + */ +static inline void vb2_clear_last_buffer_dequeued(struct vb2_queue *q) +{ + q->last_buffer_dequeued = false; +} + /* * The following functions are not part of the vb2 core API, but are simple * helper functions that you can use in your struct v4l2_file_operations, -- cgit v1.2.3-59-g8ed1b From 9f2bfb33a817459fdfe3277cdf864a2a4fe3ef7b Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 4 May 2015 07:51:07 -0300 Subject: [media] coda: Set last buffer flag and fix EOS event Setting the last buffer flag causes the videobuf2 core to return -EPIPE from DQBUF calls on the capture queue after the last buffer is dequeued. This patch also fixes the EOS event to conform to the specification. It now is sent right after the last buffer has been decoded instead of when the last buffer is dequeued. Signed-off-by: Philipp Zabel Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-bit.c | 4 ++-- drivers/media/platform/coda/coda-common.c | 27 +++++++++++---------------- drivers/media/platform/coda/coda.h | 3 +++ 3 files changed, 16 insertions(+), 18 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index d0430071d2ee..109797bb8fbb 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c @@ -1305,7 +1305,7 @@ static void coda_finish_encode(struct coda_ctx *ctx) v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE); dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); - v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE); + coda_m2m_buf_done(ctx, dst_buf, VB2_BUF_STATE_DONE); ctx->gopcounter--; if (ctx->gopcounter < 0) @@ -1975,7 +1975,7 @@ static void coda_finish_decode(struct coda_ctx *ctx) } vb2_set_plane_payload(dst_buf, 0, payload); - v4l2_m2m_buf_done(dst_buf, ctx->frame_errors[display_idx] ? + coda_m2m_buf_done(ctx, dst_buf, ctx->frame_errors[display_idx] ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE); v4l2_dbg(1, coda_debug, &dev->v4l2_dev, diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 8e6fe0200117..6d6e0ca91fb4 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -724,35 +724,30 @@ static int coda_qbuf(struct file *file, void *priv, } static bool coda_buf_is_end_of_stream(struct coda_ctx *ctx, - struct v4l2_buffer *buf) + struct vb2_buffer *buf) { struct vb2_queue *src_vq; src_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); return ((ctx->bit_stream_param & CODA_BIT_STREAM_END_FLAG) && - (buf->sequence == (ctx->qsequence - 1))); + (buf->v4l2_buf.sequence == (ctx->qsequence - 1))); } -static int coda_dqbuf(struct file *file, void *priv, - struct v4l2_buffer *buf) +void coda_m2m_buf_done(struct coda_ctx *ctx, struct vb2_buffer *buf, + enum vb2_buffer_state state) { - struct coda_ctx *ctx = fh_to_ctx(priv); - int ret; + const struct v4l2_event eos_event = { + .type = V4L2_EVENT_EOS + }; - ret = v4l2_m2m_dqbuf(file, ctx->fh.m2m_ctx, buf); - - /* If this is the last capture buffer, emit an end-of-stream event */ - if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && - coda_buf_is_end_of_stream(ctx, buf)) { - const struct v4l2_event eos_event = { - .type = V4L2_EVENT_EOS - }; + if (coda_buf_is_end_of_stream(ctx, buf)) { + buf->v4l2_buf.flags |= V4L2_BUF_FLAG_LAST; v4l2_event_queue_fh(&ctx->fh, &eos_event); } - return ret; + v4l2_m2m_buf_done(buf, state); } static int coda_g_selection(struct file *file, void *fh, @@ -865,7 +860,7 @@ static const struct v4l2_ioctl_ops coda_ioctl_ops = { .vidioc_qbuf = coda_qbuf, .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, - .vidioc_dqbuf = coda_dqbuf, + .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, .vidioc_streamon = v4l2_m2m_ioctl_streamon, diff --git a/drivers/media/platform/coda/coda.h b/drivers/media/platform/coda/coda.h index 6a5c8f6c688e..8e0af221b2e9 100644 --- a/drivers/media/platform/coda/coda.h +++ b/drivers/media/platform/coda/coda.h @@ -287,6 +287,9 @@ static inline unsigned int coda_get_bitstream_payload(struct coda_ctx *ctx) void coda_bit_stream_end_flag(struct coda_ctx *ctx); +void coda_m2m_buf_done(struct coda_ctx *ctx, struct vb2_buffer *buf, + enum vb2_buffer_state state); + int coda_h264_padding(int size, char *p); bool coda_jpeg_check_buffer(struct coda_ctx *ctx, struct vb2_buffer *vb); -- cgit v1.2.3-59-g8ed1b From 52722ca8c53243c2b3eb45731c01ec4d8d219f3b Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 4 May 2015 07:51:08 -0300 Subject: [media] s5p-mfc: Set last buffer flag Setting the last buffer flag causes the videobuf2 core to return -EPIPE from DQBUF calls on the capture queue after the last buffer is dequeued. Signed-off-by: Philipp Zabel Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 684a3363d1b8..8de61dc1e142 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -211,6 +211,7 @@ static void s5p_mfc_handle_frame_all_extracted(struct s5p_mfc_ctx *ctx) dst_buf->b->v4l2_buf.field = V4L2_FIELD_NONE; else dst_buf->b->v4l2_buf.field = V4L2_FIELD_INTERLACED; + dst_buf->b->v4l2_buf.flags |= V4L2_BUF_FLAG_LAST; ctx->dec_dst_flag &= ~(1 << dst_buf->b->v4l2_buf.index); vb2_buffer_done(dst_buf->b, VB2_BUF_STATE_DONE); -- cgit v1.2.3-59-g8ed1b From 7f099a7558e4d308ddb19b3c1737944c371b8f48 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Mon, 16 Mar 2015 16:54:33 -0300 Subject: [media] constify of_device_id array of_device_id is always used as const. (See driver.of_match_table and open firmware functions) [mchehab@osg.samsung.com: fix a merge conflict at adv7604.c] Signed-off-by: Fabian Frederick Acked-by: Patrice Chotard Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7604.c | 4 ++-- drivers/media/platform/fsl-viu.c | 2 +- drivers/media/platform/soc_camera/rcar_vin.c | 2 +- drivers/media/rc/gpio-ir-recv.c | 2 +- drivers/media/rc/ir-hix5hd2.c | 2 +- drivers/media/rc/st_rc.c | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index c1be0f721727..be3f8660e457 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -2642,14 +2642,14 @@ static const struct adv76xx_chip_info adv76xx_chip_info[] = { }, }; -static struct i2c_device_id adv76xx_i2c_id[] = { +static const struct i2c_device_id adv76xx_i2c_id[] = { { "adv7604", (kernel_ulong_t)&adv76xx_chip_info[ADV7604] }, { "adv7611", (kernel_ulong_t)&adv76xx_chip_info[ADV7611] }, { } }; MODULE_DEVICE_TABLE(i2c, adv76xx_i2c_id); -static struct of_device_id adv76xx_of_id[] __maybe_unused = { +static const struct of_device_id adv76xx_of_id[] __maybe_unused = { { .compatible = "adi,adv7611", .data = &adv76xx_chip_info[ADV7611] }, { } }; diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c index bbf428104871..5b76e3db6a92 100644 --- a/drivers/media/platform/fsl-viu.c +++ b/drivers/media/platform/fsl-viu.c @@ -1664,7 +1664,7 @@ static int viu_resume(struct platform_device *op) /* * Initialization and module stuff */ -static struct of_device_id mpc512x_viu_of_match[] = { +static const struct of_device_id mpc512x_viu_of_match[] = { { .compatible = "fsl,mpc5121-viu", }, diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c index 4c30d0dbdb30..4dc3288ddd06 100644 --- a/drivers/media/platform/soc_camera/rcar_vin.c +++ b/drivers/media/platform/soc_camera/rcar_vin.c @@ -1821,7 +1821,7 @@ static struct soc_camera_host_ops rcar_vin_host_ops = { }; #ifdef CONFIG_OF -static struct of_device_id rcar_vin_of_table[] = { +static const struct of_device_id rcar_vin_of_table[] = { { .compatible = "renesas,vin-r8a7794", .data = (void *)RCAR_GEN2 }, { .compatible = "renesas,vin-r8a7793", .data = (void *)RCAR_GEN2 }, { .compatible = "renesas,vin-r8a7791", .data = (void *)RCAR_GEN2 }, diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c index 229853d68451..707df5422666 100644 --- a/drivers/media/rc/gpio-ir-recv.c +++ b/drivers/media/rc/gpio-ir-recv.c @@ -59,7 +59,7 @@ static int gpio_ir_recv_get_devtree_pdata(struct device *dev, return 0; } -static struct of_device_id gpio_ir_recv_of_match[] = { +static const struct of_device_id gpio_ir_recv_of_match[] = { { .compatible = "gpio-ir-receiver", }, { }, }; diff --git a/drivers/media/rc/ir-hix5hd2.c b/drivers/media/rc/ir-hix5hd2.c index 58ec5986274e..838e29e3fd69 100644 --- a/drivers/media/rc/ir-hix5hd2.c +++ b/drivers/media/rc/ir-hix5hd2.c @@ -319,7 +319,7 @@ static int hix5hd2_ir_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(hix5hd2_ir_pm_ops, hix5hd2_ir_suspend, hix5hd2_ir_resume); -static struct of_device_id hix5hd2_ir_table[] = { +static const struct of_device_id hix5hd2_ir_table[] = { { .compatible = "hisilicon,hix5hd2-ir", }, {}, }; diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c index 0e758ae2e529..50ea09da7739 100644 --- a/drivers/media/rc/st_rc.c +++ b/drivers/media/rc/st_rc.c @@ -381,7 +381,7 @@ static int st_rc_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(st_rc_pm_ops, st_rc_suspend, st_rc_resume); #ifdef CONFIG_OF -static struct of_device_id st_rc_match[] = { +static const struct of_device_id st_rc_match[] = { { .compatible = "st,comms-irb", }, {}, }; -- cgit v1.2.3-59-g8ed1b From b3ab190f1c731e76da357f6640ceebacfdaccae1 Mon Sep 17 00:00:00 2001 From: "Lad, Prabhakar" Date: Wed, 15 Apr 2015 18:14:17 -0300 Subject: [media] media: i2c: ov2659: Use v4l2_of_alloc_parse_endpoint() Instead of parsing the link-frequencies property in the driver, let v4l2_of_alloc_parse_endpoint() do it. Signed-off-by: Lad, Prabhakar Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov2659.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c index d700a1d0a6f2..c8615f7f2627 100644 --- a/drivers/media/i2c/ov2659.c +++ b/drivers/media/i2c/ov2659.c @@ -1340,8 +1340,8 @@ static struct ov2659_platform_data * ov2659_get_pdata(struct i2c_client *client) { struct ov2659_platform_data *pdata; + struct v4l2_of_endpoint *bus_cfg; struct device_node *endpoint; - int ret; if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) return client->dev.platform_data; @@ -1350,18 +1350,27 @@ ov2659_get_pdata(struct i2c_client *client) if (!endpoint) return NULL; + bus_cfg = v4l2_of_alloc_parse_endpoint(endpoint); + if (IS_ERR(bus_cfg)) { + pdata = NULL; + goto done; + } + pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) goto done; - ret = of_property_read_u64(endpoint, "link-frequencies", - &pdata->link_frequency); - if (ret) { - dev_err(&client->dev, "link-frequencies property not found\n"); + if (!bus_cfg->nr_of_link_frequencies) { + dev_err(&client->dev, + "link-frequencies property not found or too many\n"); pdata = NULL; + goto done; } + pdata->link_frequency = bus_cfg->link_frequencies[0]; + done: + v4l2_of_free_endpoint(bus_cfg); of_node_put(endpoint); return pdata; } -- cgit v1.2.3-59-g8ed1b From ccf509f845576b8809702aa693867839bf77beb0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 24 Apr 2015 06:52:47 -0300 Subject: [media] marvell-ccic: fix RGB444 format The RGB444 format swapped the red and blue components, fix this. Rather than making a new BGR444 format (as I proposed initially), Jon prefers to just fix this and return the colors in the right order. I think that makes sense in this case. Since the RGB444 pixel format is deprecated due to the ambiguous specification of the alpha component we use the XRGB444 pixel format instead (specified as having no alpha channel). Signed-off-by: Hans Verkuil Acked-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/marvell-ccic/mcam-core.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index ce5b0eaf0c20..5e2b4df48b3c 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -138,8 +138,8 @@ static struct mcam_format_struct { .planar = true, }, { - .desc = "RGB 444", - .pixelformat = V4L2_PIX_FMT_RGB444, + .desc = "XRGB 444", + .pixelformat = V4L2_PIX_FMT_XRGB444, .mbus_code = MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, .bpp = 2, .planar = false, @@ -777,10 +777,9 @@ static void mcam_ctlr_image(struct mcam_camera *cam) mcam_reg_write_mask(cam, REG_CTRL0, C0_DF_YUV | C0_YUV_PACKED | C0_YUVE_SWAP24, C0_DF_MASK); break; - case V4L2_PIX_FMT_RGB444: + case V4L2_PIX_FMT_XRGB444: mcam_reg_write_mask(cam, REG_CTRL0, - C0_DF_RGB | C0_RGBF_444 | C0_RGB4_XRGB, C0_DF_MASK); - /* Alpha value? */ + C0_DF_RGB | C0_RGBF_444 | C0_RGB4_XBGR, C0_DF_MASK); break; case V4L2_PIX_FMT_RGB565: mcam_reg_write_mask(cam, REG_CTRL0, -- cgit v1.2.3-59-g8ed1b From 44767fc418b6f69f629f70033eb7a08de396224e Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Sat, 21 Mar 2015 17:42:23 -0300 Subject: [media] dw2102: TeVii S482 support TeVii S482 is a PCIe device with two tuners that actually contains two USB devices. The devices are visible in the lsusb printout. Bus 006 Device 002: ID 9022:d483 TeVii Technology Ltd. Bus 007 Device 002: ID 9022:d484 TeVii Technology Ltd. The device itself works exactly with the same settings as TechnoTrend TT-connect S2-4600. Firmware for DS3103 demodulator is required: http://palosaari.fi/linux/v4l-dvb/firmware/M88DS3103/ This patch should be applied on top of the TT S2-4600 patch: https://patchwork.linuxtv.org/patch/28818/ Signed-off-by: Olli Salonen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/dw2102.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c index 28fd6bacb852..0a1dc3759c7c 100644 --- a/drivers/media/usb/dvb-usb/dw2102.c +++ b/drivers/media/usb/dvb-usb/dw2102.c @@ -1657,6 +1657,8 @@ enum dw2102_table_entry { GOTVIEW_SAT_HD, GENIATECH_T220, TECHNOTREND_S2_4600, + TEVII_S482_1, + TEVII_S482_2, }; static struct usb_device_id dw2102_table[] = { @@ -1682,6 +1684,8 @@ static struct usb_device_id dw2102_table[] = { [GENIATECH_T220] = {USB_DEVICE(0x1f4d, 0xD220)}, [TECHNOTREND_S2_4600] = {USB_DEVICE(USB_VID_TECHNOTREND, USB_PID_TECHNOTREND_CONNECT_S2_4600)}, + [TEVII_S482_1] = {USB_DEVICE(0x9022, 0xd483)}, + [TEVII_S482_2] = {USB_DEVICE(0x9022, 0xd484)}, { } }; @@ -2199,12 +2203,20 @@ static struct dvb_usb_device_properties tt_s2_4600_properties = { } }, } }, - .num_device_descs = 1, + .num_device_descs = 3, .devices = { { "TechnoTrend TT-connect S2-4600", { &dw2102_table[TECHNOTREND_S2_4600], NULL }, { NULL }, }, + { "TeVii S482 (tuner 1)", + { &dw2102_table[TEVII_S482_1], NULL }, + { NULL }, + }, + { "TeVii S482 (tuner 2)", + { &dw2102_table[TEVII_S482_2], NULL }, + { NULL }, + }, } }; -- cgit v1.2.3-59-g8ed1b From b2624ff4bf46869df66148b2e1e675981565742e Mon Sep 17 00:00:00 2001 From: Silvan Jegen Date: Mon, 23 Mar 2015 13:25:53 -0300 Subject: [media] mantis: fix error handling Remove dead code, make goto label names more expressive and add a label in order to call mantis_dvb_exit if mantis_uart_init fails. Also make sure that mantis_pci_exit is called if we fail the mantis_stream_control call and that we call mantis_i2c_exit if mantis_get_mac fails. [mchehab@osg.samsung.com: fix merge conflict] Signed-off-by: Silvan Jegen Reviewed-by: Dan Carpenter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/mantis/mantis_cards.c | 36 +++++++++++++++------------------ 1 file changed, 16 insertions(+), 20 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/mantis/mantis_cards.c b/drivers/media/pci/mantis/mantis_cards.c index f437646aa9aa..9861a8cf1dce 100644 --- a/drivers/media/pci/mantis/mantis_cards.c +++ b/drivers/media/pci/mantis/mantis_cards.c @@ -169,8 +169,7 @@ static int mantis_pci_probe(struct pci_dev *pdev, mantis = kzalloc(sizeof(struct mantis_pci), GFP_KERNEL); if (mantis == NULL) { printk(KERN_ERR "%s ERROR: Out of memory\n", __func__); - err = -ENOMEM; - goto fail0; + return -ENOMEM; } mantis->num = devs; @@ -183,67 +182,64 @@ static int mantis_pci_probe(struct pci_dev *pdev, err = mantis_pci_init(mantis); if (err) { dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI initialization failed <%d>", err); - goto fail1; + goto err_free_mantis; } err = mantis_stream_control(mantis, STREAM_TO_HIF); if (err < 0) { dprintk(MANTIS_ERROR, 1, "ERROR: Mantis stream control failed <%d>", err); - goto fail1; + goto err_pci_exit; } err = mantis_i2c_init(mantis); if (err < 0) { dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C initialization failed <%d>", err); - goto fail2; + goto err_pci_exit; } err = mantis_get_mac(mantis); if (err < 0) { dprintk(MANTIS_ERROR, 1, "ERROR: Mantis MAC address read failed <%d>", err); - goto fail2; + goto err_i2c_exit; } err = mantis_dma_init(mantis); if (err < 0) { dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA initialization failed <%d>", err); - goto fail3; + goto err_i2c_exit; } err = mantis_dvb_init(mantis); if (err < 0) { dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err); - goto fail4; + goto err_dma_exit; } + err = mantis_uart_init(mantis); if (err < 0) { dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART initialization failed <%d>", err); - goto fail6; + goto err_dvb_exit; } devs++; - return err; + return 0; +err_dvb_exit: + mantis_dvb_exit(mantis); -fail6: -fail4: - dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA exit! <%d>", err); +err_dma_exit: mantis_dma_exit(mantis); -fail3: - dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C exit! <%d>", err); +err_i2c_exit: mantis_i2c_exit(mantis); -fail2: - dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI exit! <%d>", err); +err_pci_exit: mantis_pci_exit(mantis); -fail1: - dprintk(MANTIS_ERROR, 1, "ERROR: Mantis free! <%d>", err); +err_free_mantis: kfree(mantis); -fail0: return err; } -- cgit v1.2.3-59-g8ed1b From 8117a3121da1881f8730d38ed9ebfc1c1a6ffda9 Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Tue, 5 May 2015 13:54:14 -0300 Subject: [media] si2168: add support for gapped clock Add a parameter in si2168_config to support gapped clock. This might be necessary on some devices with higher bitrates. Signed-off-by: Olli Salonen Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/si2168.c | 3 +++ drivers/media/dvb-frontends/si2168.h | 3 +++ drivers/media/dvb-frontends/si2168_priv.h | 1 + 3 files changed, 7 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c index 5db588ebfc24..29a59369ea7b 100644 --- a/drivers/media/dvb-frontends/si2168.c +++ b/drivers/media/dvb-frontends/si2168.c @@ -508,6 +508,8 @@ static int si2168_init(struct dvb_frontend *fe) /* set ts mode */ memcpy(cmd.args, "\x14\x00\x01\x10\x10\x00", 6); cmd.args[4] |= dev->ts_mode; + if (dev->ts_clock_gapped) + cmd.args[4] |= 0x40; cmd.wlen = 6; cmd.rlen = 4; ret = si2168_cmd_execute(client, &cmd); @@ -688,6 +690,7 @@ static int si2168_probe(struct i2c_client *client, *config->fe = &dev->fe; dev->ts_mode = config->ts_mode; dev->ts_clock_inv = config->ts_clock_inv; + dev->ts_clock_gapped = config->ts_clock_gapped; dev->fw_loaded = false; i2c_set_clientdata(client, dev); diff --git a/drivers/media/dvb-frontends/si2168.h b/drivers/media/dvb-frontends/si2168.h index 70d702ae6f49..3225d0cc93c7 100644 --- a/drivers/media/dvb-frontends/si2168.h +++ b/drivers/media/dvb-frontends/si2168.h @@ -42,6 +42,9 @@ struct si2168_config { /* TS clock inverted */ bool ts_clock_inv; + + /* TS clock gapped */ + bool ts_clock_gapped; }; #endif diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h index d7efce8043ed..d2589e3d2ff2 100644 --- a/drivers/media/dvb-frontends/si2168_priv.h +++ b/drivers/media/dvb-frontends/si2168_priv.h @@ -38,6 +38,7 @@ struct si2168_dev { bool fw_loaded; u8 ts_mode; bool ts_clock_inv; + bool ts_clock_gapped; }; /* firmware command struct */ -- cgit v1.2.3-59-g8ed1b From c060f9329f4a5aa94d8e61c8f2bb8996a8180059 Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Tue, 5 May 2015 13:54:15 -0300 Subject: [media] dvbsky: use si2168 config option ts_clock_gapped Change the dvbsky driver to support gapped clock instead of the current hack. Signed-off-by: Olli Salonen Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/dvbsky.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c index cdf59bcd760c..0f73b1d23d56 100644 --- a/drivers/media/usb/dvb-usb-v2/dvbsky.c +++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c @@ -615,7 +615,8 @@ static int dvbsky_t330_attach(struct dvb_usb_adapter *adap) memset(&si2168_config, 0, sizeof(si2168_config)); si2168_config.i2c_adapter = &i2c_adapter; si2168_config.fe = &adap->fe[0]; - si2168_config.ts_mode = SI2168_TS_PARALLEL | 0x40; + si2168_config.ts_mode = SI2168_TS_PARALLEL; + si2168_config.ts_clock_gapped = true; memset(&info, 0, sizeof(struct i2c_board_info)); strlcpy(info.type, "si2168", I2C_NAME_SIZE); info.addr = 0x64; -- cgit v1.2.3-59-g8ed1b From 7adf99d20ce0e96a70755f452e3a63824b14060f Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Tue, 5 May 2015 13:54:16 -0300 Subject: [media] si2168: add I2C error handling Return error from si2168_cmd_execute in case the demodulator returns an error. Signed-off-by: Olli Salonen Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/si2168.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c index 29a59369ea7b..b68ab346b93b 100644 --- a/drivers/media/dvb-frontends/si2168.c +++ b/drivers/media/dvb-frontends/si2168.c @@ -60,6 +60,12 @@ static int si2168_cmd_execute(struct i2c_client *client, struct si2168_cmd *cmd) jiffies_to_msecs(jiffies) - (jiffies_to_msecs(timeout) - TIMEOUT)); + /* error bit set? */ + if ((cmd->args[0] >> 6) & 0x01) { + ret = -EREMOTEIO; + goto err_mutex_unlock; + } + if (!((cmd->args[0] >> 7) & 0x01)) { ret = -ETIMEDOUT; goto err_mutex_unlock; -- cgit v1.2.3-59-g8ed1b From ee3c3e46885946cc041f08ec68e7c5b91b087cbe Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Tue, 5 May 2015 13:54:17 -0300 Subject: [media] si2157: support selection of IF interface The chips supported by the si2157 driver have two IF outputs (either pins 12+13 or pins 9+11). Instead of hardcoding the output to be used add an option to choose which output shall be used. As this patch changes the default behaviour, the IF interface is specified in each driver currently using si2157 driver. This is to keep bisectability. Signed-off-by: Olli Salonen Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-dvb.c | 4 ++++ drivers/media/pci/saa7164/saa7164-dvb.c | 3 +++ drivers/media/pci/smipcie/smipcie.c | 1 + drivers/media/tuners/si2157.c | 4 +++- drivers/media/tuners/si2157.h | 6 ++++++ drivers/media/tuners/si2157_priv.h | 1 + drivers/media/usb/cx231xx/cx231xx-dvb.c | 2 ++ drivers/media/usb/dvb-usb-v2/af9035.c | 1 + drivers/media/usb/dvb-usb-v2/dvbsky.c | 2 ++ drivers/media/usb/dvb-usb/cxusb.c | 1 + drivers/media/usb/em28xx/em28xx-dvb.c | 2 ++ 11 files changed, 26 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 745caabe3397..37fd013c385b 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -1912,6 +1912,7 @@ static int dvb_register(struct cx23885_tsport *port) /* attach tuner */ memset(&si2157_config, 0, sizeof(si2157_config)); si2157_config.fe = fe0->dvb.frontend; + si2157_config.if_port = 1; memset(&info, 0, sizeof(struct i2c_board_info)); strlcpy(info.type, "si2157", I2C_NAME_SIZE); info.addr = 0x60; @@ -1957,6 +1958,7 @@ static int dvb_register(struct cx23885_tsport *port) /* attach tuner */ memset(&si2157_config, 0, sizeof(si2157_config)); si2157_config.fe = fe0->dvb.frontend; + si2157_config.if_port = 1; memset(&info, 0, sizeof(struct i2c_board_info)); strlcpy(info.type, "si2157", I2C_NAME_SIZE); info.addr = 0x60; @@ -2093,6 +2095,7 @@ static int dvb_register(struct cx23885_tsport *port) /* attach tuner */ memset(&si2157_config, 0, sizeof(si2157_config)); si2157_config.fe = fe0->dvb.frontend; + si2157_config.if_port = 1; memset(&info, 0, sizeof(struct i2c_board_info)); strlcpy(info.type, "si2157", I2C_NAME_SIZE); info.addr = 0x60; @@ -2172,6 +2175,7 @@ static int dvb_register(struct cx23885_tsport *port) /* attach tuner */ memset(&si2157_config, 0, sizeof(si2157_config)); si2157_config.fe = fe0->dvb.frontend; + si2157_config.if_port = 1; memset(&info, 0, sizeof(struct i2c_board_info)); strlcpy(info.type, "si2157", I2C_NAME_SIZE); info.addr = 0x60; diff --git a/drivers/media/pci/saa7164/saa7164-dvb.c b/drivers/media/pci/saa7164/saa7164-dvb.c index 99698002a808..e9a783b71b45 100644 --- a/drivers/media/pci/saa7164/saa7164-dvb.c +++ b/drivers/media/pci/saa7164/saa7164-dvb.c @@ -111,6 +111,7 @@ static struct lgdt3306a_config hauppauge_hvr2255b_config = { static struct si2157_config hauppauge_hvr2255_tuner_config = { .inversion = 1, + .if_port = 1, }; static int si2157_attach(struct saa7164_port *port, struct i2c_adapter *adapter, @@ -665,6 +666,7 @@ int saa7164_dvb_register(struct saa7164_port *port) /* attach tuner */ memset(&si2157_config, 0, sizeof(si2157_config)); + si2157_config.if_port = 1; si2157_config.fe = port->dvb.frontend; memset(&info, 0, sizeof(struct i2c_board_info)); strlcpy(info.type, "si2157", I2C_NAME_SIZE); @@ -710,6 +712,7 @@ int saa7164_dvb_register(struct saa7164_port *port) /* attach tuner */ memset(&si2157_config, 0, sizeof(si2157_config)); si2157_config.fe = port->dvb.frontend; + si2157_config.if_port = 1; memset(&info, 0, sizeof(struct i2c_board_info)); strlcpy(info.type, "si2157", I2C_NAME_SIZE); info.addr = 0xc0 >> 1; diff --git a/drivers/media/pci/smipcie/smipcie.c b/drivers/media/pci/smipcie/smipcie.c index 411592524c63..143fd7899ecd 100644 --- a/drivers/media/pci/smipcie/smipcie.c +++ b/drivers/media/pci/smipcie/smipcie.c @@ -657,6 +657,7 @@ static int smi_dvbsky_sit2_fe_attach(struct smi_port *port) /* attach tuner */ memset(&si2157_config, 0, sizeof(si2157_config)); si2157_config.fe = port->fe; + si2157_config.if_port = 1; memset(&client_info, 0, sizeof(struct i2c_board_info)); strlcpy(client_info.type, "si2157", I2C_NAME_SIZE); diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c index d74ae26621ca..cdaf68781a2e 100644 --- a/drivers/media/tuners/si2157.c +++ b/drivers/media/tuners/si2157.c @@ -298,7 +298,8 @@ static int si2157_set_params(struct dvb_frontend *fe) if (dev->chiptype == SI2157_CHIPTYPE_SI2146) memcpy(cmd.args, "\x14\x00\x02\x07\x00\x01", 6); else - memcpy(cmd.args, "\x14\x00\x02\x07\x01\x00", 6); + memcpy(cmd.args, "\x14\x00\x02\x07\x00\x00", 6); + cmd.args[4] = dev->if_port; cmd.wlen = 6; cmd.rlen = 4; ret = si2157_cmd_execute(client, &cmd); @@ -378,6 +379,7 @@ static int si2157_probe(struct i2c_client *client, i2c_set_clientdata(client, dev); dev->fe = cfg->fe; dev->inversion = cfg->inversion; + dev->if_port = cfg->if_port; dev->fw_loaded = false; dev->chiptype = (u8)id->driver_data; dev->if_frequency = 5000000; /* default value of property 0x0706 */ diff --git a/drivers/media/tuners/si2157.h b/drivers/media/tuners/si2157.h index a564c4a9fba7..4db97ab744d6 100644 --- a/drivers/media/tuners/si2157.h +++ b/drivers/media/tuners/si2157.h @@ -34,6 +34,12 @@ struct si2157_config { * Spectral Inversion */ bool inversion; + + /* + * Port selection + * Select the RF interface to use (pins 9+11 or 12+13) + */ + u8 if_port; }; #endif diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h index cd8fa5b25304..71a5f8c389de 100644 --- a/drivers/media/tuners/si2157_priv.h +++ b/drivers/media/tuners/si2157_priv.h @@ -28,6 +28,7 @@ struct si2157_dev { bool fw_loaded; bool inversion; u8 chiptype; + u8 if_port; u32 if_frequency; }; diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c index 610d5675bde6..66ee161fc7ba 100644 --- a/drivers/media/usb/cx231xx/cx231xx-dvb.c +++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c @@ -797,6 +797,7 @@ static int dvb_init(struct cx231xx *dev) /* attach tuner */ memset(&si2157_config, 0, sizeof(si2157_config)); si2157_config.fe = dev->dvb->frontend; + si2157_config.if_port = 1; si2157_config.inversion = true; strlcpy(info.type, "si2157", I2C_NAME_SIZE); info.addr = 0x60; @@ -852,6 +853,7 @@ static int dvb_init(struct cx231xx *dev) /* attach tuner */ memset(&si2157_config, 0, sizeof(si2157_config)); si2157_config.fe = dev->dvb->frontend; + si2157_config.if_port = 1; si2157_config.inversion = true; strlcpy(info.type, "si2157", I2C_NAME_SIZE); info.addr = 0x60; diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index 80a29f5377ea..7b7f75d8216e 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c @@ -1569,6 +1569,7 @@ static int it930x_tuner_attach(struct dvb_usb_adapter *adap) memset(&si2157_config, 0, sizeof(si2157_config)); si2157_config.fe = adap->fe[0]; + si2157_config.if_port = 1; ret = af9035_add_i2c_dev(d, "si2157", 0x63, &si2157_config, state->i2c_adapter_demod); diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c index 0f73b1d23d56..57c8c2db9f2d 100644 --- a/drivers/media/usb/dvb-usb-v2/dvbsky.c +++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c @@ -549,6 +549,7 @@ static int dvbsky_t680c_attach(struct dvb_usb_adapter *adap) /* attach tuner */ memset(&si2157_config, 0, sizeof(si2157_config)); si2157_config.fe = adap->fe[0]; + si2157_config.if_port = 1; memset(&info, 0, sizeof(struct i2c_board_info)); strlcpy(info.type, "si2157", I2C_NAME_SIZE); info.addr = 0x60; @@ -633,6 +634,7 @@ static int dvbsky_t330_attach(struct dvb_usb_adapter *adap) /* attach tuner */ memset(&si2157_config, 0, sizeof(si2157_config)); si2157_config.fe = adap->fe[0]; + si2157_config.if_port = 1; memset(&info, 0, sizeof(struct i2c_board_info)); strlcpy(info.type, "si2157", I2C_NAME_SIZE); info.addr = 0x60; diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c index ffc3704abded..ab7151181728 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c +++ b/drivers/media/usb/dvb-usb/cxusb.c @@ -1350,6 +1350,7 @@ static int cxusb_mygica_t230_frontend_attach(struct dvb_usb_adapter *adap) /* attach tuner */ memset(&si2157_config, 0, sizeof(si2157_config)); si2157_config.fe = adap->fe_adap[0].fe; + si2157_config.if_port = 1; memset(&info, 0, sizeof(struct i2c_board_info)); strlcpy(info.type, "si2157", I2C_NAME_SIZE); info.addr = 0x60; diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index a5b22c5a240c..5b7c7c888274 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -1579,6 +1579,7 @@ static int em28xx_dvb_init(struct em28xx *dev) /* attach tuner */ memset(&si2157_config, 0, sizeof(si2157_config)); si2157_config.fe = dvb->fe[0]; + si2157_config.if_port = 1; memset(&info, 0, sizeof(struct i2c_board_info)); strlcpy(info.type, "si2157", I2C_NAME_SIZE); info.addr = 0x60; @@ -1639,6 +1640,7 @@ static int em28xx_dvb_init(struct em28xx *dev) /* attach tuner */ memset(&si2157_config, 0, sizeof(si2157_config)); si2157_config.fe = dvb->fe[0]; + si2157_config.if_port = 0; memset(&info, 0, sizeof(struct i2c_board_info)); strlcpy(info.type, "si2146", I2C_NAME_SIZE); info.addr = 0x60; -- cgit v1.2.3-59-g8ed1b From d744a0cb8a819e93ad3852705a8df7bbe4599ad4 Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Tue, 5 May 2015 13:54:18 -0300 Subject: [media] rtl28xxu: add I2C read without write Add support for I2C read operation without a preceeding write. While here, change the error code to EOPNOTSUPP in case an unsupported I2C operation is attempted. Signed-off-by: Olli Salonen Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 895441fe90f7..54cb10979d99 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -232,8 +232,14 @@ static int rtl28xxu_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], req.data = msg[0].buf; ret = rtl28xxu_ctrl_msg(d, &req); } + } else if (num == 1 && (msg[0].flags & I2C_M_RD)) { + req.value = (msg[0].addr << 1); + req.index = CMD_I2C_DA_RD; + req.size = msg[0].len; + req.data = msg[0].buf; + ret = rtl28xxu_ctrl_msg(d, &req); } else { - ret = -EINVAL; + ret = -EOPNOTSUPP; } err_mutex_unlock: -- cgit v1.2.3-59-g8ed1b From 699dcffc5244388a38f6323afc15ed3833c1ad96 Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Tue, 5 May 2015 13:54:19 -0300 Subject: [media] rtl2832: add support for GoTView MasterHD 3 USB tuner GoTView MasterHD 3 is a DVB-T2/C USB 2.0 tuner. It's based on the following components: - USB bridge: RTL2832P (contains also DVB-T demodulator) - Demodulator: Si2168-A30 - Tuner: Si2148-A20 The demodulator and the tuner will need firmwares. The Si2148 uses Si2158 firmware. Antti has the firmwares available for download: http://palosaari.fi/linux/v4l-dvb/firmware/ Do note that for DVB-T either of the demodulators can be used. DVB-C and DVB-T2 are only supported by the Si2168 demodulator. The driver will register 2 frontends for the same adapter. Frontend 0 will be the RTL2832 demodulator and frontend 1 will be the Si2168 demodulator. The same tuner is used for both. As a consequence of the above, it's recommended to use application that does implement proper DVBv5 support. For some reason, the old I2C write method sporadically fails. Thus the need for an option to only use the new I2C write method supported by the RTL2832. Signed-off-by: Olli Salonen Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/rtl2832.c | 4 + drivers/media/dvb-frontends/rtl2832.h | 1 + drivers/media/dvb-frontends/rtl2832_priv.h | 25 ++++++ drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 117 ++++++++++++++++++++++++++++- drivers/media/usb/dvb-usb-v2/rtl28xxu.h | 5 ++ 5 files changed, 149 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c index b400f7b3c2e7..55a8b1f26bee 100644 --- a/drivers/media/dvb-frontends/rtl2832.c +++ b/drivers/media/dvb-frontends/rtl2832.c @@ -376,6 +376,10 @@ static int rtl2832_init(struct dvb_frontend *fe) len = ARRAY_SIZE(rtl2832_tuner_init_r820t); init = rtl2832_tuner_init_r820t; break; + case RTL2832_TUNER_SI2157: + len = ARRAY_SIZE(rtl2832_tuner_init_si2157); + init = rtl2832_tuner_init_si2157; + break; default: ret = -EINVAL; goto err; diff --git a/drivers/media/dvb-frontends/rtl2832.h b/drivers/media/dvb-frontends/rtl2832.h index a8e912e679a5..c6cdcc45d1ce 100644 --- a/drivers/media/dvb-frontends/rtl2832.h +++ b/drivers/media/dvb-frontends/rtl2832.h @@ -47,6 +47,7 @@ struct rtl2832_platform_data { #define RTL2832_TUNER_FC0013 0x29 #define RTL2832_TUNER_R820T 0x2a #define RTL2832_TUNER_R828D 0x2b +#define RTL2832_TUNER_SI2157 0x2c u8 tuner; struct dvb_frontend* (*get_dvb_frontend)(struct i2c_client *); diff --git a/drivers/media/dvb-frontends/rtl2832_priv.h b/drivers/media/dvb-frontends/rtl2832_priv.h index c3a922c37903..a973b8aba07c 100644 --- a/drivers/media/dvb-frontends/rtl2832_priv.h +++ b/drivers/media/dvb-frontends/rtl2832_priv.h @@ -377,4 +377,29 @@ static const struct rtl2832_reg_value rtl2832_tuner_init_r820t[] = { {DVBT_SPEC_INV, 0x1}, }; +static const struct rtl2832_reg_value rtl2832_tuner_init_si2157[] = { + {DVBT_DAGC_TRG_VAL, 0x39}, + {DVBT_AGC_TARG_VAL_0, 0x0}, + {DVBT_AGC_TARG_VAL_8_1, 0x40}, + {DVBT_AAGC_LOOP_GAIN, 0x16}, + {DVBT_LOOP_GAIN2_3_0, 0x8}, + {DVBT_LOOP_GAIN2_4, 0x1}, + {DVBT_LOOP_GAIN3, 0x18}, + {DVBT_VTOP1, 0x35}, + {DVBT_VTOP2, 0x21}, + {DVBT_VTOP3, 0x21}, + {DVBT_KRF1, 0x0}, + {DVBT_KRF2, 0x40}, + {DVBT_KRF3, 0x10}, + {DVBT_KRF4, 0x10}, + {DVBT_IF_AGC_MIN, 0x80}, + {DVBT_IF_AGC_MAX, 0x7f}, + {DVBT_RF_AGC_MIN, 0x80}, + {DVBT_RF_AGC_MAX, 0x7f}, + {DVBT_POLAR_RF_AGC, 0x0}, + {DVBT_POLAR_IF_AGC, 0x0}, + {DVBT_AD7_SETTING, 0xe9f4}, + {DVBT_SPEC_INV, 0x0}, +}; + #endif /* RTL2832_PRIV_H */ diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 54cb10979d99..616be9950904 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -217,7 +217,7 @@ static int rtl28xxu_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], req.data = &msg[0].buf[1]; ret = rtl28xxu_ctrl_msg(d, &req); } - } else if (msg[0].len < 23) { + } else if ((msg[0].len < 23) && (!dev->new_i2c_write)) { /* method 2 - old I2C */ req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1); req.index = CMD_I2C_WR; @@ -363,6 +363,8 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) struct rtl28xxu_req req_r828d = {0x0074, CMD_I2C_RD, 1, buf}; struct rtl28xxu_req req_mn88472 = {0xff38, CMD_I2C_RD, 1, buf}; struct rtl28xxu_req req_mn88473 = {0xff38, CMD_I2C_RD, 1, buf}; + struct rtl28xxu_req req_si2157 = {0x00c0, CMD_I2C_RD, 1, buf}; + struct rtl28xxu_req req_si2168 = {0x00c8, CMD_I2C_RD, 1, buf}; dev_dbg(&d->intf->dev, "\n"); @@ -483,6 +485,35 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) goto tuner_found; } + /* GPIO0 and GPIO5 to reset Si2157/Si2168 tuner and demod */ + ret = rtl28xxu_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x00, 0x21); + if (ret) + goto err; + + ret = rtl28xxu_wr_reg_mask(d, SYS_GPIO_OUT_EN, 0x00, 0x21); + if (ret) + goto err; + + msleep(50); + + ret = rtl28xxu_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x21, 0x21); + if (ret) + goto err; + + ret = rtl28xxu_wr_reg_mask(d, SYS_GPIO_OUT_EN, 0x21, 0x21); + if (ret) + goto err; + + msleep(50); + + /* check Si2157 ID register; reg=c0 val=80 */ + ret = rtl28xxu_ctrl_msg(d, &req_si2157); + if (ret == 0 && ((buf[0] & 0x80) == 0x80)) { + dev->tuner = TUNER_RTL2832_SI2157; + dev->tuner_name = "SI2157"; + goto tuner_found; + } + tuner_found: dev_dbg(&d->intf->dev, "tuner=%s\n", dev->tuner_name); @@ -516,6 +547,15 @@ tuner_found: goto demod_found; } } + if (dev->tuner == TUNER_RTL2832_SI2157) { + /* check Si2168 ID register; reg=c8 val=80 */ + ret = rtl28xxu_ctrl_msg(d, &req_si2168); + if (ret == 0 && ((buf[0] & 0x80) == 0x80)) { + dev_dbg(&d->intf->dev, "Si2168 found\n"); + dev->slave_demod = SLAVE_DEMOD_SI2168; + goto demod_found; + } + } demod_found: /* close demod I2C gate */ @@ -674,6 +714,11 @@ static const struct rtl2832_platform_data rtl2832_r820t_platform_data = { .tuner = TUNER_RTL2832_R820T, }; +static const struct rtl2832_platform_data rtl2832_si2157_platform_data = { + .clk = 28800000, + .tuner = TUNER_RTL2832_SI2157, +}; + static int rtl2832u_fc0012_tuner_callback(struct dvb_usb_device *d, int cmd, int arg) { @@ -823,6 +868,9 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap) case TUNER_RTL2832_R828D: *pdata = rtl2832_r820t_platform_data; break; + case TUNER_RTL2832_SI2157: + *pdata = rtl2832_si2157_platform_data; + break; default: dev_err(&d->intf->dev, "unknown tuner %s\n", dev->tuner_name); ret = -ENODEV; @@ -890,7 +938,7 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap) } dev->i2c_client_slave_demod = client; - } else { + } else if (dev->slave_demod == SLAVE_DEMOD_MN88473) { struct mn88473_config mn88473_config = {}; mn88473_config.fe = &adap->fe[1]; @@ -912,9 +960,37 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap) } dev->i2c_client_slave_demod = client; + } else { + struct si2168_config si2168_config = {}; + struct i2c_adapter *adapter; + + si2168_config.i2c_adapter = &adapter; + si2168_config.fe = &adap->fe[1]; + si2168_config.ts_mode = SI2168_TS_SERIAL; + si2168_config.ts_clock_inv = false; + si2168_config.ts_clock_gapped = true; + strlcpy(info.type, "si2168", I2C_NAME_SIZE); + info.addr = 0x64; + info.platform_data = &si2168_config; + request_module(info.type); + client = i2c_new_device(&d->i2c_adap, &info); + if (client == NULL || client->dev.driver == NULL) { + dev->slave_demod = SLAVE_DEMOD_NONE; + goto err_slave_demod_failed; + } + + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + dev->slave_demod = SLAVE_DEMOD_NONE; + goto err_slave_demod_failed; + } + + dev->i2c_client_slave_demod = client; + + /* for Si2168 devices use only new I2C write method */ + dev->new_i2c_write = true; } } - return 0; err_slave_demod_failed: err: @@ -1154,6 +1230,39 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) adap->fe[1]->ops.tuner_ops.get_rf_strength; } break; + case TUNER_RTL2832_SI2157: { + struct si2157_config si2157_config = { + .fe = adap->fe[0], + .if_port = 0, + .inversion = false, + }; + + strlcpy(info.type, "si2157", I2C_NAME_SIZE); + info.addr = 0x60; + info.platform_data = &si2157_config; + request_module(info.type); + client = i2c_new_device(&d->i2c_adap, &info); + if (client == NULL || client->dev.driver == NULL) + break; + + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + break; + } + + dev->i2c_client_tuner = client; + subdev = i2c_get_clientdata(client); + + /* copy tuner ops for 2nd FE as tuner is shared */ + if (adap->fe[1]) { + adap->fe[1]->tuner_priv = + adap->fe[0]->tuner_priv; + memcpy(&adap->fe[1]->ops.tuner_ops, + &adap->fe[0]->ops.tuner_ops, + sizeof(struct dvb_tuner_ops)); + } + } + break; default: dev_err(&d->intf->dev, "unknown tuner %d\n", dev->tuner); } @@ -1770,6 +1879,8 @@ static const struct usb_device_id rtl28xxu_id_table[] = { /* RTL2832P devices: */ { DVB_USB_DEVICE(USB_VID_HANFTEK, 0x0131, &rtl28xxu_props, "Astrometa DVB-T2", NULL) }, + { DVB_USB_DEVICE(0x5654, 0xca42, + &rtl28xxu_props, "GoTView MasterHD 3", NULL) }, { } }; MODULE_DEVICE_TABLE(usb, rtl28xxu_id_table); diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h index 1b5d7ffb685e..9f6115a2ee01 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h @@ -41,6 +41,8 @@ #include "fc2580.h" #include "tua9001.h" #include "r820t.h" +#include "si2168.h" +#include "si2157.h" /* * USB commands @@ -76,6 +78,7 @@ struct rtl28xxu_dev { u8 page; /* integrated demod active register page */ struct i2c_adapter *demod_i2c_adapter; bool rc_active; + bool new_i2c_write; struct i2c_client *i2c_client_demod; struct i2c_client *i2c_client_tuner; struct i2c_client *i2c_client_slave_demod; @@ -83,6 +86,7 @@ struct rtl28xxu_dev { #define SLAVE_DEMOD_NONE 0 #define SLAVE_DEMOD_MN88472 1 #define SLAVE_DEMOD_MN88473 2 + #define SLAVE_DEMOD_SI2168 3 unsigned int slave_demod:2; union { struct rtl2830_platform_data rtl2830_platform_data; @@ -116,6 +120,7 @@ enum rtl28xxu_tuner { TUNER_RTL2832_FC0013, TUNER_RTL2832_R820T, TUNER_RTL2832_R828D, + TUNER_RTL2832_SI2157, }; struct rtl28xxu_req { -- cgit v1.2.3-59-g8ed1b From 250d2ff01623e80943c4ffed0308b0d19fe6625d Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 16 Apr 2015 09:22:46 -0300 Subject: [media] rtl28xxu: fix return value check in rtl2832u_tuner_attach() In case of error, the function platform_device_register_data() returns ERR_PTR() and never returns NULL. The NULL test in the return value check should be replaced with IS_ERR(). Signed-off-by: Wei Yongjun Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 616be9950904..bcd7e0f4e978 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -1293,7 +1293,7 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) "rtl2832_sdr", PLATFORM_DEVID_AUTO, &pdata, sizeof(pdata)); - if (pdev == NULL || pdev->dev.driver == NULL) + if (IS_ERR(pdev) || pdev->dev.driver == NULL) break; dev->platform_device_sdr = pdev; break; -- cgit v1.2.3-59-g8ed1b From 8e95dba6fbdb978a1f3836331c9cc063cb57efc0 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 30 Mar 2015 07:59:32 -0300 Subject: [media] media/fintek: drop pci_ids dependency This driver does not use any PCI IDs, don't include the pci_ids.h header. Signed-off-by: Michael S. Tsirkin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/fintek-cir.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c index 5c63c2ec6183..bd7b3bdb1a88 100644 --- a/drivers/media/rc/fintek-cir.c +++ b/drivers/media/rc/fintek-cir.c @@ -33,7 +33,6 @@ #include #include #include -#include #include "fintek-cir.h" -- cgit v1.2.3-59-g8ed1b From 4d298b8539ed59f1d69d3aa6e41a2c4908137612 Mon Sep 17 00:00:00 2001 From: David Härdeman Date: Mon, 30 Mar 2015 17:51:01 -0300 Subject: [media] rc-core: fix dib0700 scancode generation for RC5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit af3a4a9bbeb0 ("[media] dib0700: NEC scancode cleanup") cleaned up the NEC scancode logic but overlooked the RC5 case. This patch brings the RC5 case in line with the NEC code and makes the struct self-documenting. Signed-off-by: David Härdeman Reported-by: David Cimbůrek Cc: stable@vger.kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/dib0700_core.c | 70 ++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 30 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c index 2b40393836ff..0d248ce02a9b 100644 --- a/drivers/media/usb/dvb-usb/dib0700_core.c +++ b/drivers/media/usb/dvb-usb/dib0700_core.c @@ -655,10 +655,20 @@ out: struct dib0700_rc_response { u8 report_id; u8 data_state; - u8 system; - u8 not_system; - u8 data; - u8 not_data; + union { + struct { + u8 system; + u8 not_system; + u8 data; + u8 not_data; + } nec; + struct { + u8 not_used; + u8 system; + u8 data; + u8 not_data; + } rc5; + }; }; #define RC_MSG_SIZE_V1_20 6 @@ -694,8 +704,8 @@ static void dib0700_rc_urb_completion(struct urb *purb) deb_data("IR ID = %02X state = %02X System = %02X %02X Cmd = %02X %02X (len %d)\n", poll_reply->report_id, poll_reply->data_state, - poll_reply->system, poll_reply->not_system, - poll_reply->data, poll_reply->not_data, + poll_reply->nec.system, poll_reply->nec.not_system, + poll_reply->nec.data, poll_reply->nec.not_data, purb->actual_length); switch (d->props.rc.core.protocol) { @@ -704,30 +714,30 @@ static void dib0700_rc_urb_completion(struct urb *purb) toggle = 0; /* NEC protocol sends repeat code as 0 0 0 FF */ - if (poll_reply->system == 0x00 && - poll_reply->not_system == 0x00 && - poll_reply->data == 0x00 && - poll_reply->not_data == 0xff) { + if (poll_reply->nec.system == 0x00 && + poll_reply->nec.not_system == 0x00 && + poll_reply->nec.data == 0x00 && + poll_reply->nec.not_data == 0xff) { poll_reply->data_state = 2; break; } - if ((poll_reply->data ^ poll_reply->not_data) != 0xff) { + if ((poll_reply->nec.data ^ poll_reply->nec.not_data) != 0xff) { deb_data("NEC32 protocol\n"); - keycode = RC_SCANCODE_NEC32(poll_reply->system << 24 | - poll_reply->not_system << 16 | - poll_reply->data << 8 | - poll_reply->not_data); - } else if ((poll_reply->system ^ poll_reply->not_system) != 0xff) { + keycode = RC_SCANCODE_NEC32(poll_reply->nec.system << 24 | + poll_reply->nec.not_system << 16 | + poll_reply->nec.data << 8 | + poll_reply->nec.not_data); + } else if ((poll_reply->nec.system ^ poll_reply->nec.not_system) != 0xff) { deb_data("NEC extended protocol\n"); - keycode = RC_SCANCODE_NECX(poll_reply->system << 8 | - poll_reply->not_system, - poll_reply->data); + keycode = RC_SCANCODE_NECX(poll_reply->nec.system << 8 | + poll_reply->nec.not_system, + poll_reply->nec.data); } else { deb_data("NEC normal protocol\n"); - keycode = RC_SCANCODE_NEC(poll_reply->system, - poll_reply->data); + keycode = RC_SCANCODE_NEC(poll_reply->nec.system, + poll_reply->nec.data); } break; @@ -735,19 +745,19 @@ static void dib0700_rc_urb_completion(struct urb *purb) deb_data("RC5 protocol\n"); protocol = RC_TYPE_RC5; toggle = poll_reply->report_id; - keycode = RC_SCANCODE_RC5(poll_reply->system, poll_reply->data); + keycode = RC_SCANCODE_RC5(poll_reply->rc5.system, poll_reply->rc5.data); + + if ((poll_reply->rc5.data ^ poll_reply->rc5.not_data) != 0xff) { + /* Key failed integrity check */ + err("key failed integrity check: %02x %02x %02x %02x", + poll_reply->rc5.not_used, poll_reply->rc5.system, + poll_reply->rc5.data, poll_reply->rc5.not_data); + goto resubmit; + } break; } - if ((poll_reply->data + poll_reply->not_data) != 0xff) { - /* Key failed integrity check */ - err("key failed integrity check: %02x %02x %02x %02x", - poll_reply->system, poll_reply->not_system, - poll_reply->data, poll_reply->not_data); - goto resubmit; - } - rc_keydown(d->rc_dev, protocol, keycode, toggle); resubmit: -- cgit v1.2.3-59-g8ed1b From 9a12ccfc8054e69895c7773176bb2c89e3a195f6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 30 Apr 2015 06:44:56 -0300 Subject: [media] saa7134: prepare to use pr_foo macros Add a pr_fmt macro, and move saa7134.h header to the beginning, to avoid warnings when using the pr_foo macros. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-alsa.c | 6 +++--- drivers/media/pci/saa7134/saa7134-cards.c | 5 +++-- drivers/media/pci/saa7134/saa7134-core.c | 6 +++--- drivers/media/pci/saa7134/saa7134-dvb.c | 5 +++-- drivers/media/pci/saa7134/saa7134-empress.c | 6 +++--- drivers/media/pci/saa7134/saa7134-go7007.c | 5 +++-- drivers/media/pci/saa7134/saa7134-i2c.c | 5 +++-- drivers/media/pci/saa7134/saa7134-input.c | 6 +++--- drivers/media/pci/saa7134/saa7134-ts.c | 6 +++--- drivers/media/pci/saa7134/saa7134-tvaudio.c | 6 +++--- drivers/media/pci/saa7134/saa7134-vbi.c | 6 +++--- drivers/media/pci/saa7134/saa7134-video.c | 6 +++--- drivers/media/pci/saa7134/saa7134.h | 2 ++ 13 files changed, 38 insertions(+), 32 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7134/saa7134-alsa.c b/drivers/media/pci/saa7134/saa7134-alsa.c index ac3cd74e824e..d5b0610a91fb 100644 --- a/drivers/media/pci/saa7134/saa7134-alsa.c +++ b/drivers/media/pci/saa7134/saa7134-alsa.c @@ -16,6 +16,9 @@ * */ +#include "saa7134.h" +#include "saa7134-reg.h" + #include #include #include @@ -29,9 +32,6 @@ #include #include -#include "saa7134.h" -#include "saa7134-reg.h" - static unsigned int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug,"enable debug messages [alsa]"); diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c index d48fd5338db5..20de0b12c818 100644 --- a/drivers/media/pci/saa7134/saa7134-cards.c +++ b/drivers/media/pci/saa7134/saa7134-cards.c @@ -20,13 +20,14 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "saa7134.h" +#include "saa7134-reg.h" + #include #include #include #include -#include "saa7134-reg.h" -#include "saa7134.h" #include "tuner-xc2028.h" #include #include diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c index a349e964e0bc..76e8ba98e4aa 100644 --- a/drivers/media/pci/saa7134/saa7134-core.c +++ b/drivers/media/pci/saa7134/saa7134-core.c @@ -20,6 +20,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "saa7134.h" +#include "saa7134-reg.h" + #include #include #include @@ -33,9 +36,6 @@ #include #include -#include "saa7134-reg.h" -#include "saa7134.h" - MODULE_DESCRIPTION("v4l2 driver module for saa7130/34 based TV cards"); MODULE_AUTHOR("Gerd Knorr [SuSE Labs]"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/pci/saa7134/saa7134-dvb.c b/drivers/media/pci/saa7134/saa7134-dvb.c index bcfebd56fa2b..e1fe006c8ff9 100644 --- a/drivers/media/pci/saa7134/saa7134-dvb.c +++ b/drivers/media/pci/saa7134/saa7134-dvb.c @@ -20,6 +20,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "saa7134.h" +#include "saa7134-reg.h" + #include #include #include @@ -28,8 +31,6 @@ #include #include -#include "saa7134-reg.h" -#include "saa7134.h" #include #include "dvb-pll.h" #include diff --git a/drivers/media/pci/saa7134/saa7134-empress.c b/drivers/media/pci/saa7134/saa7134-empress.c index c9118e0cbe00..707fc872eb7f 100644 --- a/drivers/media/pci/saa7134/saa7134-empress.c +++ b/drivers/media/pci/saa7134/saa7134-empress.c @@ -17,6 +17,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "saa7134.h" +#include "saa7134-reg.h" + #include #include #include @@ -26,9 +29,6 @@ #include #include -#include "saa7134-reg.h" -#include "saa7134.h" - /* ------------------------------------------------------------------ */ MODULE_AUTHOR("Gerd Knorr [SuSE Labs]"); diff --git a/drivers/media/pci/saa7134/saa7134-go7007.c b/drivers/media/pci/saa7134/saa7134-go7007.c index 54e650b4dff1..da7c4be4bed2 100644 --- a/drivers/media/pci/saa7134/saa7134-go7007.c +++ b/drivers/media/pci/saa7134/saa7134-go7007.c @@ -11,6 +11,9 @@ * GNU General Public License for more details. */ +#include "saa7134.h" +#include "saa7134-reg.h" + #include #include #include @@ -27,8 +30,6 @@ #include #include -#include "saa7134.h" -#include "saa7134-reg.h" #include "go7007-priv.h" /*#define GO7007_HPI_DEBUG*/ diff --git a/drivers/media/pci/saa7134/saa7134-i2c.c b/drivers/media/pci/saa7134/saa7134-i2c.c index f4da674e7f26..b69c47546d29 100644 --- a/drivers/media/pci/saa7134/saa7134-i2c.c +++ b/drivers/media/pci/saa7134/saa7134-i2c.c @@ -20,14 +20,15 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "saa7134.h" +#include "saa7134-reg.h" + #include #include #include #include #include -#include "saa7134-reg.h" -#include "saa7134.h" #include /* ----------------------------------------------------------- */ diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c index dc3d6516edf7..9406d5d7cdde 100644 --- a/drivers/media/pci/saa7134/saa7134-input.c +++ b/drivers/media/pci/saa7134/saa7134-input.c @@ -18,15 +18,15 @@ * */ +#include "saa7134.h" +#include "saa7134-reg.h" + #include #include #include #include #include -#include "saa7134-reg.h" -#include "saa7134.h" - #define MODULE_NAME "saa7134" static unsigned int disable_ir; diff --git a/drivers/media/pci/saa7134/saa7134-ts.c b/drivers/media/pci/saa7134/saa7134-ts.c index 2709b83d57b1..8a2938c34d32 100644 --- a/drivers/media/pci/saa7134/saa7134-ts.c +++ b/drivers/media/pci/saa7134/saa7134-ts.c @@ -20,15 +20,15 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "saa7134.h" +#include "saa7134-reg.h" + #include #include #include #include #include -#include "saa7134-reg.h" -#include "saa7134.h" - /* ------------------------------------------------------------------ */ static unsigned int ts_debug; diff --git a/drivers/media/pci/saa7134/saa7134-tvaudio.c b/drivers/media/pci/saa7134/saa7134-tvaudio.c index 3afbcb70b518..d020dff04bfe 100644 --- a/drivers/media/pci/saa7134/saa7134-tvaudio.c +++ b/drivers/media/pci/saa7134/saa7134-tvaudio.c @@ -20,6 +20,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "saa7134.h" +#include "saa7134-reg.h" + #include #include #include @@ -29,9 +32,6 @@ #include #include -#include "saa7134-reg.h" -#include "saa7134.h" - /* ------------------------------------------------------------------ */ static unsigned int audio_debug; diff --git a/drivers/media/pci/saa7134/saa7134-vbi.c b/drivers/media/pci/saa7134/saa7134-vbi.c index 5306e549e526..109c2ffeab93 100644 --- a/drivers/media/pci/saa7134/saa7134-vbi.c +++ b/drivers/media/pci/saa7134/saa7134-vbi.c @@ -20,14 +20,14 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "saa7134.h" +#include "saa7134-reg.h" + #include #include #include #include -#include "saa7134-reg.h" -#include "saa7134.h" - /* ------------------------------------------------------------------ */ static unsigned int vbi_debug; diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c index 99d09a7566d3..5cef84a84863 100644 --- a/drivers/media/pci/saa7134/saa7134-video.c +++ b/drivers/media/pci/saa7134/saa7134-video.c @@ -20,6 +20,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "saa7134.h" +#include "saa7134-reg.h" + #include #include #include @@ -31,9 +34,6 @@ #include #include -#include "saa7134-reg.h" -#include "saa7134.h" - /* ------------------------------------------------------------------ */ unsigned int video_debug; diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h index 8bf0553b8d2f..6fec01711680 100644 --- a/drivers/media/pci/saa7134/saa7134.h +++ b/drivers/media/pci/saa7134/saa7134.h @@ -21,6 +21,8 @@ #define SAA7134_VERSION "0, 2, 17" +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include -- cgit v1.2.3-59-g8ed1b From 83582009164b9e293e4b8c34b198c4ac0d2a82dd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 30 Apr 2015 06:46:34 -0300 Subject: [media] saa7134: instead of using printk KERN_foo, use pr_foo Replaces all occurrences of printk with KERN_INFO, KERN_WARNING and KERN_ERR to pr_info/pr_warning, pr_err, using this small shell script: for i in drivers/media/pci/saa7134/*.[ch]; do sed s,'printk(KERN_INFO ','pr_info(',g <$i >a && mv a $i; done for i in drivers/media/pci/saa7134/*.[ch]; do sed s,'printk(KERN_ERR ','pr_err(',g <$i >a && mv a $i; done for i in drivers/media/pci/saa7134/*.[ch]; do sed s,'printk(KERN_WARNING ','pr_warn(',g <$i >a && mv a $i; done Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-alsa.c | 14 ++++---- drivers/media/pci/saa7134/saa7134-cards.c | 32 +++++++++--------- drivers/media/pci/saa7134/saa7134-core.c | 52 ++++++++++++++--------------- drivers/media/pci/saa7134/saa7134-dvb.c | 10 +++--- drivers/media/pci/saa7134/saa7134-empress.c | 4 +-- drivers/media/pci/saa7134/saa7134-i2c.c | 6 ++-- drivers/media/pci/saa7134/saa7134-tvaudio.c | 4 +-- drivers/media/pci/saa7134/saa7134-video.c | 8 ++--- 8 files changed, 65 insertions(+), 65 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7134/saa7134-alsa.c b/drivers/media/pci/saa7134/saa7134-alsa.c index d5b0610a91fb..f8764a4c2f15 100644 --- a/drivers/media/pci/saa7134/saa7134-alsa.c +++ b/drivers/media/pci/saa7134/saa7134-alsa.c @@ -821,7 +821,7 @@ static int snd_card_saa7134_capture_open(struct snd_pcm_substream * substream) int amux, err; if (!saa7134) { - printk(KERN_ERR "BUG: saa7134 can't find device struct." + pr_err("BUG: saa7134 can't find device struct." " Can't proceed with open\n"); return -ENODEV; } @@ -1175,7 +1175,7 @@ static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum) (void*) &dev->dmasound); if (err < 0) { - printk(KERN_ERR "%s: can't get IRQ %d for ALSA\n", + pr_err("%s: can't get IRQ %d for ALSA\n", dev->name, dev->pci->irq); goto __nodev; } @@ -1196,7 +1196,7 @@ static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum) sprintf(card->longname, "%s at 0x%lx irq %d", chip->dev->name, chip->iobase, chip->irq); - printk(KERN_INFO "%s/alsa: %s registered as card %d\n",dev->name,card->longname,index[devnum]); + pr_info("%s/alsa: %s registered as card %d\n",dev->name,card->longname,index[devnum]); if ((err = snd_card_register(card)) == 0) { snd_saa7134_cards[devnum] = card; @@ -1240,19 +1240,19 @@ static int saa7134_alsa_init(void) saa7134_dmasound_init = alsa_device_init; saa7134_dmasound_exit = alsa_device_exit; - printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n"); + pr_info("saa7134 ALSA driver for DMA sound loaded\n"); list_for_each(list,&saa7134_devlist) { dev = list_entry(list, struct saa7134_dev, devlist); if (dev->pci->device == PCI_DEVICE_ID_PHILIPS_SAA7130) - printk(KERN_INFO "%s/alsa: %s doesn't support digital audio\n", + pr_info("%s/alsa: %s doesn't support digital audio\n", dev->name, saa7134_boards[dev->board].name); else alsa_device_init(dev); } if (dev == NULL) - printk(KERN_INFO "saa7134 ALSA: no saa7134 cards found\n"); + pr_info("saa7134 ALSA: no saa7134 cards found\n"); return 0; @@ -1272,7 +1272,7 @@ static void saa7134_alsa_exit(void) saa7134_dmasound_init = NULL; saa7134_dmasound_exit = NULL; - printk(KERN_INFO "saa7134 ALSA driver for DMA sound unloaded\n"); + pr_info("saa7134 ALSA driver for DMA sound unloaded\n"); return; } diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c index 20de0b12c818..3159e15a57d4 100644 --- a/drivers/media/pci/saa7134/saa7134-cards.c +++ b/drivers/media/pci/saa7134/saa7134-cards.c @@ -7381,7 +7381,7 @@ int saa7134_tuner_callback(void *priv, int component, int command, int arg) return saa7134_xc5000_callback(dev, command, arg); } } else { - printk(KERN_ERR "saa7134: Error - device struct undefined.\n"); + pr_err("saa7134: Error - device struct undefined.\n"); return -EINVAL; } return -EINVAL; @@ -7412,12 +7412,12 @@ static void hauppauge_eeprom(struct saa7134_dev *dev, u8 *eeprom_data) case 67659: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */ break; default: - printk(KERN_WARNING "%s: warning: " + pr_warn("%s: warning: " "unknown hauppauge model #%d\n", dev->name, tv.model); break; } - printk(KERN_INFO "%s: hauppauge eeprom: model=%d\n", + pr_info("%s: hauppauge eeprom: model=%d\n", dev->name, tv.model); } @@ -7428,7 +7428,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) /* Always print gpio, often manufacturers encode tuner type and other info. */ saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0); dev->gpio_value = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2); - printk(KERN_INFO "%s: board init: gpio is %x\n", dev->name, dev->gpio_value); + pr_info("%s: board init: gpio is %x\n", dev->name, dev->gpio_value); switch (dev->board) { case SAA7134_BOARD_FLYVIDEO2000: @@ -7811,7 +7811,7 @@ int saa7134_board_init2(struct saa7134_dev *dev) */ ret = i2c_transfer(&dev->i2c_adap, msg, 2); if (ret != 2) { - printk(KERN_ERR "EEPROM read failure\n"); + pr_err("EEPROM read failure\n"); } else if ((data[0] != 0) && (data[0] != 0xff)) { /* old config structure */ subaddr = data[0] + 2; @@ -7826,7 +7826,7 @@ int saa7134_board_init2(struct saa7134_dev *dev) dev->tuner_type = TUNER_PHILIPS_FM1216ME_MK3; break; default: - printk(KERN_ERR "%s Can't determine tuner type %x from EEPROM\n", dev->name, tuner_t); + pr_err("%s Can't determine tuner type %x from EEPROM\n", dev->name, tuner_t); } } else if ((data[1] != 0) && (data[1] != 0xff)) { /* new config structure */ @@ -7843,17 +7843,17 @@ int saa7134_board_init2(struct saa7134_dev *dev) break; case 0x001d: dev->tuner_type = TUNER_PHILIPS_FMD1216ME_MK3; - printk(KERN_INFO "%s Board has DVB-T\n", + pr_info("%s Board has DVB-T\n", dev->name); break; default: - printk(KERN_ERR "%s Can't determine tuner type %x from EEPROM\n", dev->name, tuner_t); + pr_err("%s Can't determine tuner type %x from EEPROM\n", dev->name, tuner_t); } } else { - printk(KERN_ERR "%s unexpected config structure\n", dev->name); + pr_err("%s unexpected config structure\n", dev->name); } - printk(KERN_INFO "%s Tuner type is %d\n", dev->name, dev->tuner_type); + pr_info("%s Tuner type is %d\n", dev->name, dev->tuner_type); break; } case SAA7134_BOARD_PHILIPS_EUROPA: @@ -7861,7 +7861,7 @@ int saa7134_board_init2(struct saa7134_dev *dev) /* Reconfigure board as Snake reference design */ dev->board = SAA7134_BOARD_PHILIPS_SNAKE; dev->tuner_type = saa7134_boards[dev->board].tuner_type; - printk(KERN_INFO "%s: Reconfigured board as %s\n", + pr_info("%s: Reconfigured board as %s\n", dev->name, saa7134_boards[dev->board].name); break; } @@ -7889,7 +7889,7 @@ int saa7134_board_init2(struct saa7134_dev *dev) struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; if (dev->autodetected && (dev->eedata[0x49] == 0x50)) { dev->board = SAA7134_BOARD_PHILIPS_TIGER_S; - printk(KERN_INFO "%s: Reconfigured board as %s\n", + pr_info("%s: Reconfigured board as %s\n", dev->name, saa7134_boards[dev->board].name); } if (dev->board == SAA7134_BOARD_PHILIPS_TIGER_S) { @@ -7976,12 +7976,12 @@ int saa7134_board_init2(struct saa7134_dev *dev) msg.addr = 0x0b; msg.len = 1; if (1 != i2c_transfer(&dev->i2c_adap, &msg, 1)) { - printk(KERN_WARNING "%s: send wake up byte to pic16C505" + pr_warn("%s: send wake up byte to pic16C505" "(IR chip) failed\n", dev->name); } else { msg.flags = I2C_M_RD; rc = i2c_transfer(&dev->i2c_adap, &msg, 1); - printk(KERN_INFO "%s: probe IR chip @ i2c 0x%02x: %s\n", + pr_info("%s: probe IR chip @ i2c 0x%02x: %s\n", dev->name, msg.addr, (1 == rc) ? "yes" : "no"); if (rc == 1) @@ -8022,10 +8022,10 @@ int saa7134_board_init2(struct saa7134_dev *dev) dev->board = SAA7134_BOARD_VIDEOMATE_DVBT_200A; dev->tuner_type = saa7134_boards[dev->board].tuner_type; dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf; - printk(KERN_INFO "%s: Reconfigured board as %s\n", + pr_info("%s: Reconfigured board as %s\n", dev->name, saa7134_boards[dev->board].name); } else { - printk(KERN_WARNING "%s: Unexpected tuner type info: %x in eeprom\n", + pr_warn("%s: Unexpected tuner type info: %x in eeprom\n", dev->name, dev->eedata[0x41]); break; } diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c index 76e8ba98e4aa..9ffdcdcfd2b0 100644 --- a/drivers/media/pci/saa7134/saa7134-core.c +++ b/drivers/media/pci/saa7134/saa7134-core.c @@ -614,24 +614,24 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id) print_irqstatus(dev,loop,report,status); if (report & SAA7134_IRQ_REPORT_PE) { /* disable all parity error */ - printk(KERN_WARNING "%s/irq: looping -- " + pr_warn("%s/irq: looping -- " "clearing PE (parity error!) enable bit\n",dev->name); saa_clearl(SAA7134_IRQ2,SAA7134_IRQ2_INTE_PE); } else if (report & SAA7134_IRQ_REPORT_GPIO16) { /* disable gpio16 IRQ */ - printk(KERN_WARNING "%s/irq: looping -- " + pr_warn("%s/irq: looping -- " "clearing GPIO16 enable bit\n",dev->name); saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO16_P); saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO16_N); } else if (report & SAA7134_IRQ_REPORT_GPIO18) { /* disable gpio18 IRQs */ - printk(KERN_WARNING "%s/irq: looping -- " + pr_warn("%s/irq: looping -- " "clearing GPIO18 enable bit\n",dev->name); saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18_P); saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18_N); } else { /* disable all irqs */ - printk(KERN_WARNING "%s/irq: looping -- " + pr_warn("%s/irq: looping -- " "clearing all enable bits\n",dev->name); saa_writel(SAA7134_IRQ1,0); saa_writel(SAA7134_IRQ2,0); @@ -790,7 +790,7 @@ static void must_configure_manually(int has_eeprom) "saa7134: The supported cards are:\n"); for (i = 0; i < saa7134_bcount; i++) { - printk(KERN_WARNING "saa7134: card=%d -> %-40.40s", + pr_warn("saa7134: card=%d -> %-40.40s", i,saa7134_boards[i].name); for (p = 0; saa7134_pci_tbl[p].driver_data; p++) { if (saa7134_pci_tbl[p].driver_data != i) @@ -903,31 +903,31 @@ static int saa7134_initdev(struct pci_dev *pci_dev, /* pci quirks */ if (pci_pci_problems) { if (pci_pci_problems & PCIPCI_TRITON) - printk(KERN_INFO "%s: quirk: PCIPCI_TRITON\n", dev->name); + pr_info("%s: quirk: PCIPCI_TRITON\n", dev->name); if (pci_pci_problems & PCIPCI_NATOMA) - printk(KERN_INFO "%s: quirk: PCIPCI_NATOMA\n", dev->name); + pr_info("%s: quirk: PCIPCI_NATOMA\n", dev->name); if (pci_pci_problems & PCIPCI_VIAETBF) - printk(KERN_INFO "%s: quirk: PCIPCI_VIAETBF\n", dev->name); + pr_info("%s: quirk: PCIPCI_VIAETBF\n", dev->name); if (pci_pci_problems & PCIPCI_VSFX) - printk(KERN_INFO "%s: quirk: PCIPCI_VSFX\n",dev->name); + pr_info("%s: quirk: PCIPCI_VSFX\n",dev->name); #ifdef PCIPCI_ALIMAGIK if (pci_pci_problems & PCIPCI_ALIMAGIK) { - printk(KERN_INFO "%s: quirk: PCIPCI_ALIMAGIK -- latency fixup\n", + pr_info("%s: quirk: PCIPCI_ALIMAGIK -- latency fixup\n", dev->name); latency = 0x0A; } #endif if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL)) { - printk(KERN_INFO "%s: quirk: this driver and your " + pr_info("%s: quirk: this driver and your " "chipset may not work together" " in overlay mode.\n",dev->name); if (!saa7134_no_overlay) { - printk(KERN_INFO "%s: quirk: overlay " + pr_info("%s: quirk: overlay " "mode will be disabled.\n", dev->name); saa7134_no_overlay = 1; } else { - printk(KERN_INFO "%s: quirk: overlay " + pr_info("%s: quirk: overlay " "mode will be forced. Use this" " option at your own risk.\n", dev->name); @@ -935,7 +935,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, } } if (UNSET != latency) { - printk(KERN_INFO "%s: setting pci latency timer to %d\n", + pr_info("%s: setting pci latency timer to %d\n", dev->name,latency); pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, latency); } @@ -943,7 +943,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, /* print pci info */ dev->pci_rev = pci_dev->revision; pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); - printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, " + pr_info("%s: found at %s, rev: %d, irq: %d, " "latency: %d, mmio: 0x%llx\n", dev->name, pci_name(pci_dev), dev->pci_rev, pci_dev->irq, dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0)); @@ -972,7 +972,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf; if (UNSET != tuner[dev->nr]) dev->tuner_type = tuner[dev->nr]; - printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", + pr_info("%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", dev->name,pci_dev->subsystem_vendor, pci_dev->subsystem_device,saa7134_boards[dev->board].name, dev->board, dev->autodetected ? @@ -983,7 +983,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, pci_resource_len(pci_dev,0), dev->name)) { err = -EBUSY; - printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n", + pr_err("%s: can't get MMIO memory @ 0x%llx\n", dev->name,(unsigned long long)pci_resource_start(pci_dev,0)); goto fail1; } @@ -992,7 +992,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, dev->bmmio = (__u8 __iomem *)dev->lmmio; if (NULL == dev->lmmio) { err = -EIO; - printk(KERN_ERR "%s: can't ioremap() MMIO memory\n", + pr_err("%s: can't ioremap() MMIO memory\n", dev->name); goto fail2; } @@ -1010,7 +1010,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, err = request_irq(pci_dev->irq, saa7134_irq, IRQF_SHARED, dev->name, dev); if (err < 0) { - printk(KERN_ERR "%s: can't get IRQ %d\n", + pr_err("%s: can't get IRQ %d\n", dev->name,pci_dev->irq); goto fail4; } @@ -1040,7 +1040,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, &dev->i2c_adap, "saa6588", 0, I2C_ADDRS(saa7134_boards[dev->board].rds_addr)); if (sd) { - printk(KERN_INFO "%s: found RDS decoder\n", dev->name); + pr_info("%s: found RDS decoder\n", dev->name); dev->has_rds = 1; } } @@ -1059,7 +1059,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, /* register v4l devices */ if (saa7134_no_overlay > 0) - printk(KERN_INFO "%s: Overlay support disabled.\n", dev->name); + pr_info("%s: Overlay support disabled.\n", dev->name); dev->video_dev = vdev_init(dev,&saa7134_video_template,"video"); dev->video_dev->ctrl_handler = &dev->ctrl_handler; @@ -1068,11 +1068,11 @@ static int saa7134_initdev(struct pci_dev *pci_dev, err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER, video_nr[dev->nr]); if (err < 0) { - printk(KERN_INFO "%s: can't register video device\n", + pr_info("%s: can't register video device\n", dev->name); goto fail5; } - printk(KERN_INFO "%s: registered device %s [v4l2]\n", + pr_info("%s: registered device %s [v4l2]\n", dev->name, video_device_node_name(dev->video_dev)); dev->vbi_dev = vdev_init(dev, &saa7134_video_template, "vbi"); @@ -1084,7 +1084,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, vbi_nr[dev->nr]); if (err < 0) goto fail5; - printk(KERN_INFO "%s: registered device %s\n", + pr_info("%s: registered device %s\n", dev->name, video_device_node_name(dev->vbi_dev)); if (card_has_radio(dev)) { @@ -1095,7 +1095,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, radio_nr[dev->nr]); if (err < 0) goto fail5; - printk(KERN_INFO "%s: registered device %s\n", + pr_info("%s: registered device %s\n", dev->name, video_device_node_name(dev->radio_dev)); } @@ -1358,7 +1358,7 @@ static struct pci_driver saa7134_pci_driver = { static int __init saa7134_init(void) { INIT_LIST_HEAD(&saa7134_devlist); - printk(KERN_INFO "saa7130/34: v4l2 driver version %s loaded\n", + pr_info("saa7130/34: v4l2 driver version %s loaded\n", SAA7134_VERSION); return pci_register_driver(&saa7134_pci_driver); } diff --git a/drivers/media/pci/saa7134/saa7134-dvb.c b/drivers/media/pci/saa7134/saa7134-dvb.c index e1fe006c8ff9..c7d9896a454e 100644 --- a/drivers/media/pci/saa7134/saa7134-dvb.c +++ b/drivers/media/pci/saa7134/saa7134-dvb.c @@ -87,7 +87,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); /* Print a warning */ #define wprintk(fmt, arg...) \ - printk(KERN_WARNING "%s/dvb: " fmt, dev->name, ## arg) + pr_warn("%s/dvb: " fmt, dev->name, ## arg) /* ------------------------------------------------------------------ * mt352 based DVB-T cards @@ -1223,10 +1223,10 @@ static int dvb_init(struct saa7134_dev *dev) mutex_init(&dev->frontends.lock); INIT_LIST_HEAD(&dev->frontends.felist); - printk(KERN_INFO "%s() allocating 1 frontend\n", __func__); + pr_info("%s() allocating 1 frontend\n", __func__); fe0 = vb2_dvb_alloc_frontend(&dev->frontends, 1); if (!fe0) { - printk(KERN_ERR "%s() failed to alloc\n", __func__); + pr_err("%s() failed to alloc\n", __func__); return -ENOMEM; } @@ -1872,14 +1872,14 @@ static int dvb_init(struct saa7134_dev *dev) fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (!fe) { - printk(KERN_ERR "%s/2: xc3028 attach failed\n", + pr_err("%s/2: xc3028 attach failed\n", dev->name); goto detach_frontend; } } if (NULL == fe0->dvb.frontend) { - printk(KERN_ERR "%s/dvb: frontend initialization failed\n", dev->name); + pr_err("%s/dvb: frontend initialization failed\n", dev->name); goto detach_frontend; } /* define general-purpose callback pointer */ diff --git a/drivers/media/pci/saa7134/saa7134-empress.c b/drivers/media/pci/saa7134/saa7134-empress.c index 707fc872eb7f..baccd5d72ab9 100644 --- a/drivers/media/pci/saa7134/saa7134-empress.c +++ b/drivers/media/pci/saa7134/saa7134-empress.c @@ -310,13 +310,13 @@ static int empress_init(struct saa7134_dev *dev) err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER, empress_nr[dev->nr]); if (err < 0) { - printk(KERN_INFO "%s: can't register video device\n", + pr_info("%s: can't register video device\n", dev->name); video_device_release(dev->empress_dev); dev->empress_dev = NULL; return err; } - printk(KERN_INFO "%s: registered device %s [mpeg]\n", + pr_info("%s: registered device %s [mpeg]\n", dev->name, video_device_node_name(dev->empress_dev)); empress_signal_update(&dev->empress_workqueue); diff --git a/drivers/media/pci/saa7134/saa7134-i2c.c b/drivers/media/pci/saa7134/saa7134-i2c.c index b69c47546d29..2dcc497fb166 100644 --- a/drivers/media/pci/saa7134/saa7134-i2c.c +++ b/drivers/media/pci/saa7134/saa7134-i2c.c @@ -360,18 +360,18 @@ saa7134_i2c_eeprom(struct saa7134_dev *dev, unsigned char *eedata, int len) dev->i2c_client.addr = 0xa0 >> 1; buf = 0; if (1 != (err = i2c_master_send(&dev->i2c_client,&buf,1))) { - printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n", + pr_info("%s: Huh, no eeprom present (err=%d)?\n", dev->name,err); return -1; } if (len != (err = i2c_master_recv(&dev->i2c_client,eedata,len))) { - printk(KERN_WARNING "%s: i2c eeprom read error (err=%d)\n", + pr_warn("%s: i2c eeprom read error (err=%d)\n", dev->name,err); return -1; } for (i = 0; i < len; i++) { if (0 == (i % 16)) - printk(KERN_INFO "%s: i2c eeprom %02x:",dev->name,i); + pr_info("%s: i2c eeprom %02x:",dev->name,i); printk(" %02x",eedata[i]); if (15 == (i % 16)) printk("\n"); diff --git a/drivers/media/pci/saa7134/saa7134-tvaudio.c b/drivers/media/pci/saa7134/saa7134-tvaudio.c index d020dff04bfe..e8aeea4cf422 100644 --- a/drivers/media/pci/saa7134/saa7134-tvaudio.c +++ b/drivers/media/pci/saa7134/saa7134-tvaudio.c @@ -673,7 +673,7 @@ static inline int saa_dsp_wait_bit(struct saa7134_dev *dev, int bit) state = saa_readb(SAA7135_DSP_RWSTATE); if (unlikely(state & SAA7135_DSP_RWSTATE_ERR)) { - printk(KERN_WARNING "%s: dsp access error\n", dev->name); + pr_warn("%s: dsp access error\n", dev->name); saa_dsp_reset_error_bit(dev); return -EIO; } @@ -1031,7 +1031,7 @@ int saa7134_tvaudio_init2(struct saa7134_dev *dev) /* start tvaudio thread */ dev->thread.thread = kthread_run(my_thread, dev, "%s", dev->name); if (IS_ERR(dev->thread.thread)) { - printk(KERN_WARNING "%s: kernel_thread() failed\n", + pr_warn("%s: kernel_thread() failed\n", dev->name); /* XXX: missing error handling here */ } diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c index 5cef84a84863..f7dcdccfc307 100644 --- a/drivers/media/pci/saa7134/saa7134-video.c +++ b/drivers/media/pci/saa7134/saa7134-video.c @@ -1229,7 +1229,7 @@ static int saa7134_g_fmt_vid_overlay(struct file *file, void *priv, int i; if (saa7134_no_overlay > 0) { - printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); + pr_err("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); return -EINVAL; } f->fmt.win = dev->win; @@ -1305,7 +1305,7 @@ static int saa7134_try_fmt_vid_overlay(struct file *file, void *priv, struct saa7134_dev *dev = video_drvdata(file); if (saa7134_no_overlay > 0) { - printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); + pr_err("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); return -EINVAL; } @@ -1339,7 +1339,7 @@ static int saa7134_s_fmt_vid_overlay(struct file *file, void *priv, unsigned long flags; if (saa7134_no_overlay > 0) { - printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); + pr_err("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); return -EINVAL; } if (f->fmt.win.clips == NULL) @@ -1738,7 +1738,7 @@ static int saa7134_enum_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_fmtdesc *f) { if (saa7134_no_overlay > 0) { - printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); + pr_err("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); return -EINVAL; } -- cgit v1.2.3-59-g8ed1b From bea8630e5db47f458788848092678da3e8021f44 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 30 Apr 2015 06:55:53 -0300 Subject: [media] saa7134: fix a few other occurrences of KERN_INFO/KERN_WARNING On a few places, the search expression used on the script that replaced pr_info/pr_warn didn't match, because the string were on the next line. It is best to manually edit those lines, and re-indent the paragraphs. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-cards.c | 15 ++++++--------- drivers/media/pci/saa7134/saa7134-core.c | 28 +++++++++++++--------------- 2 files changed, 19 insertions(+), 24 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c index 3159e15a57d4..5b81157a5003 100644 --- a/drivers/media/pci/saa7134/saa7134-cards.c +++ b/drivers/media/pci/saa7134/saa7134-cards.c @@ -7906,9 +7906,8 @@ int saa7134_board_init2(struct saa7134_dev *dev) /* The card below is detected as card=53, but is different */ if (dev->autodetected && (dev->eedata[0x27] == 0x03)) { dev->board = SAA7134_BOARD_ASUSTeK_P7131_ANALOG; - printk(KERN_INFO - "%s: P7131 analog only, using entry of %s\n", - dev->name, saa7134_boards[dev->board].name); + pr_info("%s: P7131 analog only, using entry of %s\n", + dev->name, saa7134_boards[dev->board].name); /* * IR init has already happened for other cards, so @@ -8047,9 +8046,8 @@ int saa7134_board_init2(struct saa7134_dev *dev) msg.buf = &buffer[i][0]; msg.len = ARRAY_SIZE(buffer[0]); if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) - printk(KERN_WARNING - "%s: Unable to enable tuner(%i).\n", - dev->name, i); + pr_warn("%s: Unable to enable tuner(%i).\n", + dev->name, i); } break; } @@ -8065,9 +8063,8 @@ int saa7134_board_init2(struct saa7134_dev *dev) /* watch TV without software reboot. For solve this problem */ /* switch the tuner to analog TV mode manually. */ if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) - printk(KERN_WARNING - "%s: Unable to enable IF of the tuner.\n", - dev->name); + pr_warn("%s: Unable to enable IF of the tuner.\n", + dev->name); break; } case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG: diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c index 9ffdcdcfd2b0..c206148f816b 100644 --- a/drivers/media/pci/saa7134/saa7134-core.c +++ b/drivers/media/pci/saa7134/saa7134-core.c @@ -772,22 +772,20 @@ static void must_configure_manually(int has_eeprom) unsigned int i,p; if (!has_eeprom) - printk(KERN_WARNING - "saa7134: \n" - "saa7134: Congratulations! Your TV card vendor saved a few\n" - "saa7134: cents for a eeprom, thus your pci board has no\n" - "saa7134: subsystem ID and I can't identify it automatically\n" - "saa7134: \n" - "saa7134: I feel better now. Ok, here are the good news:\n" - "saa7134: You can use the card= insmod option to specify\n" - "saa7134: which board do you have. The list:\n"); + pr_warn("saa7134: \n" + "saa7134: Congratulations! Your TV card vendor saved a few\n" + "saa7134: cents for a eeprom, thus your pci board has no\n" + "saa7134: subsystem ID and I can't identify it automatically\n" + "saa7134: \n" + "saa7134: I feel better now. Ok, here are the good news:\n" + "saa7134: You can use the card= insmod option to specify\n" + "saa7134: which board do you have. The list:\n"); else - printk(KERN_WARNING - "saa7134: Board is currently unknown. You might try to use the card=\n" - "saa7134: insmod option to specify which board do you have, but this is\n" - "saa7134: somewhat risky, as might damage your card. It is better to ask\n" - "saa7134: for support at linux-media@vger.kernel.org.\n" - "saa7134: The supported cards are:\n"); + pr_warn("saa7134: Board is currently unknown. You might try to use the card=\n" + "saa7134: insmod option to specify which board do you have, but this is\n" + "saa7134: somewhat risky, as might damage your card. It is better to ask\n" + "saa7134: for support at linux-media@vger.kernel.org.\n" + "saa7134: The supported cards are:\n"); for (i = 0; i < saa7134_bcount; i++) { pr_warn("saa7134: card=%d -> %-40.40s", -- cgit v1.2.3-59-g8ed1b From 7592eefc1ce14d7d699f18d57da4868761bdd92c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 30 Apr 2015 06:59:53 -0300 Subject: [media] saa7134-alsa: use pr_debug() instead of printk On saa7134-alsa, there is just one printk macro that use a different debug level. It should be easy to enable/disable this one using dynamic_printk, if one need to individually control it. So, this module can easily use pr_debug() instead of using its own macros. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-alsa.c | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7134/saa7134-alsa.c b/drivers/media/pci/saa7134/saa7134-alsa.c index f8764a4c2f15..4199fbf9bc44 100644 --- a/drivers/media/pci/saa7134/saa7134-alsa.c +++ b/drivers/media/pci/saa7134/saa7134-alsa.c @@ -32,10 +32,6 @@ #include #include -static unsigned int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug,"enable debug messages [alsa]"); - /* * Configuration macros */ @@ -57,11 +53,6 @@ module_param_array(enable, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s)."); MODULE_PARM_DESC(enable, "Enable (or not) the SAA7134 capture interface(s)."); -#define dprintk(fmt, arg...) if (debug) \ - printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ##arg) - - - /* * Main chip structure */ @@ -149,11 +140,11 @@ static void saa7134_irq_alsa_done(struct saa7134_dev *dev, spin_lock(&dev->slock); if (UNSET == dev->dmasound.dma_blk) { - dprintk("irq: recording stopped\n"); + pr_debug("irq: recording stopped\n"); goto done; } if (0 != (status & 0x0f000000)) - dprintk("irq: lost %ld\n", (status >> 24) & 0x0f); + pr_debug("irq: lost %ld\n", (status >> 24) & 0x0f); if (0 == (status & 0x10000000)) { /* odd */ if (0 == (dev->dmasound.dma_blk & 0x01)) @@ -164,13 +155,13 @@ static void saa7134_irq_alsa_done(struct saa7134_dev *dev, reg = SAA7134_RS_BA2(6); } if (0 == reg) { - dprintk("irq: field oops [%s]\n", + pr_debug("irq: field oops [%s]\n", (status & 0x10000000) ? "even" : "odd"); goto done; } if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) { - dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count, + pr_debug("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count, dev->dmasound.bufsize, dev->dmasound.blocks); spin_unlock(&dev->slock); snd_pcm_stop_xrun(dev->dmasound.substream); @@ -180,10 +171,9 @@ static void saa7134_irq_alsa_done(struct saa7134_dev *dev, /* next block addr */ next_blk = (dev->dmasound.dma_blk + 2) % dev->dmasound.blocks; saa_writel(reg,next_blk * dev->dmasound.blksize); - if (debug > 2) - dprintk("irq: ok, %s, next_blk=%d, addr=%x, blocks=%u, size=%u, read=%u\n", - (status & 0x10000000) ? "even" : "odd ", next_blk, - next_blk * dev->dmasound.blksize, dev->dmasound.blocks, dev->dmasound.blksize, dev->dmasound.read_count); + pr_debug("irq: ok, %s, next_blk=%d, addr=%x, blocks=%u, size=%u, read=%u\n", + (status & 0x10000000) ? "even" : "odd ", next_blk, + next_blk * dev->dmasound.blksize, dev->dmasound.blocks, dev->dmasound.blksize, dev->dmasound.read_count); /* update status & wake waiting readers */ dev->dmasound.dma_blk = (dev->dmasound.dma_blk + 1) % dev->dmasound.blocks; @@ -233,7 +223,7 @@ static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id) } if (loop == 10) { - dprintk("error! looping IRQ!"); + pr_debug("error! looping IRQ!"); } out: @@ -281,11 +271,11 @@ static int saa7134_alsa_dma_init(struct saa7134_dev *dev, int nr_pages) dma->vaddr = vmalloc_32(nr_pages << PAGE_SHIFT); if (NULL == dma->vaddr) { - dprintk("vmalloc_32(%d pages) failed\n", nr_pages); + pr_debug("vmalloc_32(%d pages) failed\n", nr_pages); return -ENOMEM; } - dprintk("vmalloc is at addr 0x%08lx, size=%d\n", + pr_debug("vmalloc is at addr 0x%08lx, size=%d\n", (unsigned long)dma->vaddr, nr_pages << PAGE_SHIFT); @@ -572,7 +562,7 @@ static int snd_card_saa7134_capture_prepare(struct snd_pcm_substream * substream break; } - dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n", + pr_debug("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n", runtime->format, runtime->channels, fmt, bswap ? 'b' : '-'); /* dma: setup channel 6 (= AUDIO) */ -- cgit v1.2.3-59-g8ed1b From ae618919f10588046c0c91117348f2ed49414a1e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 30 Apr 2015 07:06:23 -0300 Subject: [media] saa7134-dvb: get rid of wprintk() macro wprintk() macro is now just a wrapper for pr_warn(). Get rid of it! Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-dvb.c | 59 +++++++++++++++------------------ 1 file changed, 27 insertions(+), 32 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7134/saa7134-dvb.c b/drivers/media/pci/saa7134/saa7134-dvb.c index c7d9896a454e..7e0091343c87 100644 --- a/drivers/media/pci/saa7134/saa7134-dvb.c +++ b/drivers/media/pci/saa7134/saa7134-dvb.c @@ -85,9 +85,6 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); #define dprintk(fmt, arg...) do { if (debug) \ printk(KERN_DEBUG "%s/dvb: " fmt, dev->name , ## arg); } while(0) -/* Print a warning */ -#define wprintk(fmt, arg...) \ - pr_warn("%s/dvb: " fmt, dev->name, ## arg) /* ------------------------------------------------------------------ * mt352 based DVB-T cards @@ -259,7 +256,7 @@ static int kworld_sbtvd_gate_ctrl(struct dvb_frontend* fe, int enable) struct i2c_msg msg = {.addr = 0x4b, .flags = 0, .buf = initmsg, .len = 2}; if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) { - wprintk("could not access the I2C gate\n"); + pr_warn("could not access the I2C gate\n"); return -EIO; } if (enable) @@ -267,7 +264,7 @@ static int kworld_sbtvd_gate_ctrl(struct dvb_frontend* fe, int enable) else msg.buf = msg_disable; if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) { - wprintk("could not access the I2C gate\n"); + pr_warn("could not access the I2C gate\n"); return -EIO; } msleep(20); @@ -370,7 +367,7 @@ static int philips_tda6651_pll_set(struct dvb_frontend *fe) if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) { - wprintk("could not write to tuner at addr: 0x%02x\n", + pr_warn("could not write to tuner at addr: 0x%02x\n", addr << 1); return -EIO; } @@ -557,8 +554,7 @@ static int tda8290_i2c_gate_ctrl( struct dvb_frontend* fe, int enable) tda8290_msg.buf = tda8290_open; } if (i2c_transfer(state->i2c, &tda8290_msg, 1) != 1) { - struct saa7134_dev *dev = fe->dvb->priv; - wprintk("could not access tda8290 I2C gate\n"); + pr_warn("could not access tda8290 I2C gate\n"); return -EIO; } msleep(20); @@ -620,7 +616,7 @@ static int configure_tda827x_fe(struct saa7134_dev *dev, &dev->i2c_adap, tuner_conf)) return 0; - wprintk("no tda827x tuner found at addr: %02x\n", + pr_warn("no tda827x tuner found at addr: %02x\n", cdec_conf->tuner_address); } return -EINVAL; @@ -1042,8 +1038,7 @@ static int md8800_set_voltage2(struct dvb_frontend *fe, fe_sec_voltage_t voltage static int md8800_set_high_voltage2(struct dvb_frontend *fe, long arg) { - struct saa7134_dev *dev = fe->dvb->priv; - wprintk("%s: sorry can't set high LNB supply voltage from here\n", __func__); + pr_warn("%s: sorry can't set high LNB supply voltage from here\n", __func__); return -EIO; } @@ -1402,13 +1397,13 @@ static int dvb_init(struct saa7134_dev *dev) if (fe0->dvb.frontend) { if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x63, &dev->i2c_adap, 0) == NULL) { - wprintk("%s: Lifeview Trio, No tda826x found!\n", __func__); + pr_warn("%s: Lifeview Trio, No tda826x found!\n", __func__); goto detach_frontend; } if (dvb_attach(isl6421_attach, fe0->dvb.frontend, &dev->i2c_adap, 0x08, 0, 0, false) == NULL) { - wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __func__); + pr_warn("%s: Lifeview Trio, No ISL6421 found!\n", __func__); goto detach_frontend; } } @@ -1423,12 +1418,12 @@ static int dvb_init(struct saa7134_dev *dev) if (dvb_attach(tda827x_attach,fe0->dvb.frontend, ads_tech_duo_config.tuner_address, &dev->i2c_adap, &ads_duo_cfg) == NULL) { - wprintk("no tda827x tuner found at addr: %02x\n", + pr_warn("no tda827x tuner found at addr: %02x\n", ads_tech_duo_config.tuner_address); goto detach_frontend; } } else - wprintk("failed to attach tda10046\n"); + pr_warn("failed to attach tda10046\n"); break; case SAA7134_BOARD_TEVION_DVBT_220RF: if (configure_tda827x_fe(dev, &tevion_dvbt220rf_config, @@ -1451,7 +1446,7 @@ static int dvb_init(struct saa7134_dev *dev) if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60, &dev->i2c_adap, 0) == NULL) { - wprintk("%s: Medion Quadro, no tda826x " + pr_warn("%s: Medion Quadro, no tda826x " "found !\n", __func__); goto detach_frontend; } @@ -1460,7 +1455,7 @@ static int dvb_init(struct saa7134_dev *dev) fe->ops.i2c_gate_ctrl(fe, 1); if (dvb_attach(isl6405_attach, fe, &dev->i2c_adap, 0x08, 0, 0) == NULL) { - wprintk("%s: Medion Quadro, no ISL6405 " + pr_warn("%s: Medion Quadro, no ISL6405 " "found !\n", __func__); goto detach_frontend; } @@ -1520,13 +1515,13 @@ static int dvb_init(struct saa7134_dev *dev) if (fe0->dvb.frontend) { if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60, &dev->i2c_adap, 0) == NULL) { - wprintk("%s: No tda826x found!\n", __func__); + pr_warn("%s: No tda826x found!\n", __func__); goto detach_frontend; } if (dvb_attach(isl6421_attach, fe0->dvb.frontend, &dev->i2c_adap, 0x08, 0, 0, false) == NULL) { - wprintk("%s: No ISL6421 found!\n", __func__); + pr_warn("%s: No ISL6421 found!\n", __func__); goto detach_frontend; } } @@ -1594,12 +1589,12 @@ static int dvb_init(struct saa7134_dev *dev) if (fe0->dvb.frontend) { if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60, &dev->i2c_adap, 0) == NULL) { - wprintk("%s: No tda826x found!\n", __func__); + pr_warn("%s: No tda826x found!\n", __func__); goto detach_frontend; } if (dvb_attach(lnbp21_attach, fe0->dvb.frontend, &dev->i2c_adap, 0, 0) == NULL) { - wprintk("%s: No lnbp21 found!\n", __func__); + pr_warn("%s: No lnbp21 found!\n", __func__); goto detach_frontend; } } @@ -1631,7 +1626,7 @@ static int dvb_init(struct saa7134_dev *dev) struct dvb_frontend *fe; if (dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60, &dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL) { - wprintk("%s: MD7134 DVB-S, no SD1878 " + pr_warn("%s: MD7134 DVB-S, no SD1878 " "found !\n", __func__); goto detach_frontend; } @@ -1640,7 +1635,7 @@ static int dvb_init(struct saa7134_dev *dev) fe->ops.i2c_gate_ctrl(fe, 1); if (dvb_attach(isl6405_attach, fe, &dev->i2c_adap, 0x08, 0, 0) == NULL) { - wprintk("%s: MD7134 DVB-S, no ISL6405 " + pr_warn("%s: MD7134 DVB-S, no ISL6405 " "found !\n", __func__); goto detach_frontend; } @@ -1672,13 +1667,13 @@ static int dvb_init(struct saa7134_dev *dev) if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60, &dev->i2c_adap, 0) == NULL) { - wprintk("%s: Asus Tiger 3in1, no " + pr_warn("%s: Asus Tiger 3in1, no " "tda826x found!\n", __func__); goto detach_frontend; } if (dvb_attach(lnbp21_attach, fe0->dvb.frontend, &dev->i2c_adap, 0, 0) == NULL) { - wprintk("%s: Asus Tiger 3in1, no lnbp21" + pr_warn("%s: Asus Tiger 3in1, no lnbp21" " found!\n", __func__); goto detach_frontend; } @@ -1697,13 +1692,13 @@ static int dvb_init(struct saa7134_dev *dev) if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60, &dev->i2c_adap, 0) == NULL) { - wprintk("%s: Asus My Cinema PS3-100, no " + pr_warn("%s: Asus My Cinema PS3-100, no " "tda826x found!\n", __func__); goto detach_frontend; } if (dvb_attach(lnbp21_attach, fe0->dvb.frontend, &dev->i2c_adap, 0, 0) == NULL) { - wprintk("%s: Asus My Cinema PS3-100, no lnbp21" + pr_warn("%s: Asus My Cinema PS3-100, no lnbp21" " found!\n", __func__); goto detach_frontend; } @@ -1751,7 +1746,7 @@ static int dvb_init(struct saa7134_dev *dev) if (fe0->dvb.frontend) { if (dvb_attach(zl10036_attach, fe0->dvb.frontend, &avertv_a700_tuner, &dev->i2c_adap) == NULL) { - wprintk("%s: No zl10036 found!\n", + pr_warn("%s: No zl10036 found!\n", __func__); } } @@ -1762,7 +1757,7 @@ static int dvb_init(struct saa7134_dev *dev) if (fe0->dvb.frontend) if (dvb_attach(zl10039_attach, fe0->dvb.frontend, 0x60, &dev->i2c_adap) == NULL) - wprintk("%s: No zl10039 found!\n", + pr_warn("%s: No zl10039 found!\n", __func__); break; @@ -1775,7 +1770,7 @@ static int dvb_init(struct saa7134_dev *dev) fe0->dvb.frontend, &dev->i2c_adap, &videomate_t750_qt1010_config) == NULL) - wprintk("error attaching QT1010\n"); + pr_warn("error attaching QT1010\n"); } break; case SAA7134_BOARD_ZOLID_HYBRID_PCI: @@ -1851,12 +1846,12 @@ static int dvb_init(struct saa7134_dev *dev) fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL; if (dvb_attach(zl10039_attach, fe0->dvb.frontend, 0x60, &dev->i2c_adap) == NULL) - wprintk("%s: No zl10039 found!\n", + pr_warn("%s: No zl10039 found!\n", __func__); } break; default: - wprintk("Huh? unknown DVB card?\n"); + pr_warn("Huh? unknown DVB card?\n"); break; } -- cgit v1.2.3-59-g8ed1b From 7516657af08d4a35abec6807701933d48bcac7c6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 30 Apr 2015 07:09:02 -0300 Subject: [media] saa7134-dvb: use pr_debug() for the saa7134 dvb module As this module doesn't use any debug level, it is easy to just replace all debug printks by pr_debug(). Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-dvb.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7134/saa7134-dvb.c b/drivers/media/pci/saa7134/saa7134-dvb.c index 7e0091343c87..7edb49729489 100644 --- a/drivers/media/pci/saa7134/saa7134-dvb.c +++ b/drivers/media/pci/saa7134/saa7134-dvb.c @@ -76,16 +76,8 @@ static int use_frontend; module_param(use_frontend, int, 0644); MODULE_PARM_DESC(use_frontend,"for cards with multiple frontends (0: terrestrial, 1: satellite)"); -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off module debugging (default:off)."); - DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -#define dprintk(fmt, arg...) do { if (debug) \ - printk(KERN_DEBUG "%s/dvb: " fmt, dev->name , ## arg); } while(0) - - /* ------------------------------------------------------------------ * mt352 based DVB-T cards */ @@ -110,7 +102,7 @@ static int pinnacle_antenna_pwr(struct saa7134_dev *dev, int on) saa_setl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 28)); udelay(10); ok = saa_readl(SAA7134_GPIO_GPSTATUS0) & (1 << 27); - dprintk("%s %s\n", __func__, ok ? "on" : "off"); + pr_debug("%s %s\n", __func__, ok ? "on" : "off"); if (!ok) saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26)); @@ -128,9 +120,8 @@ static int mt352_pinnacle_init(struct dvb_frontend* fe) static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x0f }; static u8 scan_ctl_cfg [] = { SCAN_CTL, 0x0d }; static u8 irq_cfg [] = { INTERRUPT_EN_0, 0x00, 0x00, 0x00, 0x00 }; - struct saa7134_dev *dev= fe->dvb->priv; - dprintk("%s called\n", __func__); + pr_debug("%s called\n", __func__); mt352_write(fe, clock_config, sizeof(clock_config)); udelay(200); @@ -568,10 +559,10 @@ static int philips_tda827x_tuner_init(struct dvb_frontend *fe) switch (state->config->antenna_switch) { case 0: break; - case 1: dprintk("setting GPIO21 to 0 (TV antenna?)\n"); + case 1: pr_debug("setting GPIO21 to 0 (TV antenna?)\n"); saa7134_set_gpio(dev, 21, 0); break; - case 2: dprintk("setting GPIO21 to 1 (Radio antenna?)\n"); + case 2: pr_debug("setting GPIO21 to 1 (Radio antenna?)\n"); saa7134_set_gpio(dev, 21, 1); break; } @@ -585,10 +576,10 @@ static int philips_tda827x_tuner_sleep(struct dvb_frontend *fe) switch (state->config->antenna_switch) { case 0: break; - case 1: dprintk("setting GPIO21 to 1 (Radio antenna?)\n"); + case 1: pr_debug("setting GPIO21 to 1 (Radio antenna?)\n"); saa7134_set_gpio(dev, 21, 1); break; - case 2: dprintk("setting GPIO21 to 0 (TV antenna?)\n"); + case 2: pr_debug("setting GPIO21 to 0 (TV antenna?)\n"); saa7134_set_gpio(dev, 21, 0); break; } @@ -1246,7 +1237,7 @@ static int dvb_init(struct saa7134_dev *dev) switch (dev->board) { case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL: - dprintk("pinnacle 300i dvb setup\n"); + pr_debug("pinnacle 300i dvb setup\n"); fe0->dvb.frontend = dvb_attach(mt352_attach, &pinnacle_300i, &dev->i2c_adap); if (fe0->dvb.frontend) { @@ -1255,7 +1246,7 @@ static int dvb_init(struct saa7134_dev *dev) break; case SAA7134_BOARD_AVERMEDIA_777: case SAA7134_BOARD_AVERMEDIA_A16AR: - dprintk("avertv 777 dvb setup\n"); + pr_debug("avertv 777 dvb setup\n"); fe0->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777, &dev->i2c_adap); if (fe0->dvb.frontend) { @@ -1265,7 +1256,7 @@ static int dvb_init(struct saa7134_dev *dev) } break; case SAA7134_BOARD_AVERMEDIA_A16D: - dprintk("AverMedia A16D dvb setup\n"); + pr_debug("AverMedia A16D dvb setup\n"); fe0->dvb.frontend = dvb_attach(mt352_attach, &avermedia_xc3028_mt352_dev, &dev->i2c_adap); @@ -1610,7 +1601,7 @@ static int dvb_init(struct saa7134_dev *dev) goto detach_frontend; break; case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: - dprintk("AverMedia E506R dvb setup\n"); + pr_debug("AverMedia E506R dvb setup\n"); saa7134_set_gpio(dev, 25, 0); msleep(10); saa7134_set_gpio(dev, 25, 1); -- cgit v1.2.3-59-g8ed1b From e43c1732addce62ba50ce1a37009c104b585ac45 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 30 Apr 2015 07:12:19 -0300 Subject: [media] saa7134-empress: use pr_debug() for the saa7134 empress module As this module doesn't use any debug level, it is easy to just replace all debug printks by pr_debug(). Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-empress.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7134/saa7134-empress.c b/drivers/media/pci/saa7134/saa7134-empress.c index baccd5d72ab9..86ab17bbc444 100644 --- a/drivers/media/pci/saa7134/saa7134-empress.c +++ b/drivers/media/pci/saa7134/saa7134-empress.c @@ -39,13 +39,6 @@ static unsigned int empress_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; module_param_array(empress_nr, int, NULL, 0444); MODULE_PARM_DESC(empress_nr,"ts device number"); -static unsigned int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug,"enable debug messages"); - -#define dprintk(fmt, arg...) if (debug) \ - printk(KERN_DEBUG "%s/empress: " fmt, dev->name , ## arg) - /* ------------------------------------------------------------------ */ static int start_streaming(struct vb2_queue *vq, unsigned int count) @@ -229,9 +222,9 @@ static void empress_signal_update(struct work_struct *work) container_of(work, struct saa7134_dev, empress_workqueue); if (dev->nosignal) { - dprintk("no video signal\n"); + pr_debug("no video signal\n"); } else { - dprintk("video signal acquired\n"); + pr_debug("video signal acquired\n"); } } @@ -263,7 +256,7 @@ static int empress_init(struct saa7134_dev *dev) struct vb2_queue *q; int err; - dprintk("%s: %s\n",dev->name,__func__); + pr_debug("%s: %s\n",dev->name,__func__); dev->empress_dev = video_device_alloc(); if (NULL == dev->empress_dev) return -ENOMEM; @@ -325,7 +318,7 @@ static int empress_init(struct saa7134_dev *dev) static int empress_fini(struct saa7134_dev *dev) { - dprintk("%s: %s\n",dev->name,__func__); + pr_debug("%s: %s\n",dev->name,__func__); if (NULL == dev->empress_dev) return 0; -- cgit v1.2.3-59-g8ed1b From 51626557ace26ebc48d5d56c85675fb106d839c9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 30 Apr 2015 07:15:20 -0300 Subject: [media] saa7134: use pr_warn() on some places where no KERN_foo were used On a few places, mostly during board detection, some printk() macros were called without especifying any message level. Those are actually warnings. So, use pr_warn() for them. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-cards.c | 28 ++++++++++++++-------------- drivers/media/pci/saa7134/saa7134-core.c | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c index 5b81157a5003..abbeeb923114 100644 --- a/drivers/media/pci/saa7134/saa7134-cards.c +++ b/drivers/media/pci/saa7134/saa7134-cards.c @@ -7159,10 +7159,10 @@ MODULE_DEVICE_TABLE(pci, saa7134_pci_tbl); static void board_flyvideo(struct saa7134_dev *dev) { - printk("%s: there are different flyvideo cards with different tuners\n" - "%s: out there, you might have to use the tuner= insmod\n" - "%s: option to override the default value.\n", - dev->name, dev->name, dev->name); + pr_warn("%s: there are different flyvideo cards with different tuners\n" + "%s: out there, you might have to use the tuner= insmod\n" + "%s: option to override the default value.\n", + dev->name, dev->name, dev->name); } static int saa7134_xc2028_callback(struct saa7134_dev *dev, @@ -7513,10 +7513,10 @@ int saa7134_board_init1(struct saa7134_dev *dev) dev->has_remote = SAA7134_REMOTE_GPIO; break; case SAA7134_BOARD_MD5044: - printk("%s: seems there are two different versions of the MD5044\n" - "%s: (with the same ID) out there. If sound doesn't work for\n" - "%s: you try the audio_clock_override=0x200000 insmod option.\n", - dev->name,dev->name,dev->name); + pr_warn("%s: seems there are two different versions of the MD5044\n" + "%s: (with the same ID) out there. If sound doesn't work for\n" + "%s: you try the audio_clock_override=0x200000 insmod option.\n", + dev->name,dev->name,dev->name); break; case SAA7134_BOARD_CINERGY400_CARDBUS: /* power-up tuner chip */ @@ -7641,10 +7641,10 @@ int saa7134_board_init1(struct saa7134_dev *dev) dev->has_remote = SAA7134_REMOTE_I2C; break; case SAA7134_BOARD_AVERMEDIA_A169_B: - printk("%s: %s: dual saa713x broadcast decoders\n" - "%s: Sorry, none of the inputs to this chip are supported yet.\n" - "%s: Dual decoder functionality is disabled for now, use the other chip.\n", - dev->name,card(dev).name,dev->name,dev->name); + pr_warn("%s: %s: dual saa713x broadcast decoders\n" + "%s: Sorry, none of the inputs to this chip are supported yet.\n" + "%s: Dual decoder functionality is disabled for now, use the other chip.\n", + dev->name,card(dev).name,dev->name,dev->name); break; case SAA7134_BOARD_AVERMEDIA_M102: /* enable tuner */ @@ -7790,7 +7790,7 @@ int saa7134_board_init2(struct saa7134_dev *dev) if (board == dev->board) break; dev->board = board; - printk("%s: board type fixup: %s\n", dev->name, + pr_warn("%s: board type fixup: %s\n", dev->name, saa7134_boards[dev->board].name); dev->tuner_type = saa7134_boards[dev->board].tuner_type; @@ -8047,7 +8047,7 @@ int saa7134_board_init2(struct saa7134_dev *dev) msg.len = ARRAY_SIZE(buffer[0]); if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) pr_warn("%s: Unable to enable tuner(%i).\n", - dev->name, i); + dev->name, i); } break; } diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c index c206148f816b..83dbb443214e 100644 --- a/drivers/media/pci/saa7134/saa7134-core.c +++ b/drivers/media/pci/saa7134/saa7134-core.c @@ -947,7 +947,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0)); pci_set_master(pci_dev); if (!pci_dma_supported(pci_dev, DMA_BIT_MASK(32))) { - printk("%s: Oops: no 32bit PCI DMA ???\n",dev->name); + pr_warn("%s: Oops: no 32bit PCI DMA ???\n", dev->name); err = -EIO; goto fail1; } -- cgit v1.2.3-59-g8ed1b From c6c62cce324c96a74a84c419ff8f2f847fd4a918 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 30 Apr 2015 08:03:30 -0300 Subject: [media] saa7134: better handle core debug messages On media drivers, debugging messages should be grouped into categories, as this makes easier to debug the driver. In the case of saa7134, the core has 2 debug categories, one for IRQ, and another one for the core itself. The IRQ have actually 2 levels of debug. So, instead of using pr_dbg(), where everything would be in the same box, let's define two macros that use pr_fmt(), one for the core, and another one for irq. With that, we can replace the remaining printk() occurrences at the core to use either core_dbg() or irq_dbg(), depending on the group of debug macros that need to be enabled. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-core.c | 68 ++++++++++++++++---------------- 1 file changed, 33 insertions(+), 35 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c index 83dbb443214e..e88e4ec8c0ee 100644 --- a/drivers/media/pci/saa7134/saa7134-core.c +++ b/drivers/media/pci/saa7134/saa7134-core.c @@ -102,8 +102,11 @@ static unsigned int saa7134_devcount; int (*saa7134_dmasound_init)(struct saa7134_dev *dev); int (*saa7134_dmasound_exit)(struct saa7134_dev *dev); -#define dprintk(fmt, arg...) if (core_debug) \ - printk(KERN_DEBUG "%s/core: " fmt, dev->name , ## arg) +#define core_dbg(fmt, arg...) if (core_debug) \ + printk(KERN_DEBUG pr_fmt("core: " fmt), ## arg) + +#define irq_dbg(level, fmt, arg...) if (irq_debug > level) \ + printk(KERN_DEBUG pr_fmt("irq: " fmt), ## arg) void saa7134_track_gpio(struct saa7134_dev *dev, char *msg) { @@ -116,8 +119,7 @@ void saa7134_track_gpio(struct saa7134_dev *dev, char *msg) saa_andorb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN,SAA7134_GPIO_GPRESCAN); mode = saa_readl(SAA7134_GPIO_GPMODE0 >> 2) & 0xfffffff; status = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & 0xfffffff; - printk(KERN_DEBUG - "%s: gpio: mode=0x%07lx in=0x%07lx out=0x%07lx [%s]\n", + core_dbg("%s: gpio: mode=0x%07lx in=0x%07lx out=0x%07lx [%s]\n", dev->name, mode, (~mode) & status, mode & status, msg); } @@ -128,7 +130,7 @@ void saa7134_set_gpio(struct saa7134_dev *dev, int bit_no, int value) index = 1 << bit_no; switch (value) { case 0: /* static value */ - case 1: dprintk("setting GPIO%d to static %d\n", bit_no, value); + case 1: core_dbg("setting GPIO%d to static %d\n", bit_no, value); /* turn sync mode off if necessary */ if (index & 0x00c00000) saa_andorb(SAA7134_VIDEO_PORT_CTRL6, 0x0f, 0x00); @@ -140,7 +142,7 @@ void saa7134_set_gpio(struct saa7134_dev *dev, int bit_no, int value) saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, index, bitval); break; case 3: /* tristate */ - dprintk("setting GPIO%d to tristate\n", bit_no); + core_dbg("setting GPIO%d to tristate\n", bit_no); saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, index, 0); break; } @@ -274,7 +276,7 @@ int saa7134_buffer_queue(struct saa7134_dev *dev, unsigned long flags; spin_lock_irqsave(&dev->slock, flags); - dprintk("buffer_queue %p\n", buf); + core_dbg("buffer_queue %p\n", buf); if (NULL == q->curr) { if (!q->need_two) { q->curr = buf; @@ -298,7 +300,7 @@ void saa7134_buffer_finish(struct saa7134_dev *dev, struct saa7134_dmaqueue *q, unsigned int state) { - dprintk("buffer_finish %p\n", q->curr); + core_dbg("buffer_finish %p\n", q->curr); /* finish current buffer */ v4l2_get_timestamp(&q->curr->vb2.v4l2_buf.timestamp); @@ -318,18 +320,18 @@ void saa7134_buffer_next(struct saa7134_dev *dev, if (!list_empty(&q->queue)) { /* activate next one from queue */ buf = list_entry(q->queue.next, struct saa7134_buf, entry); - dprintk("buffer_next %p [prev=%p/next=%p]\n", + core_dbg("buffer_next %p [prev=%p/next=%p]\n", buf, q->queue.prev, q->queue.next); list_del(&buf->entry); if (!list_empty(&q->queue)) next = list_entry(q->queue.next, struct saa7134_buf, entry); q->curr = buf; buf->activate(dev, buf, next); - dprintk("buffer_next #2 prev=%p/next=%p\n", + core_dbg("buffer_next #2 prev=%p/next=%p\n", q->queue.prev, q->queue.next); } else { /* nothing to do -- just stop DMA */ - dprintk("buffer_next %p\n", NULL); + core_dbg("buffer_next %p\n", NULL); saa7134_set_dmabits(dev); del_timer(&q->timeout); } @@ -351,7 +353,7 @@ void saa7134_buffer_timeout(unsigned long data) /* flag current buffer as failed, try to start over with the next one. */ if (q->curr) { - dprintk("timeout on %p\n", q->curr); + core_dbg("timeout on %p\n", q->curr); saa7134_buffer_finish(dev, q, VB2_BUF_STATE_ERROR); } saa7134_buffer_next(dev, q); @@ -474,7 +476,7 @@ int saa7134_set_dmabits(struct saa7134_dev *dev) SAA7134_MAIN_CTRL_TE5 | SAA7134_MAIN_CTRL_TE6, ctrl); - dprintk("dmabits: task=0x%02x ctrl=0x%02x irq=0x%x split=%s\n", + core_dbg("dmabits: task=0x%02x ctrl=0x%02x irq=0x%x split=%s\n", task, ctrl, irq, split ? "no" : "yes"); return 0; @@ -496,21 +498,21 @@ static void print_irqstatus(struct saa7134_dev *dev, int loop, { unsigned int i; - printk(KERN_DEBUG "%s/irq[%d,%ld]: r=0x%lx s=0x%02lx", - dev->name,loop,jiffies,report,status); + irq_dbg(1, "[%d,%ld]: r=0x%lx s=0x%02lx", + loop, jiffies, report,status); for (i = 0; i < IRQBITS; i++) { if (!(report & (1 << i))) continue; - printk(" %s",irqbits[i]); + pr_cont(" %s",irqbits[i]); } if (report & SAA7134_IRQ_REPORT_DONE_RA0) { - printk(" | RA0=%s,%s,%s,%ld", - (status & 0x40) ? "vbi" : "video", - (status & 0x20) ? "b" : "a", - (status & 0x10) ? "odd" : "even", - (status & 0x0f)); + pr_cont(" | RA0=%s,%s,%s,%ld", + (status & 0x40) ? "vbi" : "video", + (status & 0x20) ? "b" : "a", + (status & 0x10) ? "odd" : "even", + (status & 0x0f)); } - printk("\n"); + pr_cont("\n"); } static irqreturn_t saa7134_irq(int irq, void *dev_id) @@ -532,16 +534,12 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id) if ((report & SAA7134_IRQ_REPORT_DONE_RA3) && (dev->dmasound.priv_data != NULL) ) { - if (irq_debug > 1) - printk(KERN_DEBUG "%s/irq: preserving DMA sound interrupt\n", - dev->name); + irq_dbg(2, "preserving DMA sound interrupt\n"); report &= ~SAA7134_IRQ_REPORT_DONE_RA3; } if (0 == report) { - if (irq_debug > 1) - printk(KERN_DEBUG "%s/irq: no (more) work\n", - dev->name); + irq_dbg(2,"no (more) work\n"); goto out; } @@ -680,7 +678,7 @@ static int saa7134_hw_enable1(struct saa7134_dev *dev) static int saa7134_hwinit1(struct saa7134_dev *dev) { - dprintk("hwinit1\n"); + core_dbg("hwinit1\n"); saa_writel(SAA7134_IRQ1, 0); saa_writel(SAA7134_IRQ2, 0); @@ -742,7 +740,7 @@ static int saa7134_hw_enable2(struct saa7134_dev *dev) static int saa7134_hwinit2(struct saa7134_dev *dev) { - dprintk("hwinit2\n"); + core_dbg("hwinit2\n"); saa7134_video_init2(dev); saa7134_tvaudio_init2(dev); @@ -756,7 +754,7 @@ static int saa7134_hwinit2(struct saa7134_dev *dev) /* shutdown */ static int saa7134_hwfini(struct saa7134_dev *dev) { - dprintk("hwfini\n"); + core_dbg("hwfini\n"); if (card_has_mpeg(dev)) saa7134_ts_fini(dev); @@ -793,11 +791,11 @@ static void must_configure_manually(int has_eeprom) for (p = 0; saa7134_pci_tbl[p].driver_data; p++) { if (saa7134_pci_tbl[p].driver_data != i) continue; - printk(" %04x:%04x", + pr_cont(" %04x:%04x", saa7134_pci_tbl[p].subvendor, saa7134_pci_tbl[p].subdevice); } - printk("\n"); + pr_cont("\n"); } } @@ -1202,12 +1200,12 @@ static int saa7134_buffer_requeue(struct saa7134_dev *dev, buf = q->curr; next = buf; - dprintk("buffer_requeue\n"); + core_dbg("buffer_requeue\n"); if (!buf) return 0; - dprintk("buffer_requeue : resending active buffers \n"); + core_dbg("buffer_requeue : resending active buffers \n"); if (!list_empty(&q->queue)) next = list_entry(q->queue.next, struct saa7134_buf, -- cgit v1.2.3-59-g8ed1b From 30693f346e4f5c0720de66c424b38053f9e34a08 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 30 Apr 2015 08:21:14 -0300 Subject: [media] saa7134-i2c: make debug macros to use pr_fmt() Converting debug prints to use pr_foo() is not trivial, as the result will be a way worse than what's provided here, due to the pieces of the code that prints the I2C transfers. Those use a lot pr_cont(), and, depending on using either level 1 or 2, a different set of macros are selected. So, let's replace d1printk() and d2printk() macros by i2c_dbg() and i2c_count() adding a debug level there. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-i2c.c | 54 ++++++++++++++++----------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7134/saa7134-i2c.c b/drivers/media/pci/saa7134/saa7134-i2c.c index 2dcc497fb166..b140143dba7d 100644 --- a/drivers/media/pci/saa7134/saa7134-i2c.c +++ b/drivers/media/pci/saa7134/saa7134-i2c.c @@ -41,8 +41,11 @@ static unsigned int i2c_scan; module_param(i2c_scan, int, 0444); MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); -#define d1printk if (1 == i2c_debug) printk -#define d2printk if (2 == i2c_debug) printk +#define i2c_dbg(level, fmt, arg...) if (i2c_debug == level) \ + printk(KERN_DEBUG pr_fmt("i2c: " fmt), ## arg) + +#define i2c_cont(level, fmt, arg...) if (i2c_debug == level) \ + pr_cont(fmt, ## arg) #define I2C_WAIT_DELAY 32 #define I2C_WAIT_RETRY 16 @@ -90,23 +93,20 @@ static inline enum i2c_status i2c_get_status(struct saa7134_dev *dev) enum i2c_status status; status = saa_readb(SAA7134_I2C_ATTR_STATUS) & 0x0f; - d2printk(KERN_DEBUG "%s: i2c stat <= %s\n",dev->name, - str_i2c_status[status]); + i2c_dbg(2, "i2c stat <= %s\n", str_i2c_status[status]); return status; } static inline void i2c_set_status(struct saa7134_dev *dev, enum i2c_status status) { - d2printk(KERN_DEBUG "%s: i2c stat => %s\n",dev->name, - str_i2c_status[status]); + i2c_dbg(2, "i2c stat => %s\n", str_i2c_status[status]); saa_andorb(SAA7134_I2C_ATTR_STATUS,0x0f,status); } static inline void i2c_set_attr(struct saa7134_dev *dev, enum i2c_attr attr) { - d2printk(KERN_DEBUG "%s: i2c attr => %s\n",dev->name, - str_i2c_attr[attr]); + i2c_dbg(2, "i2c attr => %s\n", str_i2c_attr[attr]); saa_andorb(SAA7134_I2C_ATTR_STATUS,0xc0,attr << 6); } @@ -169,7 +169,7 @@ static int i2c_reset(struct saa7134_dev *dev) enum i2c_status status; int count; - d2printk(KERN_DEBUG "%s: i2c reset\n",dev->name); + i2c_dbg(2, "i2c reset\n"); status = i2c_get_status(dev); if (!i2c_is_error(status)) return true; @@ -207,7 +207,7 @@ static inline int i2c_send_byte(struct saa7134_dev *dev, // dword |= 0x40 << 16; /* 400 kHz */ dword |= 0xf0 << 24; saa_writel(SAA7134_I2C_ATTR_STATUS >> 2, dword); - d2printk(KERN_DEBUG "%s: i2c data => 0x%x\n",dev->name,data); + i2c_dbg(2, "i2c data => 0x%x\n", data); if (!i2c_is_busy_wait(dev)) return -EIO; @@ -229,7 +229,7 @@ static inline int i2c_recv_byte(struct saa7134_dev *dev) if (i2c_is_error(status)) return -EIO; data = saa_readb(SAA7134_I2C_DATA); - d2printk(KERN_DEBUG "%s: i2c data <= 0x%x\n",dev->name,data); + i2c_dbg(2, "i2c data <= 0x%x\n", data); return data; } @@ -246,12 +246,12 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap, if (!i2c_reset(dev)) return -EIO; - d2printk("start xfer\n"); - d1printk(KERN_DEBUG "%s: i2c xfer:",dev->name); + i2c_dbg(2, "start xfer\n"); + i2c_dbg(1, "i2c xfer:"); for (i = 0; i < num; i++) { if (!(msgs[i].flags & I2C_M_NOSTART) || 0 == i) { /* send address */ - d2printk("send address\n"); + i2c_dbg(2, "send address\n"); addr = msgs[i].addr << 1; if (msgs[i].flags & I2C_M_RD) addr |= 1; @@ -263,50 +263,50 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap, * needed to talk to the mt352 demux * thanks to pinnacle for the hint */ int quirk = 0xfe; - d1printk(" [%02x quirk]",quirk); + i2c_cont(1, " [%02x quirk]",quirk); i2c_send_byte(dev,START,quirk); i2c_recv_byte(dev); } - d1printk(" < %02x", addr); + i2c_cont(1, " < %02x", addr); rc = i2c_send_byte(dev,START,addr); if (rc < 0) goto err; } if (msgs[i].flags & I2C_M_RD) { /* read bytes */ - d2printk("read bytes\n"); + i2c_dbg(2, "read bytes\n"); for (byte = 0; byte < msgs[i].len; byte++) { - d1printk(" ="); + i2c_cont(1, " ="); rc = i2c_recv_byte(dev); if (rc < 0) goto err; - d1printk("%02x", rc); + i2c_cont(1, "%02x", rc); msgs[i].buf[byte] = rc; } /* discard mysterious extra byte when reading from Samsung S5H1411. i2c bus gets error if we do not. */ if (0x19 == msgs[i].addr) { - d1printk(" ?"); + i2c_cont(1, " ?"); rc = i2c_recv_byte(dev); if (rc < 0) goto err; - d1printk("%02x", rc); + i2c_cont(1, "%02x", rc); } } else { /* write bytes */ - d2printk("write bytes\n"); + i2c_dbg(2, "write bytes\n"); for (byte = 0; byte < msgs[i].len; byte++) { data = msgs[i].buf[byte]; - d1printk(" %02x", data); + i2c_cont(1, " %02x", data); rc = i2c_send_byte(dev,CONTINUE,data); if (rc < 0) goto err; } } } - d2printk("xfer done\n"); - d1printk(" >"); + i2c_dbg(2, "xfer done\n"); + i2c_cont(1, " >"); i2c_set_attr(dev,STOP); rc = -EIO; if (!i2c_is_busy_wait(dev)) @@ -317,12 +317,12 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap, /* ensure that the bus is idle for at least one bit slot */ msleep(1); - d1printk("\n"); + i2c_cont(1, "\n"); return num; err: if (1 == i2c_debug) { status = i2c_get_status(dev); - printk(" ERROR: %s\n",str_i2c_status[status]); + i2c_cont(1, " ERROR: %s\n", str_i2c_status[status]); } return rc; } -- cgit v1.2.3-59-g8ed1b From af5d20ceb359bcd6a76c156a99ff5100c4b05401 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 30 Apr 2015 08:38:02 -0300 Subject: [media] saa7134-ts: use pr_fmt() at the debug macro instead of using dev->name, let's use pr_fmt() like on the other parts of saa7134. Also, rename the debug macro to ts_dbg() to match the namespace for the debug macros. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-ts.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7134/saa7134-ts.c b/drivers/media/pci/saa7134/saa7134-ts.c index 8a2938c34d32..5d7c4afac8e6 100644 --- a/drivers/media/pci/saa7134/saa7134-ts.c +++ b/drivers/media/pci/saa7134/saa7134-ts.c @@ -35,8 +35,8 @@ static unsigned int ts_debug; module_param(ts_debug, int, 0644); MODULE_PARM_DESC(ts_debug,"enable debug messages [ts]"); -#define dprintk(fmt, arg...) if (ts_debug) \ - printk(KERN_DEBUG "%s/ts: " fmt, dev->name , ## arg) +#define ts_dbg(fmt, arg...) if (ts_debug) \ + printk(KERN_DEBUG pr_fmt("ts: " fmt), ## arg) /* ------------------------------------------------------------------ */ static int buffer_activate(struct saa7134_dev *dev, @@ -44,7 +44,7 @@ static int buffer_activate(struct saa7134_dev *dev, struct saa7134_buf *next) { - dprintk("buffer_activate [%p]",buf); + ts_dbg("buffer_activate [%p]",buf); buf->top_seen = 0; if (!dev->ts_started) @@ -53,12 +53,12 @@ static int buffer_activate(struct saa7134_dev *dev, if (NULL == next) next = buf; if (V4L2_FIELD_TOP == dev->ts_field) { - dprintk("- [top] buf=%p next=%p\n",buf,next); + ts_dbg("- [top] buf=%p next=%p\n",buf,next); saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(buf)); saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(next)); dev->ts_field = V4L2_FIELD_BOTTOM; } else { - dprintk("- [bottom] buf=%p next=%p\n",buf,next); + ts_dbg("- [bottom] buf=%p next=%p\n",buf,next); saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next)); saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf)); dev->ts_field = V4L2_FIELD_TOP; @@ -95,7 +95,7 @@ int saa7134_ts_buffer_prepare(struct vb2_buffer *vb2) struct sg_table *dma = vb2_dma_sg_plane_desc(vb2, 0); unsigned int lines, llength, size; - dprintk("buffer_prepare [%p]\n", buf); + ts_dbg("buffer_prepare [%p]\n", buf); llength = TS_PACKET_SIZE; lines = dev->ts.nr_packets; @@ -239,7 +239,7 @@ int saa7134_ts_init1(struct saa7134_dev *dev) /* Function for stop TS */ int saa7134_ts_stop(struct saa7134_dev *dev) { - dprintk("TS stop\n"); + ts_dbg("TS stop\n"); if (!dev->ts_started) return 0; @@ -261,7 +261,7 @@ int saa7134_ts_stop(struct saa7134_dev *dev) /* Function for start TS */ int saa7134_ts_start(struct saa7134_dev *dev) { - dprintk("TS start\n"); + ts_dbg("TS start\n"); if (WARN_ON(dev->ts_started)) return 0; -- cgit v1.2.3-59-g8ed1b From e67bcf3ebec17897e9a1ba7acf49772c37f5d418 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 30 Apr 2015 08:45:18 -0300 Subject: [media] saa7134: change the debug macros for saa7134-tvaudio use just one macro instead of 2, naming it as audio_dbg() and using pr_fmt(). Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-tvaudio.c | 144 ++++++++++++++-------------- 1 file changed, 70 insertions(+), 74 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7134/saa7134-tvaudio.c b/drivers/media/pci/saa7134/saa7134-tvaudio.c index e8aeea4cf422..360f447bd74d 100644 --- a/drivers/media/pci/saa7134/saa7134-tvaudio.c +++ b/drivers/media/pci/saa7134/saa7134-tvaudio.c @@ -49,13 +49,8 @@ static int audio_clock_tweak; module_param(audio_clock_tweak, int, 0644); MODULE_PARM_DESC(audio_clock_tweak, "Audio clock tick fine tuning for cards with audio crystal that's slightly off (range [-1024 .. 1024])"); -#define dprintk(fmt, arg...) if (audio_debug) \ - printk(KERN_DEBUG "%s/audio: " fmt, dev->name , ## arg) -#define d2printk(fmt, arg...) if (audio_debug > 1) \ - printk(KERN_DEBUG "%s/audio: " fmt, dev->name, ## arg) - -#define print_regb(reg) printk("%s: reg 0x%03x [%-16s]: 0x%02x\n", \ - dev->name,(SAA7134_##reg),(#reg),saa_readb((SAA7134_##reg))) +#define audio_dbg(level, fmt, arg...) if (audio_debug >= level) \ + printk(KERN_DEBUG pr_fmt("audio: " fmt), ## arg) /* msecs */ #define SCAN_INITIAL_DELAY 1000 @@ -206,13 +201,14 @@ static void mute_input_7134(struct saa7134_dev *dev) if (dev->hw_mute == mute && dev->hw_input == in && !dev->insuspend) { - dprintk("mute/input: nothing to do [mute=%d,input=%s]\n", - mute,in->name); + audio_dbg(1, "mute/input: nothing to do [mute=%d,input=%s]\n", + mute, in->name); return; } - dprintk("ctl_mute=%d automute=%d input=%s => mute=%d input=%s\n", - dev->ctl_mute,dev->automute,dev->input->name,mute,in->name); + audio_dbg(1, "ctl_mute=%d automute=%d input=%s => mute=%d input=%s\n", + dev->ctl_mute, dev->automute, + dev->input->name, mute, in->name); dev->hw_mute = mute; dev->hw_input = in; @@ -265,8 +261,8 @@ static void tvaudio_setmode(struct saa7134_dev *dev, tweak = audio_clock_tweak; if (note) - dprintk("tvaudio_setmode: %s %s [%d.%03d/%d.%03d MHz] acpf=%d%+d\n", - note,audio->name, + audio_dbg(1, "tvaudio_setmode: %s %s [%d.%03d/%d.%03d MHz] acpf=%d%+d\n", + note, audio->name, audio->carr1 / 1000, audio->carr1 % 1000, audio->carr2 / 1000, audio->carr2 % 1000, acpf, tweak); @@ -334,14 +330,14 @@ static int tvaudio_checkcarrier(struct saa7134_dev *dev, struct mainscan *scan) if (!(dev->tvnorm->id & scan->std)) { value = 0; - dprintk("skipping %d.%03d MHz [%4s]\n", - scan->carr / 1000, scan->carr % 1000, scan->name); + audio_dbg(1, "skipping %d.%03d MHz [%4s]\n", + scan->carr / 1000, scan->carr % 1000, scan->name); return 0; } if (audio_debug > 1) { int i; - dprintk("debug %d:",scan->carr); + audio_dbg(1, "debug %d:", scan->carr); for (i = -150; i <= 150; i += 30) { tvaudio_setcarrier(dev,scan->carr+i,scan->carr+i); saa_readl(SAA7134_LEVEL_READOUT1 >> 2); @@ -349,11 +345,11 @@ static int tvaudio_checkcarrier(struct saa7134_dev *dev, struct mainscan *scan) return -1; value = saa_readl(SAA7134_LEVEL_READOUT1 >> 2); if (0 == i) - printk(" # %6d # ",value >> 16); + pr_cont(" # %6d # ",value >> 16); else - printk(" %6d",value >> 16); + pr_cont(" %6d",value >> 16); } - printk("\n"); + pr_cont("\n"); } tvaudio_setcarrier(dev,scan->carr-90,scan->carr-90); @@ -371,9 +367,9 @@ static int tvaudio_checkcarrier(struct saa7134_dev *dev, struct mainscan *scan) left >>= 16; right >>= 16; value = left > right ? left - right : right - left; - dprintk("scanning %d.%03d MHz [%4s] => dc is %5d [%d/%d]\n", - scan->carr / 1000, scan->carr % 1000, - scan->name, value, left, right); + audio_dbg(1, "scanning %d.%03d MHz [%4s] => dc is %5d [%d/%d]\n", + scan->carr / 1000, scan->carr % 1000, + scan->name, value, left, right); return value; } @@ -389,7 +385,7 @@ static int tvaudio_getstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *au case TVAUDIO_FM_K_STEREO: case TVAUDIO_FM_BG_STEREO: idp = (saa_readb(SAA7134_IDENT_SIF) & 0xe0) >> 5; - dprintk("getstereo: fm/stereo: idp=0x%x\n",idp); + audio_dbg(1, "getstereo: fm/stereo: idp=0x%x\n", idp); if (0x03 == (idp & 0x03)) retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; else if (0x05 == (idp & 0x05)) @@ -403,10 +399,10 @@ static int tvaudio_getstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *au case TVAUDIO_NICAM_FM: case TVAUDIO_NICAM_AM: nicam = saa_readb(SAA7134_AUDIO_STATUS); - dprintk("getstereo: nicam=0x%x\n",nicam); + audio_dbg(1, "getstereo: nicam=0x%x\n", nicam); if (nicam & 0x1) { nicam_status = saa_readb(SAA7134_NICAM_STATUS); - dprintk("getstereo: nicam_status=0x%x\n", nicam_status); + audio_dbg(1, "getstereo: nicam_status=0x%x\n", nicam_status); switch (nicam_status & 0x03) { case 0x01: @@ -424,7 +420,7 @@ static int tvaudio_getstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *au break; } if (retval != -1) - dprintk("found audio subchannels:%s%s%s%s\n", + audio_dbg(1, "found audio subchannels:%s%s%s%s\n", (retval & V4L2_TUNER_SUB_MONO) ? " mono" : "", (retval & V4L2_TUNER_SUB_STEREO) ? " stereo" : "", (retval & V4L2_TUNER_SUB_LANG1) ? " lang1" : "", @@ -459,8 +455,8 @@ static int tvaudio_setstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *au case TVAUDIO_FM_BG_STEREO: case TVAUDIO_NICAM_AM: case TVAUDIO_NICAM_FM: - dprintk("setstereo [fm] => %s\n", - name[ mode % ARRAY_SIZE(name) ]); + audio_dbg(1, "setstereo [fm] => %s\n", + name[mode % ARRAY_SIZE(name)]); reg = fm[ mode % ARRAY_SIZE(fm) ]; saa_writeb(SAA7134_FM_DEMATRIX, reg); break; @@ -489,7 +485,8 @@ static int tvaudio_thread(void *data) try_to_freeze(); dev->thread.scan1 = dev->thread.scan2; - dprintk("tvaudio thread scan start [%d]\n",dev->thread.scan1); + audio_dbg(1, "tvaudio thread scan start [%d]\n", + dev->thread.scan1); dev->tvaudio = NULL; saa_writeb(SAA7134_MONITOR_SELECT, 0xa0); @@ -519,7 +516,7 @@ static int tvaudio_thread(void *data) if (1 == nscan) { /* only one candidate -- skip scan ;) */ - dprintk("only one main carrier candidate - skipping scan\n"); + audio_dbg(1, "only one main carrier candidate - skipping scan\n"); max1 = 12345; carrier = default_carrier; } else { @@ -544,26 +541,24 @@ static int tvaudio_thread(void *data) if (0 != carrier && max1 > 2000 && max1 > max2*3) { /* found good carrier */ - dprintk("found %s main sound carrier @ %d.%03d MHz [%d/%d]\n", - dev->tvnorm->name, carrier/1000, carrier%1000, - max1, max2); + audio_dbg(1, "found %s main sound carrier @ %d.%03d MHz [%d/%d]\n", + dev->tvnorm->name, carrier/1000, carrier%1000, + max1, max2); dev->last_carrier = carrier; dev->automute = 0; } else if (0 != dev->last_carrier) { /* no carrier -- try last detected one as fallback */ carrier = dev->last_carrier; - dprintk("audio carrier scan failed, " - "using %d.%03d MHz [last detected]\n", - carrier/1000, carrier%1000); + audio_dbg(1, "audio carrier scan failed, using %d.%03d MHz [last detected]\n", + carrier/1000, carrier%1000); dev->automute = 1; } else { /* no carrier + no fallback -- use default */ carrier = default_carrier; - dprintk("audio carrier scan failed, " - "using %d.%03d MHz [default]\n", - carrier/1000, carrier%1000); + audio_dbg(1, "audio carrier scan failed, using %d.%03d MHz [default]\n", + carrier/1000, carrier%1000); dev->automute = 1; } tvaudio_setcarrier(dev,carrier,carrier); @@ -661,7 +656,7 @@ static inline int saa_dsp_reset_error_bit(struct saa7134_dev *dev) { int state = saa_readb(SAA7135_DSP_RWSTATE); if (unlikely(state & SAA7135_DSP_RWSTATE_ERR)) { - d2printk("%s: resetting error bit\n", dev->name); + audio_dbg(2, "%s: resetting error bit\n", dev->name); saa_writeb(SAA7135_DSP_RWCLEAR, SAA7135_DSP_RWCLEAR_RERR); } return 0; @@ -699,7 +694,7 @@ int saa_dsp_writel(struct saa7134_dev *dev, int reg, u32 value) { int err; - d2printk("dsp write reg 0x%x = 0x%06x\n",reg<<2,value); + audio_dbg(2, "dsp write reg 0x%x = 0x%06x\n", reg << 2, value); err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_WRR); if (err < 0) return err; @@ -786,14 +781,16 @@ static int tvaudio_thread_ddep(void *data) try_to_freeze(); dev->thread.scan1 = dev->thread.scan2; - dprintk("tvaudio thread scan start [%d]\n",dev->thread.scan1); + audio_dbg(1, "tvaudio thread scan start [%d]\n", + dev->thread.scan1); if (audio_ddep >= 0x04 && audio_ddep <= 0x0e) { /* insmod option override */ norms = (audio_ddep << 2) | 0x01; - dprintk("ddep override: %s\n",stdres[audio_ddep]); + audio_dbg(1, "ddep override: %s\n", + stdres[audio_ddep]); } else if (&card(dev).radio == dev->input) { - dprintk("FM Radio\n"); + audio_dbg(1, "FM Radio\n"); if (dev->tuner_type == TUNER_PHILIPS_TDA8290) { norms = (0x11 << 2) | 0x01; /* set IF frequency to 5.5 MHz */ @@ -816,12 +813,12 @@ static int tvaudio_thread_ddep(void *data) norms |= 0x10; if (0 == norms) norms = 0x7c; /* all */ - dprintk("scanning:%s%s%s%s%s\n", - (norms & 0x04) ? " B/G" : "", - (norms & 0x08) ? " D/K" : "", - (norms & 0x10) ? " L/L'" : "", - (norms & 0x20) ? " I" : "", - (norms & 0x40) ? " M" : ""); + audio_dbg(1, "scanning:%s%s%s%s%s\n", + (norms & 0x04) ? " B/G" : "", + (norms & 0x08) ? " D/K" : "", + (norms & 0x10) ? " L/L'" : "", + (norms & 0x20) ? " I" : "", + (norms & 0x40) ? " M" : ""); } /* kick automatic standard detection */ @@ -836,29 +833,28 @@ static int tvaudio_thread_ddep(void *data) goto restart; value = saa_readl(0x528 >> 2) & 0xffffff; - dprintk("tvaudio thread status: 0x%x [%s%s%s]\n", - value, stdres[value & 0x1f], - (value & 0x000020) ? ",stereo" : "", - (value & 0x000040) ? ",dual" : ""); - dprintk("detailed status: " - "%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s\n", - (value & 0x000080) ? " A2/EIAJ pilot tone " : "", - (value & 0x000100) ? " A2/EIAJ dual " : "", - (value & 0x000200) ? " A2/EIAJ stereo " : "", - (value & 0x000400) ? " A2/EIAJ noise mute " : "", - - (value & 0x000800) ? " BTSC/FM radio pilot " : "", - (value & 0x001000) ? " SAP carrier " : "", - (value & 0x002000) ? " BTSC stereo noise mute " : "", - (value & 0x004000) ? " SAP noise mute " : "", - (value & 0x008000) ? " VDSP " : "", - - (value & 0x010000) ? " NICST " : "", - (value & 0x020000) ? " NICDU " : "", - (value & 0x040000) ? " NICAM muted " : "", - (value & 0x080000) ? " NICAM reserve sound " : "", - - (value & 0x100000) ? " init done " : ""); + audio_dbg(1, "tvaudio thread status: 0x%x [%s%s%s]\n", + value, stdres[value & 0x1f], + (value & 0x000020) ? ",stereo" : "", + (value & 0x000040) ? ",dual" : ""); + audio_dbg(1, "detailed status: %s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s\n", + (value & 0x000080) ? " A2/EIAJ pilot tone " : "", + (value & 0x000100) ? " A2/EIAJ dual " : "", + (value & 0x000200) ? " A2/EIAJ stereo " : "", + (value & 0x000400) ? " A2/EIAJ noise mute " : "", + + (value & 0x000800) ? " BTSC/FM radio pilot " : "", + (value & 0x001000) ? " SAP carrier " : "", + (value & 0x002000) ? " BTSC stereo noise mute " : "", + (value & 0x004000) ? " SAP noise mute " : "", + (value & 0x008000) ? " VDSP " : "", + + (value & 0x010000) ? " NICST " : "", + (value & 0x020000) ? " NICDU " : "", + (value & 0x040000) ? " NICAM muted " : "", + (value & 0x080000) ? " NICAM reserve sound " : "", + + (value & 0x100000) ? " init done " : ""); } done: @@ -1061,7 +1057,7 @@ int saa7134_tvaudio_fini(struct saa7134_dev *dev) int saa7134_tvaudio_do_scan(struct saa7134_dev *dev) { if (dev->input->amux != TV) { - dprintk("sound IF not in use, skipping scan\n"); + audio_dbg(1, "sound IF not in use, skipping scan\n"); dev->automute = 0; saa7134_tvaudio_setmute(dev); } else if (dev->thread.thread) { -- cgit v1.2.3-59-g8ed1b From 630983b759eb1a92c30547470c8bd934a2c61fb9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 30 Apr 2015 08:52:35 -0300 Subject: [media] saa7134: change the debug macros for video and vbi rename the macro to vbi_dbg()/video_dbg() and use pr_fmt(), to be coherent with the other debug macro changes. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-vbi.c | 6 +++--- drivers/media/pci/saa7134/saa7134-video.c | 26 +++++++++++++------------- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7134/saa7134-vbi.c b/drivers/media/pci/saa7134/saa7134-vbi.c index 109c2ffeab93..face07bf420d 100644 --- a/drivers/media/pci/saa7134/saa7134-vbi.c +++ b/drivers/media/pci/saa7134/saa7134-vbi.c @@ -38,8 +38,8 @@ static unsigned int vbibufs = 4; module_param(vbibufs, int, 0444); MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32"); -#define dprintk(fmt, arg...) if (vbi_debug) \ - printk(KERN_DEBUG "%s/vbi: " fmt, dev->name , ## arg) +#define vbi_dbg(fmt, arg...) if (vbi_debug) \ + printk(KERN_DEBUG pr_fmt("vbi: " fmt), ## arg) /* ------------------------------------------------------------------ */ @@ -84,7 +84,7 @@ static int buffer_activate(struct saa7134_dev *dev, struct saa7134_dmaqueue *dmaq = buf->vb2.vb2_queue->drv_priv; unsigned long control, base; - dprintk("buffer_activate [%p]\n", buf); + vbi_dbg("buffer_activate [%p]\n", buf); buf->top_seen = 0; task_init(dev, buf, TASK_A); diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c index f7dcdccfc307..525ae6837fb3 100644 --- a/drivers/media/pci/saa7134/saa7134-video.c +++ b/drivers/media/pci/saa7134/saa7134-video.c @@ -52,8 +52,8 @@ module_param_string(secam, secam, sizeof(secam), 0644); MODULE_PARM_DESC(secam, "force SECAM variant, either DK,L or Lc"); -#define dprintk(fmt, arg...) if (video_debug&0x04) \ - printk(KERN_DEBUG "%s/video: " fmt, dev->name , ## arg) +#define video_dbg(fmt, arg...) if (video_debug & 0x04) \ + printk(KERN_DEBUG pr_fmt("video: " fmt), ## arg) /* ------------------------------------------------------------------ */ /* Defines for Video Output Port Register at address 0x191 */ @@ -385,7 +385,7 @@ static struct saa7134_format* format_by_fourcc(unsigned int fourcc) static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm) { - dprintk("set tv norm = %s\n",norm->name); + video_dbg("set tv norm = %s\n",norm->name); dev->tvnorm = norm; /* setup cropping */ @@ -407,7 +407,7 @@ static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm) static void video_mux(struct saa7134_dev *dev, int input) { - dprintk("video input = %d [%s]\n", input, card_in(dev, input).name); + video_dbg("video input = %d [%s]\n", input, card_in(dev, input).name); dev->ctl_input = input; set_tvnorm(dev, dev->tvnorm); saa7134_tvaudio_setinput(dev, &card_in(dev, input)); @@ -531,14 +531,14 @@ static void set_v_scale(struct saa7134_dev *dev, int task, int yscale) mirror = (dev->ctl_mirror) ? 0x02 : 0x00; if (yscale < 2048) { /* LPI */ - dprintk("yscale LPI yscale=%d\n",yscale); + video_dbg("yscale LPI yscale=%d\n",yscale); saa_writeb(SAA7134_V_FILTER(task), 0x00 | mirror); saa_writeb(SAA7134_LUMA_CONTRAST(task), 0x40); saa_writeb(SAA7134_CHROMA_SATURATION(task), 0x40); } else { /* ACM */ val = 0x40 * 1024 / yscale; - dprintk("yscale ACM yscale=%d val=0x%x\n",yscale,val); + video_dbg("yscale ACM yscale=%d val=0x%x\n",yscale,val); saa_writeb(SAA7134_V_FILTER(task), 0x01 | mirror); saa_writeb(SAA7134_LUMA_CONTRAST(task), val); saa_writeb(SAA7134_CHROMA_SATURATION(task), val); @@ -573,7 +573,7 @@ static void set_size(struct saa7134_dev *dev, int task, prescale = 1; xscale = 1024 * dev->crop_current.width / prescale / width; yscale = 512 * div * dev->crop_current.height / height; - dprintk("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale); + video_dbg("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale); set_h_prescale(dev,task,prescale); saa_writeb(SAA7134_H_SCALE_INC1(task), xscale & 0xff); saa_writeb(SAA7134_H_SCALE_INC2(task), xscale >> 8); @@ -615,7 +615,7 @@ static void set_cliplist(struct saa7134_dev *dev, int reg, saa_writeb(reg + 0, winbits); saa_writeb(reg + 2, cl[i].position & 0xff); saa_writeb(reg + 3, cl[i].position >> 8); - dprintk("clip: %s winbits=%02x pos=%d\n", + video_dbg("clip: %s winbits=%02x pos=%d\n", name,winbits,cl[i].position); reg += 8; } @@ -730,7 +730,7 @@ static int start_preview(struct saa7134_dev *dev) return err; dev->ovfield = dev->win.field; - dprintk("start_preview %dx%d+%d+%d %s field=%s\n", + video_dbg("start_preview %dx%d+%d+%d %s field=%s\n", dev->win.w.width, dev->win.w.height, dev->win.w.left, dev->win.w.top, dev->ovfmt->name, v4l2_field_names[dev->ovfield]); @@ -792,7 +792,7 @@ static int buffer_activate(struct saa7134_dev *dev, unsigned long base,control,bpl; unsigned long bpl_uv,lines_uv,base2,base3,tmp; /* planar */ - dprintk("buffer_activate buf=%p\n",buf); + video_dbg("buffer_activate buf=%p\n",buf); buf->top_seen = 0; set_size(dev, TASK_A, dev->width, dev->height, @@ -837,7 +837,7 @@ static int buffer_activate(struct saa7134_dev *dev, base3 = base2 + bpl_uv * lines_uv; if (dev->fmt->uvswap) tmp = base2, base2 = base3, base3 = tmp; - dprintk("uv: bpl=%ld lines=%ld base2/3=%ld/%ld\n", + video_dbg("uv: bpl=%ld lines=%ld base2/3=%ld/%ld\n", bpl_uv,lines_uv,base2,base3); if (V4L2_FIELD_HAS_BOTH(dev->field)) { /* interlaced */ @@ -1795,7 +1795,7 @@ static int saa7134_overlay(struct file *file, void *priv, unsigned int on) if (on) { if (saa7134_no_overlay > 0) { - dprintk("no_overlay\n"); + video_dbg("no_overlay\n"); return -EINVAL; } @@ -2184,7 +2184,7 @@ void saa7134_irq_video_signalchange(struct saa7134_dev *dev) st1 = saa_readb(SAA7134_STATUS_VIDEO1); st2 = saa_readb(SAA7134_STATUS_VIDEO2); - dprintk("DCSDT: pll: %s, sync: %s, norm: %s\n", + video_dbg("DCSDT: pll: %s, sync: %s, norm: %s\n", (st1 & 0x40) ? "not locked" : "locked", (st2 & 0x40) ? "no" : "yes", st[st1 & 0x03]); -- cgit v1.2.3-59-g8ed1b From 6be5b1a19a4abe1b3c66af0bde3d7e3ed3005faa Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 30 Apr 2015 09:02:03 -0300 Subject: [media] saa7134: change the debug macros for IR input Rename the macros to input_dbg() and ir_dbg(), using pr_fmt() on both, to be coherent with the other debug macro changes. The ir_dbg() also prints the IR name. I'm not sure if it is a good idea to keep both macros here, but merging them would require tests on different flavors of saaa7134-based boards. So, for now, let's keep both. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-input.c | 44 +++++++++++++++---------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c index 9406d5d7cdde..89f5fcf12722 100644 --- a/drivers/media/pci/saa7134/saa7134-input.c +++ b/drivers/media/pci/saa7134/saa7134-input.c @@ -41,10 +41,10 @@ static int pinnacle_remote; module_param(pinnacle_remote, int, 0644); /* Choose Pinnacle PCTV remote */ MODULE_PARM_DESC(pinnacle_remote, "Specify Pinnacle PCTV remote: 0=coloured, 1=grey (defaults to 0)"); -#define dprintk(fmt, arg...) if (ir_debug) \ - printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) -#define i2cdprintk(fmt, arg...) if (ir_debug) \ - printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg) +#define input_dbg(fmt, arg...) if (ir_debug) \ + printk(KERN_DEBUG pr_fmt("input: " fmt), ## arg) +#define ir_dbg(ir, fmt, arg...) if (ir_debug) \ + printk(KERN_DEBUG pr_fmt("ir %s: " fmt), ir->name, ## arg) /* Helper function for raw decoding at GPIO16 or GPIO18 */ static int saa7134_raw_decode_irq(struct saa7134_dev *dev); @@ -75,7 +75,7 @@ static int build_key(struct saa7134_dev *dev) } data = ir_extract_bits(gpio, ir->mask_keycode); - dprintk("build_key gpio=0x%x mask=0x%x data=%d\n", + input_dbg("build_key gpio=0x%x mask=0x%x data=%d\n", gpio, ir->mask_keycode, data); switch (dev->board) { @@ -119,7 +119,7 @@ static int get_key_flydvb_trio(struct IR_i2c *ir, enum rc_type *protocol, struct saa7134_dev *dev = ir->c->adapter->algo_data; if (dev == NULL) { - i2cdprintk("get_key_flydvb_trio: " + ir_dbg(ir, "get_key_flydvb_trio: " "ir->c->adapter->algo_data is NULL!\n"); return -EIO; } @@ -146,12 +146,12 @@ static int get_key_flydvb_trio(struct IR_i2c *ir, enum rc_type *protocol, msleep(10); continue; } - i2cdprintk("send wake up byte to pic16C505 (IR chip)" + ir_dbg(ir, "send wake up byte to pic16C505 (IR chip)" "failed %dx\n", attempt); return -EIO; } if (1 != i2c_master_recv(ir->c, &b, 1)) { - i2cdprintk("read error\n"); + ir_dbg(ir, "read error\n"); return -EIO; } @@ -170,7 +170,7 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, enum rc_type *protocol /* is needed to access GPIO. Used by the saa_readl macro. */ struct saa7134_dev *dev = ir->c->adapter->algo_data; if (dev == NULL) { - i2cdprintk("get_key_msi_tvanywhere_plus: " + ir_dbg(ir, "get_key_msi_tvanywhere_plus: " "ir->c->adapter->algo_data is NULL!\n"); return -EIO; } @@ -191,7 +191,7 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, enum rc_type *protocol /* GPIO says there is a button press. Get it. */ if (1 != i2c_master_recv(ir->c, &b, 1)) { - i2cdprintk("read error\n"); + ir_dbg(ir, "read error\n"); return -EIO; } @@ -202,7 +202,7 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, enum rc_type *protocol /* Button pressed */ - dprintk("get_key_msi_tvanywhere_plus: Key = 0x%02X\n", b); + input_dbg("get_key_msi_tvanywhere_plus: Key = 0x%02X\n", b); *protocol = RC_TYPE_UNKNOWN; *scancode = b; *toggle = 0; @@ -219,7 +219,7 @@ static int get_key_kworld_pc150u(struct IR_i2c *ir, enum rc_type *protocol, /* is needed to access GPIO. Used by the saa_readl macro. */ struct saa7134_dev *dev = ir->c->adapter->algo_data; if (dev == NULL) { - i2cdprintk("get_key_kworld_pc150u: " + ir_dbg(ir, "get_key_kworld_pc150u: " "ir->c->adapter->algo_data is NULL!\n"); return -EIO; } @@ -240,7 +240,7 @@ static int get_key_kworld_pc150u(struct IR_i2c *ir, enum rc_type *protocol, /* GPIO says there is a button press. Get it. */ if (1 != i2c_master_recv(ir->c, &b, 1)) { - i2cdprintk("read error\n"); + ir_dbg(ir, "read error\n"); return -EIO; } @@ -251,7 +251,7 @@ static int get_key_kworld_pc150u(struct IR_i2c *ir, enum rc_type *protocol, /* Button pressed */ - dprintk("get_key_kworld_pc150u: Key = 0x%02X\n", b); + input_dbg("get_key_kworld_pc150u: Key = 0x%02X\n", b); *protocol = RC_TYPE_UNKNOWN; *scancode = b; *toggle = 0; @@ -265,7 +265,7 @@ static int get_key_purpletv(struct IR_i2c *ir, enum rc_type *protocol, /* poll IR chip */ if (1 != i2c_master_recv(ir->c, &b, 1)) { - i2cdprintk("read error\n"); + ir_dbg(ir, "read error\n"); return -EIO; } @@ -334,7 +334,7 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, enum rc_type *protocol, ir->c->addr = 0x5a >> 1; if (12 != i2c_master_recv(ir->c, data, 12)) { - i2cdprintk("read error\n"); + ir_dbg(ir, "read error\n"); return -EIO; } @@ -359,7 +359,7 @@ static int get_key_pinnacle(struct IR_i2c *ir, enum rc_type *protocol, /* poll IR chip */ if (4 != i2c_master_recv(ir->c, b, 4)) { - i2cdprintk("read error\n"); + ir_dbg(ir, "read error\n"); return -EIO; } @@ -391,7 +391,7 @@ static int get_key_pinnacle(struct IR_i2c *ir, enum rc_type *protocol, *scancode = code; *toggle = 0; - i2cdprintk("Pinnacle PCTV key %02x\n", code); + ir_dbg(ir, "Pinnacle PCTV key %02x\n", code); return 1; } @@ -916,7 +916,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) int rc; if (disable_ir) { - dprintk("IR has been disabled, not probing for i2c remote\n"); + input_dbg("IR has been disabled, not probing for i2c remote\n"); return; } @@ -959,7 +959,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) an existing device. Weird... REVISIT: might no longer be needed */ rc = i2c_transfer(&dev->i2c_adap, &msg_msi, 1); - dprintk("probe 0x%02x @ %s: %s\n", + input_dbg("probe 0x%02x @ %s: %s\n", msg_msi.addr, dev->i2c_adap.name, (1 == rc) ? "yes" : "no"); break; @@ -974,7 +974,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) an existing device. Weird... REVISIT: might no longer be needed */ rc = i2c_transfer(&dev->i2c_adap, &msg_msi, 1); - dprintk("probe 0x%02x @ %s: %s\n", + input_dbg("probe 0x%02x @ %s: %s\n", msg_msi.addr, dev->i2c_adap.name, (1 == rc) ? "yes" : "no"); break; @@ -1019,7 +1019,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) info.addr = 0x0b; break; default: - dprintk("No I2C IR support for board %x\n", dev->board); + input_dbg("No I2C IR support for board %x\n", dev->board); return; } -- cgit v1.2.3-59-g8ed1b From 3e0051c5a40a5a29e1919361f45cd1e103d0b1fa Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 30 Apr 2015 09:15:08 -0300 Subject: [media] saa7134-i2c: simplify debug dump and use pr_info() Instead of implement its own hexdump logic, use the printk format, and convert to use pr_info(). Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-i2c.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7134/saa7134-i2c.c b/drivers/media/pci/saa7134/saa7134-i2c.c index b140143dba7d..ef3c33e3757d 100644 --- a/drivers/media/pci/saa7134/saa7134-i2c.c +++ b/drivers/media/pci/saa7134/saa7134-i2c.c @@ -369,13 +369,12 @@ saa7134_i2c_eeprom(struct saa7134_dev *dev, unsigned char *eedata, int len) dev->name,err); return -1; } - for (i = 0; i < len; i++) { - if (0 == (i % 16)) - pr_info("%s: i2c eeprom %02x:",dev->name,i); - printk(" %02x",eedata[i]); - if (15 == (i % 16)) - printk("\n"); + + for (i = 0; i < len; i+= 16) { + int size = (len - i) > 16 ? 16 : len - i; + pr_info("i2c eeprom %02x: %*ph\n", i, size, &eedata[i]); } + return 0; } -- cgit v1.2.3-59-g8ed1b From 2bb3e2eec50c4cc7e0aefc4ef4cc9a1c371038ae Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 30 Apr 2015 09:17:34 -0300 Subject: [media] saa7134: replace remaining occurences or printk() Instead of using printk(), use pr_foo() macros. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-i2c.c | 8 ++++---- drivers/media/pci/saa7134/saa7134-input.c | 3 +-- drivers/media/pci/saa7134/saa7134-tvaudio.c | 11 +++++------ 3 files changed, 10 insertions(+), 12 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7134/saa7134-i2c.c b/drivers/media/pci/saa7134/saa7134-i2c.c index ef3c33e3757d..d04fbdb49158 100644 --- a/drivers/media/pci/saa7134/saa7134-i2c.c +++ b/drivers/media/pci/saa7134/saa7134-i2c.c @@ -386,7 +386,7 @@ static char *i2c_devs[128] = { [ 0x5a >> 1 ] = "remote control", }; -static void do_i2c_scan(char *name, struct i2c_client *c) +static void do_i2c_scan(struct i2c_client *c) { unsigned char buf; int i,rc; @@ -396,8 +396,8 @@ static void do_i2c_scan(char *name, struct i2c_client *c) rc = i2c_master_recv(c,&buf,0); if (rc < 0) continue; - printk("%s: i2c scan: found device @ 0x%x [%s]\n", - name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); + pr_info("i2c scan: found device @ 0x%x [%s]\n", + i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); } } @@ -415,7 +415,7 @@ int saa7134_i2c_register(struct saa7134_dev *dev) saa7134_i2c_eeprom(dev,dev->eedata,sizeof(dev->eedata)); if (i2c_scan) - do_i2c_scan(dev->name,&dev->i2c_client); + do_i2c_scan(&dev->i2c_client); /* Instantiate the IR receiver device, if present */ saa7134_probe_i2c_ir(dev); diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c index 89f5fcf12722..c6036557b468 100644 --- a/drivers/media/pci/saa7134/saa7134-input.c +++ b/drivers/media/pci/saa7134/saa7134-input.c @@ -831,8 +831,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) break; } if (NULL == ir_codes) { - printk("%s: Oops: IR config error [card=%d]\n", - dev->name, dev->board); + pr_err("Oops: IR config error [card=%d]\n", dev->board); return -ENODEV; } diff --git a/drivers/media/pci/saa7134/saa7134-tvaudio.c b/drivers/media/pci/saa7134/saa7134-tvaudio.c index 360f447bd74d..6320b64d3528 100644 --- a/drivers/media/pci/saa7134/saa7134-tvaudio.c +++ b/drivers/media/pci/saa7134/saa7134-tvaudio.c @@ -674,12 +674,11 @@ static inline int saa_dsp_wait_bit(struct saa7134_dev *dev, int bit) } while (0 == (state & bit)) { if (unlikely(0 == count)) { - printk("%s: dsp access wait timeout [bit=%s]\n", - dev->name, - (bit & SAA7135_DSP_RWSTATE_WRR) ? "WRR" : - (bit & SAA7135_DSP_RWSTATE_RDB) ? "RDB" : - (bit & SAA7135_DSP_RWSTATE_IDA) ? "IDA" : - "???"); + pr_err("dsp access wait timeout [bit=%s]\n", + (bit & SAA7135_DSP_RWSTATE_WRR) ? "WRR" : + (bit & SAA7135_DSP_RWSTATE_RDB) ? "RDB" : + (bit & SAA7135_DSP_RWSTATE_IDA) ? "IDA" : + "???"); return -EIO; } saa_wait(DSP_DELAY); -- cgit v1.2.3-59-g8ed1b From 45f38cb3b80311ade3c87000f7d7a8f6ebd60a43 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 13 May 2015 14:09:25 -0300 Subject: [media] saa7134: avoid complex macro warnings The debug macros are not properly defined, as they generate warnings like: ERROR: Macros with complex values should be enclosed in parentheses +#define core_dbg(fmt, arg...) if (core_debug) \ + printk(KERN_DEBUG pr_fmt("core: " fmt), ## arg) Use do { } while (0) for those macros. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-core.c | 14 +++++++++----- drivers/media/pci/saa7134/saa7134-i2c.c | 14 +++++++++----- drivers/media/pci/saa7134/saa7134-input.c | 12 ++++++++---- drivers/media/pci/saa7134/saa7134-ts.c | 6 ++++-- drivers/media/pci/saa7134/saa7134-tvaudio.c | 6 ++++-- drivers/media/pci/saa7134/saa7134-vbi.c | 6 ++++-- drivers/media/pci/saa7134/saa7134-video.c | 6 ++++-- 7 files changed, 42 insertions(+), 22 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c index e88e4ec8c0ee..02a08770507d 100644 --- a/drivers/media/pci/saa7134/saa7134-core.c +++ b/drivers/media/pci/saa7134/saa7134-core.c @@ -102,11 +102,15 @@ static unsigned int saa7134_devcount; int (*saa7134_dmasound_init)(struct saa7134_dev *dev); int (*saa7134_dmasound_exit)(struct saa7134_dev *dev); -#define core_dbg(fmt, arg...) if (core_debug) \ - printk(KERN_DEBUG pr_fmt("core: " fmt), ## arg) - -#define irq_dbg(level, fmt, arg...) if (irq_debug > level) \ - printk(KERN_DEBUG pr_fmt("irq: " fmt), ## arg) +#define core_dbg(fmt, arg...) do { \ + if (core_debug) \ + printk(KERN_DEBUG pr_fmt("core: " fmt), ## arg); \ + } while (0) + +#define irq_dbg(level, fmt, arg...) do {\ + if (irq_debug > level) \ + printk(KERN_DEBUG pr_fmt("irq: " fmt), ## arg); \ + } while (0) void saa7134_track_gpio(struct saa7134_dev *dev, char *msg) { diff --git a/drivers/media/pci/saa7134/saa7134-i2c.c b/drivers/media/pci/saa7134/saa7134-i2c.c index d04fbdb49158..b90434b41efe 100644 --- a/drivers/media/pci/saa7134/saa7134-i2c.c +++ b/drivers/media/pci/saa7134/saa7134-i2c.c @@ -41,11 +41,15 @@ static unsigned int i2c_scan; module_param(i2c_scan, int, 0444); MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); -#define i2c_dbg(level, fmt, arg...) if (i2c_debug == level) \ - printk(KERN_DEBUG pr_fmt("i2c: " fmt), ## arg) - -#define i2c_cont(level, fmt, arg...) if (i2c_debug == level) \ - pr_cont(fmt, ## arg) +#define i2c_dbg(level, fmt, arg...) do { \ + if (i2c_debug == level) \ + printk(KERN_DEBUG pr_fmt("i2c: " fmt), ## arg); \ + } while (0) + +#define i2c_cont(level, fmt, arg...) do { \ + if (i2c_debug == level) \ + pr_cont(fmt, ## arg); \ + } while (0) #define I2C_WAIT_DELAY 32 #define I2C_WAIT_RETRY 16 diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c index c6036557b468..e92bcfe9bbcb 100644 --- a/drivers/media/pci/saa7134/saa7134-input.c +++ b/drivers/media/pci/saa7134/saa7134-input.c @@ -41,10 +41,14 @@ static int pinnacle_remote; module_param(pinnacle_remote, int, 0644); /* Choose Pinnacle PCTV remote */ MODULE_PARM_DESC(pinnacle_remote, "Specify Pinnacle PCTV remote: 0=coloured, 1=grey (defaults to 0)"); -#define input_dbg(fmt, arg...) if (ir_debug) \ - printk(KERN_DEBUG pr_fmt("input: " fmt), ## arg) -#define ir_dbg(ir, fmt, arg...) if (ir_debug) \ - printk(KERN_DEBUG pr_fmt("ir %s: " fmt), ir->name, ## arg) +#define input_dbg(fmt, arg...) do { \ + if (ir_debug) \ + printk(KERN_DEBUG pr_fmt("input: " fmt), ## arg); \ + } while (0) +#define ir_dbg(ir, fmt, arg...) do { \ + if (ir_debug) \ + printk(KERN_DEBUG pr_fmt("ir %s: " fmt), ir->name, ## arg); \ + } while (0) /* Helper function for raw decoding at GPIO16 or GPIO18 */ static int saa7134_raw_decode_irq(struct saa7134_dev *dev); diff --git a/drivers/media/pci/saa7134/saa7134-ts.c b/drivers/media/pci/saa7134/saa7134-ts.c index 5d7c4afac8e6..07ca32f1b6d9 100644 --- a/drivers/media/pci/saa7134/saa7134-ts.c +++ b/drivers/media/pci/saa7134/saa7134-ts.c @@ -35,8 +35,10 @@ static unsigned int ts_debug; module_param(ts_debug, int, 0644); MODULE_PARM_DESC(ts_debug,"enable debug messages [ts]"); -#define ts_dbg(fmt, arg...) if (ts_debug) \ - printk(KERN_DEBUG pr_fmt("ts: " fmt), ## arg) +#define ts_dbg(fmt, arg...) do { \ + if (ts_debug) \ + printk(KERN_DEBUG pr_fmt("ts: " fmt), ## arg); \ + } while (0) /* ------------------------------------------------------------------ */ static int buffer_activate(struct saa7134_dev *dev, diff --git a/drivers/media/pci/saa7134/saa7134-tvaudio.c b/drivers/media/pci/saa7134/saa7134-tvaudio.c index 6320b64d3528..1a960a1b07b5 100644 --- a/drivers/media/pci/saa7134/saa7134-tvaudio.c +++ b/drivers/media/pci/saa7134/saa7134-tvaudio.c @@ -49,8 +49,10 @@ static int audio_clock_tweak; module_param(audio_clock_tweak, int, 0644); MODULE_PARM_DESC(audio_clock_tweak, "Audio clock tick fine tuning for cards with audio crystal that's slightly off (range [-1024 .. 1024])"); -#define audio_dbg(level, fmt, arg...) if (audio_debug >= level) \ - printk(KERN_DEBUG pr_fmt("audio: " fmt), ## arg) +#define audio_dbg(level, fmt, arg...) do { \ + if (audio_debug >= level) \ + printk(KERN_DEBUG pr_fmt("audio: " fmt), ## arg); \ + } while (0) /* msecs */ #define SCAN_INITIAL_DELAY 1000 diff --git a/drivers/media/pci/saa7134/saa7134-vbi.c b/drivers/media/pci/saa7134/saa7134-vbi.c index face07bf420d..4d36586ad752 100644 --- a/drivers/media/pci/saa7134/saa7134-vbi.c +++ b/drivers/media/pci/saa7134/saa7134-vbi.c @@ -38,8 +38,10 @@ static unsigned int vbibufs = 4; module_param(vbibufs, int, 0444); MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32"); -#define vbi_dbg(fmt, arg...) if (vbi_debug) \ - printk(KERN_DEBUG pr_fmt("vbi: " fmt), ## arg) +#define vbi_dbg(fmt, arg...) do { \ + if (vbi_debug) \ + printk(KERN_DEBUG pr_fmt("vbi: " fmt), ## arg); \ + } while (0) /* ------------------------------------------------------------------ */ diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c index 525ae6837fb3..f874b0c9fe4a 100644 --- a/drivers/media/pci/saa7134/saa7134-video.c +++ b/drivers/media/pci/saa7134/saa7134-video.c @@ -52,8 +52,10 @@ module_param_string(secam, secam, sizeof(secam), 0644); MODULE_PARM_DESC(secam, "force SECAM variant, either DK,L or Lc"); -#define video_dbg(fmt, arg...) if (video_debug & 0x04) \ - printk(KERN_DEBUG pr_fmt("video: " fmt), ## arg) +#define video_dbg(fmt, arg...) do { \ + if (video_debug & 0x04) \ + printk(KERN_DEBUG pr_fmt("video: " fmt), ## arg); \ + } while (0) /* ------------------------------------------------------------------ */ /* Defines for Video Output Port Register at address 0x191 */ -- cgit v1.2.3-59-g8ed1b From 6139ebc65807e6d3bf60128cc42e85bcb7f578ba Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 13 May 2015 14:09:42 -0300 Subject: [media] saa7134: fix CodingStyle issues on the lines touched by pr_foo refactor Several lines touched by the pr_foo refactoring patches are not following the Linux Coding style. While we won't be fixing the style globally at the driver, we should, at least, fix on the lines we touched. Basically, this patch add (or remove) whitespaces and blank lines where needed. No functional changes. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-alsa.c | 9 ++++++--- drivers/media/pci/saa7134/saa7134-cards.c | 10 ++++++---- drivers/media/pci/saa7134/saa7134-core.c | 13 +++++++------ drivers/media/pci/saa7134/saa7134-dvb.c | 27 ++++++++++++++++++--------- drivers/media/pci/saa7134/saa7134-empress.c | 4 ++-- drivers/media/pci/saa7134/saa7134-i2c.c | 5 +++-- drivers/media/pci/saa7134/saa7134-ts.c | 6 +++--- drivers/media/pci/saa7134/saa7134-tvaudio.c | 7 ++++--- drivers/media/pci/saa7134/saa7134-video.c | 11 ++++++----- 9 files changed, 55 insertions(+), 37 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7134/saa7134-alsa.c b/drivers/media/pci/saa7134/saa7134-alsa.c index 4199fbf9bc44..1d2c310ce838 100644 --- a/drivers/media/pci/saa7134/saa7134-alsa.c +++ b/drivers/media/pci/saa7134/saa7134-alsa.c @@ -161,7 +161,8 @@ static void saa7134_irq_alsa_done(struct saa7134_dev *dev, } if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) { - pr_debug("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count, + pr_debug("irq: overrun [full=%d/%d] - Blocks in %d\n", + dev->dmasound.read_count, dev->dmasound.bufsize, dev->dmasound.blocks); spin_unlock(&dev->slock); snd_pcm_stop_xrun(dev->dmasound.substream); @@ -173,7 +174,8 @@ static void saa7134_irq_alsa_done(struct saa7134_dev *dev, saa_writel(reg,next_blk * dev->dmasound.blksize); pr_debug("irq: ok, %s, next_blk=%d, addr=%x, blocks=%u, size=%u, read=%u\n", (status & 0x10000000) ? "even" : "odd ", next_blk, - next_blk * dev->dmasound.blksize, dev->dmasound.blocks, dev->dmasound.blksize, dev->dmasound.read_count); + next_blk * dev->dmasound.blksize, dev->dmasound.blocks, + dev->dmasound.blksize, dev->dmasound.read_count); /* update status & wake waiting readers */ dev->dmasound.dma_blk = (dev->dmasound.dma_blk + 1) % dev->dmasound.blocks; @@ -1186,7 +1188,8 @@ static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum) sprintf(card->longname, "%s at 0x%lx irq %d", chip->dev->name, chip->iobase, chip->irq); - pr_info("%s/alsa: %s registered as card %d\n",dev->name,card->longname,index[devnum]); + pr_info("%s/alsa: %s registered as card %d\n", + dev->name, card->longname, index[devnum]); if ((err = snd_card_register(card)) == 0) { snd_saa7134_cards[devnum] = card; diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c index abbeeb923114..9fac6a9b7937 100644 --- a/drivers/media/pci/saa7134/saa7134-cards.c +++ b/drivers/media/pci/saa7134/saa7134-cards.c @@ -7516,7 +7516,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) pr_warn("%s: seems there are two different versions of the MD5044\n" "%s: (with the same ID) out there. If sound doesn't work for\n" "%s: you try the audio_clock_override=0x200000 insmod option.\n", - dev->name,dev->name,dev->name); + dev->name, dev->name, dev->name); break; case SAA7134_BOARD_CINERGY400_CARDBUS: /* power-up tuner chip */ @@ -7644,7 +7644,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) pr_warn("%s: %s: dual saa713x broadcast decoders\n" "%s: Sorry, none of the inputs to this chip are supported yet.\n" "%s: Dual decoder functionality is disabled for now, use the other chip.\n", - dev->name,card(dev).name,dev->name,dev->name); + dev->name, card(dev).name, dev->name, dev->name); break; case SAA7134_BOARD_AVERMEDIA_M102: /* enable tuner */ @@ -7826,7 +7826,8 @@ int saa7134_board_init2(struct saa7134_dev *dev) dev->tuner_type = TUNER_PHILIPS_FM1216ME_MK3; break; default: - pr_err("%s Can't determine tuner type %x from EEPROM\n", dev->name, tuner_t); + pr_err("%s Can't determine tuner type %x from EEPROM\n", + dev->name, tuner_t); } } else if ((data[1] != 0) && (data[1] != 0xff)) { /* new config structure */ @@ -7847,7 +7848,8 @@ int saa7134_board_init2(struct saa7134_dev *dev) dev->name); break; default: - pr_err("%s Can't determine tuner type %x from EEPROM\n", dev->name, tuner_t); + pr_err("%s Can't determine tuner type %x from EEPROM\n", + dev->name, tuner_t); } } else { pr_err("%s unexpected config structure\n", dev->name); diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c index 02a08770507d..72d7f992375e 100644 --- a/drivers/media/pci/saa7134/saa7134-core.c +++ b/drivers/media/pci/saa7134/saa7134-core.c @@ -134,7 +134,8 @@ void saa7134_set_gpio(struct saa7134_dev *dev, int bit_no, int value) index = 1 << bit_no; switch (value) { case 0: /* static value */ - case 1: core_dbg("setting GPIO%d to static %d\n", bit_no, value); + case 1: + core_dbg("setting GPIO%d to static %d\n", bit_no, value); /* turn sync mode off if necessary */ if (index & 0x00c00000) saa_andorb(SAA7134_VIDEO_PORT_CTRL6, 0x0f, 0x00); @@ -503,11 +504,11 @@ static void print_irqstatus(struct saa7134_dev *dev, int loop, unsigned int i; irq_dbg(1, "[%d,%ld]: r=0x%lx s=0x%02lx", - loop, jiffies, report,status); + loop, jiffies, report, status); for (i = 0; i < IRQBITS; i++) { if (!(report & (1 << i))) continue; - pr_cont(" %s",irqbits[i]); + pr_cont(" %s", irqbits[i]); } if (report & SAA7134_IRQ_REPORT_DONE_RA0) { pr_cont(" | RA0=%s,%s,%s,%ld", @@ -543,7 +544,7 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id) } if (0 == report) { - irq_dbg(2,"no (more) work\n"); + irq_dbg(2, "no (more) work\n"); goto out; } @@ -909,7 +910,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, if (pci_pci_problems & PCIPCI_VIAETBF) pr_info("%s: quirk: PCIPCI_VIAETBF\n", dev->name); if (pci_pci_problems & PCIPCI_VSFX) - pr_info("%s: quirk: PCIPCI_VSFX\n",dev->name); + pr_info("%s: quirk: PCIPCI_VSFX\n", dev->name); #ifdef PCIPCI_ALIMAGIK if (pci_pci_problems & PCIPCI_ALIMAGIK) { pr_info("%s: quirk: PCIPCI_ALIMAGIK -- latency fixup\n", @@ -1209,7 +1210,7 @@ static int saa7134_buffer_requeue(struct saa7134_dev *dev, if (!buf) return 0; - core_dbg("buffer_requeue : resending active buffers \n"); + core_dbg("buffer_requeue : resending active buffer\n"); if (!list_empty(&q->queue)) next = list_entry(q->queue.next, struct saa7134_buf, diff --git a/drivers/media/pci/saa7134/saa7134-dvb.c b/drivers/media/pci/saa7134/saa7134-dvb.c index 7edb49729489..d47fb22e12f2 100644 --- a/drivers/media/pci/saa7134/saa7134-dvb.c +++ b/drivers/media/pci/saa7134/saa7134-dvb.c @@ -558,11 +558,14 @@ static int philips_tda827x_tuner_init(struct dvb_frontend *fe) struct tda1004x_state *state = fe->demodulator_priv; switch (state->config->antenna_switch) { - case 0: break; - case 1: pr_debug("setting GPIO21 to 0 (TV antenna?)\n"); + case 0: + break; + case 1: + pr_debug("setting GPIO21 to 0 (TV antenna?)\n"); saa7134_set_gpio(dev, 21, 0); break; - case 2: pr_debug("setting GPIO21 to 1 (Radio antenna?)\n"); + case 2: + pr_debug("setting GPIO21 to 1 (Radio antenna?)\n"); saa7134_set_gpio(dev, 21, 1); break; } @@ -575,11 +578,14 @@ static int philips_tda827x_tuner_sleep(struct dvb_frontend *fe) struct tda1004x_state *state = fe->demodulator_priv; switch (state->config->antenna_switch) { - case 0: break; - case 1: pr_debug("setting GPIO21 to 1 (Radio antenna?)\n"); + case 0: + break; + case 1: + pr_debug("setting GPIO21 to 1 (Radio antenna?)\n"); saa7134_set_gpio(dev, 21, 1); break; - case 2: pr_debug("setting GPIO21 to 0 (TV antenna?)\n"); + case 2: + pr_debug("setting GPIO21 to 0 (TV antenna?)\n"); saa7134_set_gpio(dev, 21, 0); break; } @@ -1029,7 +1035,8 @@ static int md8800_set_voltage2(struct dvb_frontend *fe, fe_sec_voltage_t voltage static int md8800_set_high_voltage2(struct dvb_frontend *fe, long arg) { - pr_warn("%s: sorry can't set high LNB supply voltage from here\n", __func__); + pr_warn("%s: sorry can't set high LNB supply voltage from here\n", + __func__); return -EIO; } @@ -1388,13 +1395,15 @@ static int dvb_init(struct saa7134_dev *dev) if (fe0->dvb.frontend) { if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x63, &dev->i2c_adap, 0) == NULL) { - pr_warn("%s: Lifeview Trio, No tda826x found!\n", __func__); + pr_warn("%s: Lifeview Trio, No tda826x found!\n", + __func__); goto detach_frontend; } if (dvb_attach(isl6421_attach, fe0->dvb.frontend, &dev->i2c_adap, 0x08, 0, 0, false) == NULL) { - pr_warn("%s: Lifeview Trio, No ISL6421 found!\n", __func__); + pr_warn("%s: Lifeview Trio, No ISL6421 found!\n", + __func__); goto detach_frontend; } } diff --git a/drivers/media/pci/saa7134/saa7134-empress.c b/drivers/media/pci/saa7134/saa7134-empress.c index 86ab17bbc444..56b932c97196 100644 --- a/drivers/media/pci/saa7134/saa7134-empress.c +++ b/drivers/media/pci/saa7134/saa7134-empress.c @@ -256,7 +256,7 @@ static int empress_init(struct saa7134_dev *dev) struct vb2_queue *q; int err; - pr_debug("%s: %s\n",dev->name,__func__); + pr_debug("%s: %s\n", dev->name, __func__); dev->empress_dev = video_device_alloc(); if (NULL == dev->empress_dev) return -ENOMEM; @@ -318,7 +318,7 @@ static int empress_init(struct saa7134_dev *dev) static int empress_fini(struct saa7134_dev *dev) { - pr_debug("%s: %s\n",dev->name,__func__); + pr_debug("%s: %s\n", dev->name, __func__); if (NULL == dev->empress_dev) return 0; diff --git a/drivers/media/pci/saa7134/saa7134-i2c.c b/drivers/media/pci/saa7134/saa7134-i2c.c index b90434b41efe..8ef6399d794f 100644 --- a/drivers/media/pci/saa7134/saa7134-i2c.c +++ b/drivers/media/pci/saa7134/saa7134-i2c.c @@ -267,7 +267,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap, * needed to talk to the mt352 demux * thanks to pinnacle for the hint */ int quirk = 0xfe; - i2c_cont(1, " [%02x quirk]",quirk); + i2c_cont(1, " [%02x quirk]", quirk); i2c_send_byte(dev,START,quirk); i2c_recv_byte(dev); } @@ -374,8 +374,9 @@ saa7134_i2c_eeprom(struct saa7134_dev *dev, unsigned char *eedata, int len) return -1; } - for (i = 0; i < len; i+= 16) { + for (i = 0; i < len; i += 16) { int size = (len - i) > 16 ? 16 : len - i; + pr_info("i2c eeprom %02x: %*ph\n", i, size, &eedata[i]); } diff --git a/drivers/media/pci/saa7134/saa7134-ts.c b/drivers/media/pci/saa7134/saa7134-ts.c index 07ca32f1b6d9..4b202fa5fbc4 100644 --- a/drivers/media/pci/saa7134/saa7134-ts.c +++ b/drivers/media/pci/saa7134/saa7134-ts.c @@ -46,7 +46,7 @@ static int buffer_activate(struct saa7134_dev *dev, struct saa7134_buf *next) { - ts_dbg("buffer_activate [%p]",buf); + ts_dbg("buffer_activate [%p]", buf); buf->top_seen = 0; if (!dev->ts_started) @@ -55,12 +55,12 @@ static int buffer_activate(struct saa7134_dev *dev, if (NULL == next) next = buf; if (V4L2_FIELD_TOP == dev->ts_field) { - ts_dbg("- [top] buf=%p next=%p\n",buf,next); + ts_dbg("- [top] buf=%p next=%p\n", buf, next); saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(buf)); saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(next)); dev->ts_field = V4L2_FIELD_BOTTOM; } else { - ts_dbg("- [bottom] buf=%p next=%p\n",buf,next); + ts_dbg("- [bottom] buf=%p next=%p\n", buf, next); saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next)); saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf)); dev->ts_field = V4L2_FIELD_TOP; diff --git a/drivers/media/pci/saa7134/saa7134-tvaudio.c b/drivers/media/pci/saa7134/saa7134-tvaudio.c index 1a960a1b07b5..21a579309575 100644 --- a/drivers/media/pci/saa7134/saa7134-tvaudio.c +++ b/drivers/media/pci/saa7134/saa7134-tvaudio.c @@ -347,9 +347,9 @@ static int tvaudio_checkcarrier(struct saa7134_dev *dev, struct mainscan *scan) return -1; value = saa_readl(SAA7134_LEVEL_READOUT1 >> 2); if (0 == i) - pr_cont(" # %6d # ",value >> 16); + pr_cont(" # %6d # ", value >> 16); else - pr_cont(" %6d",value >> 16); + pr_cont(" %6d", value >> 16); } pr_cont("\n"); } @@ -404,7 +404,8 @@ static int tvaudio_getstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *au audio_dbg(1, "getstereo: nicam=0x%x\n", nicam); if (nicam & 0x1) { nicam_status = saa_readb(SAA7134_NICAM_STATUS); - audio_dbg(1, "getstereo: nicam_status=0x%x\n", nicam_status); + audio_dbg(1, "getstereo: nicam_status=0x%x\n", + nicam_status); switch (nicam_status & 0x03) { case 0x01: diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c index f874b0c9fe4a..035039cfae6d 100644 --- a/drivers/media/pci/saa7134/saa7134-video.c +++ b/drivers/media/pci/saa7134/saa7134-video.c @@ -387,7 +387,7 @@ static struct saa7134_format* format_by_fourcc(unsigned int fourcc) static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm) { - video_dbg("set tv norm = %s\n",norm->name); + video_dbg("set tv norm = %s\n", norm->name); dev->tvnorm = norm; /* setup cropping */ @@ -533,14 +533,14 @@ static void set_v_scale(struct saa7134_dev *dev, int task, int yscale) mirror = (dev->ctl_mirror) ? 0x02 : 0x00; if (yscale < 2048) { /* LPI */ - video_dbg("yscale LPI yscale=%d\n",yscale); + video_dbg("yscale LPI yscale=%d\n", yscale); saa_writeb(SAA7134_V_FILTER(task), 0x00 | mirror); saa_writeb(SAA7134_LUMA_CONTRAST(task), 0x40); saa_writeb(SAA7134_CHROMA_SATURATION(task), 0x40); } else { /* ACM */ val = 0x40 * 1024 / yscale; - video_dbg("yscale ACM yscale=%d val=0x%x\n",yscale,val); + video_dbg("yscale ACM yscale=%d val=0x%x\n", yscale, val); saa_writeb(SAA7134_V_FILTER(task), 0x01 | mirror); saa_writeb(SAA7134_LUMA_CONTRAST(task), val); saa_writeb(SAA7134_CHROMA_SATURATION(task), val); @@ -575,7 +575,8 @@ static void set_size(struct saa7134_dev *dev, int task, prescale = 1; xscale = 1024 * dev->crop_current.width / prescale / width; yscale = 512 * div * dev->crop_current.height / height; - video_dbg("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale); + video_dbg("prescale=%d xscale=%d yscale=%d\n", + prescale, xscale, yscale); set_h_prescale(dev,task,prescale); saa_writeb(SAA7134_H_SCALE_INC1(task), xscale & 0xff); saa_writeb(SAA7134_H_SCALE_INC2(task), xscale >> 8); @@ -794,7 +795,7 @@ static int buffer_activate(struct saa7134_dev *dev, unsigned long base,control,bpl; unsigned long bpl_uv,lines_uv,base2,base3,tmp; /* planar */ - video_dbg("buffer_activate buf=%p\n",buf); + video_dbg("buffer_activate buf=%p\n", buf); buf->top_seen = 0; set_size(dev, TASK_A, dev->width, dev->height, -- cgit v1.2.3-59-g8ed1b From 2aae557e1d690b401cf9d5abac5015fac26f3f6c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 10 Apr 2015 17:30:14 -0300 Subject: [media] exynos4_is: exynos4-fimc requires i2c Without i2c, we can get a build error: drivers/media/platform/exynos4-is/fimc-is-i2c.c: In function 'fimc_is_i2c_probe': drivers/media/platform/exynos4-is/fimc-is-i2c.c:58:8: error: implicit declaration of function 'i2c_add_adapter' [-Werror=implicit-function-declaration] The dependency already exists for exynos-fimc-lite and s5p-fimc, but is missing for exynos4-fimc. Signed-off-by: Arnd Bergmann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos4-is/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/platform/exynos4-is/Kconfig b/drivers/media/platform/exynos4-is/Kconfig index b7b2e472240a..40423c6c5324 100644 --- a/drivers/media/platform/exynos4-is/Kconfig +++ b/drivers/media/platform/exynos4-is/Kconfig @@ -57,6 +57,7 @@ endif config VIDEO_EXYNOS4_FIMC_IS tristate "EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver" + depends on I2C depends on HAS_DMA select VIDEOBUF2_DMA_CONTIG depends on OF -- cgit v1.2.3-59-g8ed1b From 0fd355c8bf8eaafdcb9617877297e74c43213126 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 10 Apr 2015 17:22:08 -0300 Subject: [media] R820T tuner needs CONFIG_BITREVERSE In a rarely hit randconfig case, the r820t tuner driver can get built when CONFIG_BITREVERSE is not selected by any other driver, resulting in this error: drivers/built-in.o: In function `r820t_read.constprop.3': :(.text+0xa0594): undefined reference to `byte_rev_table' For consistency, this adds the 'select BITREVERSE' that all other similar drivers have. Signed-off-by: Arnd Bergmann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig index 983510d282f6..db4caf2b4669 100644 --- a/drivers/media/tuners/Kconfig +++ b/drivers/media/tuners/Kconfig @@ -258,6 +258,7 @@ config MEDIA_TUNER_R820T tristate "Rafael Micro R820T silicon tuner" depends on MEDIA_SUPPORT && I2C default m if !MEDIA_SUBDRV_AUTOSELECT + select BITREVERSE help Rafael Micro R820T silicon tuner driver. -- cgit v1.2.3-59-g8ed1b From 3ea0f28559076982ae02935c27ea1a58dece65ab Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 14 Apr 2015 15:21:39 -0300 Subject: [media] ir-hix5hd2: Fix build warning Building for avr32 leads the following build warning: drivers/media/rc/ir-hix5hd2.c:221: warning: passing argument 1 of 'IS_ERR' discards qualifiers from pointer target type drivers/media/rc/ir-hix5hd2.c:222: warning: passing argument 1 of 'PTR_ERR' discards qualifiers from pointer target type devm_ioremap_resource() returns void __iomem *, so change 'base' definition accordingly. Reported-by: kbuild test robot Signed-off-by: Fabio Estevam Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/ir-hix5hd2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/rc/ir-hix5hd2.c b/drivers/media/rc/ir-hix5hd2.c index 838e29e3fd69..1c087cb76815 100644 --- a/drivers/media/rc/ir-hix5hd2.c +++ b/drivers/media/rc/ir-hix5hd2.c @@ -63,7 +63,7 @@ struct hix5hd2_ir_priv { int irq; - void volatile __iomem *base; + void __iomem *base; struct device *dev; struct rc_dev *rdev; struct regmap *regmap; @@ -213,8 +213,8 @@ static int hix5hd2_ir_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->base = devm_ioremap_resource(dev, res); - if (IS_ERR((__force void *)priv->base)) - return PTR_ERR((__force void *)priv->base); + if (IS_ERR(priv->base)) + return PTR_ERR(priv->base); priv->irq = platform_get_irq(pdev, 0); if (priv->irq < 0) { -- cgit v1.2.3-59-g8ed1b From 2235cf63400928a2deeccf65735e611a2d8aae30 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 14 Apr 2015 16:24:15 -0300 Subject: [media] st_rc: fix build warning Building for avr32 leads the following build warning: drivers/media/rc/st_rc.c:270: warning: passing argument 1 of 'IS_ERR' discards qualifiers from pointer target type drivers/media/rc/st_rc.c:271: warning: passing argument 1 of 'PTR_ERR' discards qualifiers from pointer target type devm_ioremap_resource() returns void __iomem *, so change 'base' and 'rx_base' definitions accordingly. Reported-by: kbuild test robot Signed-off-by: Fabio Estevam Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/st_rc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c index 50ea09da7739..979b40561b3a 100644 --- a/drivers/media/rc/st_rc.c +++ b/drivers/media/rc/st_rc.c @@ -22,8 +22,8 @@ struct st_rc_device { int irq; int irq_wake; struct clk *sys_clock; - volatile void __iomem *base; /* Register base address */ - volatile void __iomem *rx_base;/* RX Register base address */ + void __iomem *base; /* Register base address */ + void __iomem *rx_base;/* RX Register base address */ struct rc_dev *rdev; bool overclocking; int sample_mult; @@ -267,8 +267,8 @@ static int st_rc_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); rc_dev->base = devm_ioremap_resource(dev, res); - if (IS_ERR((__force void *)rc_dev->base)) { - ret = PTR_ERR((__force void *)rc_dev->base); + if (IS_ERR(rc_dev->base)) { + ret = PTR_ERR(rc_dev->base); goto err; } -- cgit v1.2.3-59-g8ed1b From 550f45bc83e7fb4ff454516c20ccfa674f771e37 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 21 Apr 2015 06:31:10 -0300 Subject: [media] v4l: xilinx: harmless buffer overflow My static checker warns that the name of the port can be 15 characters when you consider the NUL terminator and that's one more than the 14 characters in name[]. Maybe it's an off-by-one? It's unlikely that we hit the limit and even if we do the overflow will only affect one of the two bytes of padding so it's harmless. Still let's fix it and also change the sprintf() to snprintf(). Signed-off-by: Dan Carpenter Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/xilinx/xilinx-dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index efde88adf624..98e50e446d57 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -653,7 +653,7 @@ static const struct v4l2_file_operations xvip_dma_fops = { int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma, enum v4l2_buf_type type, unsigned int port) { - char name[14]; + char name[16]; int ret; dma->xdev = xdev; @@ -725,7 +725,7 @@ int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma, } /* ... and the DMA channel. */ - sprintf(name, "port%u", port); + snprintf(name, sizeof(name), "port%u", port); dma->dma = dma_request_slave_channel(dma->xdev->dev, name); if (dma->dma == NULL) { dev_err(dma->xdev->dev, "no VDMA channel found\n"); -- cgit v1.2.3-59-g8ed1b From 1a4de1b5e915b6ccc2b9b177b9e99af84660f045 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Tue, 28 Apr 2015 08:11:26 -0300 Subject: [media] cx25821: cx25821-medusa-reg.h: fix 0x0x prefix Fix the 0x0x prefix in integer constants. In this case a padding 0 must also be inserted to make the constants look like all the other 16 bits ones. Signed-off-by: Antonio Ospite Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-medusa-reg.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/cx25821/cx25821-medusa-reg.h b/drivers/media/pci/cx25821/cx25821-medusa-reg.h index c98ac946b277..2e10643a86b7 100644 --- a/drivers/media/pci/cx25821/cx25821-medusa-reg.h +++ b/drivers/media/pci/cx25821/cx25821-medusa-reg.h @@ -84,9 +84,9 @@ #define ABIST_BIN4_VGA3 0x01D4 #define ABIST_BIN5_VGA4 0x01D8 #define ABIST_BIN6_VGA5 0x01DC -#define ABIST_BIN7_VGA6 0x0x1E0 -#define ABIST_CLAMP_A 0x0x1E4 -#define ABIST_CLAMP_B 0x0x1E8 +#define ABIST_BIN7_VGA6 0x01E0 +#define ABIST_CLAMP_A 0x01E4 +#define ABIST_CLAMP_B 0x01E8 #define ABIST_CLAMP_C 0x01EC #define ABIST_CLAMP_D 0x01F0 #define ABIST_CLAMP_E 0x01F4 -- cgit v1.2.3-59-g8ed1b From f5d39078824fdd16f710e710e58f1cb937ab9553 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Sat, 2 May 2015 17:07:45 -0300 Subject: [media] siano: define SRVM_MAX_PID_FILTERS only once SRVM_MAX_PID_FILTERS was defined in 2 sms_tx_stats structures Signed-off-by: Fabian Frederick Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smscoreapi.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h index eb8bd689b936..4cc39e4a8318 100644 --- a/drivers/media/common/siano/smscoreapi.h +++ b/drivers/media/common/siano/smscoreapi.h @@ -1010,6 +1010,7 @@ struct sms_rx_stats_ex { s32 mrc_in_band_pwr; /* In band power in dBM */ }; +#define SRVM_MAX_PID_FILTERS 8 /* statistics information returned as response for * SmsHostApiGetstatisticsEx_Req for DVB applications, SMS1100 and up */ @@ -1021,7 +1022,6 @@ struct sms_stats_dvb { struct sms_tx_stats transmission_data; /* Burst parameters, valid only for DVB-H */ -#define SRVM_MAX_PID_FILTERS 8 struct sms_pid_data pid_data[SRVM_MAX_PID_FILTERS]; }; @@ -1035,7 +1035,6 @@ struct sms_stats_dvb_ex { struct sms_tx_stats transmission_data; /* Burst parameters, valid only for DVB-H */ -#define SRVM_MAX_PID_FILTERS 8 struct sms_pid_data pid_data[SRVM_MAX_PID_FILTERS]; }; -- cgit v1.2.3-59-g8ed1b From c636bd0bce374f3beed8a071032d807f61f0f5c4 Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Tue, 5 May 2015 13:33:52 -0300 Subject: [media] dw2102: remove unnecessary printing of MAC address While reading the MAC address for SU3000-based devices the system was printing excessive debug information in the logs: Output before the patch: [ 1515.780692] bc 00 00 00 00 00 [ 1515.781440] bc ea 00 00 00 00 [ 1515.782251] bc ea 2b 00 00 00 [ 1515.783094] bc ea 2b 46 00 00 [ 1515.783816] bc ea 2b 46 12 00 [ 1515.784565] bc ea 2b 46 12 92 [ 1515.784571] dvb-usb: MAC address: bc:ea:2b:46:12:92 Output after the patch: [ 3803.495706] dvb-usb: MAC address: bc:ea:2b:46:12:92 Signed-off-by: Olli Salonen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/dw2102.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c index 0a1dc3759c7c..d10c72c522b3 100644 --- a/drivers/media/usb/dvb-usb/dw2102.c +++ b/drivers/media/usb/dvb-usb/dw2102.c @@ -928,8 +928,6 @@ static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) break; else mac[i] = ibuf[0]; - - debug_dump(mac, 6, printk); } return 0; -- cgit v1.2.3-59-g8ed1b From 356484cabe44984d2dc66a90bd5e3465ba1f64fb Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Tue, 5 May 2015 13:33:55 -0300 Subject: [media] dw2102: resync fifo when demod locks If the streaming_ctrl is called to enable TS before demod has locked the TS will be empty. Copied the solution from the dvbsky driver for the TechnoTrend S2-4600 device: when the state changes from unlock to lock, call su3000_streaming_ctrl again. Signed-off-by: Olli Salonen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/dw2102.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c index d10c72c522b3..c2632bc9e530 100644 --- a/drivers/media/usb/dvb-usb/dw2102.c +++ b/drivers/media/usb/dvb-usb/dw2102.c @@ -117,8 +117,13 @@ struct dw2102_state { u8 initialized; + u8 last_lock; struct i2c_client *i2c_client_tuner; + + /* fe hook functions*/ int (*old_set_voltage)(struct dvb_frontend *f, fe_sec_voltage_t v); + int (*fe_read_status)(struct dvb_frontend *fe, + fe_status_t *status); }; /* debug */ @@ -999,6 +1004,23 @@ static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon) i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1); } +static int tt_s2_4600_read_status(struct dvb_frontend *fe, fe_status_t *status) +{ + struct dvb_usb_adapter *d = + (struct dvb_usb_adapter *)(fe->dvb->priv); + struct dw2102_state *st = (struct dw2102_state *)d->dev->priv; + int ret; + + ret = st->fe_read_status(fe, status); + + /* resync slave fifo when signal change from unlock to lock */ + if ((*status & FE_HAS_LOCK) && (!st->last_lock)) + su3000_streaming_ctrl(d, 1); + + st->last_lock = (*status & FE_HAS_LOCK) ? 1 : 0; + return ret; +} + static struct stv0299_config sharp_z0194a_config = { .demod_address = 0x68, .inittab = sharp_z0194a_inittab, @@ -1551,6 +1573,12 @@ static int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap) state->i2c_client_tuner = client; + /* hook fe: need to resync the slave fifo when signal locks */ + state->fe_read_status = adap->fe_adap[0].fe->ops.read_status; + adap->fe_adap[0].fe->ops.read_status = tt_s2_4600_read_status; + + state->last_lock = 0; + return 0; } -- cgit v1.2.3-59-g8ed1b From e989a73ebd09d22c22ead51fa363a2f56f70f28a Mon Sep 17 00:00:00 2001 From: Thomas Reitmayr Date: Fri, 1 May 2015 20:18:04 -0300 Subject: [media] media: Fix regression in some more dib0700 based devices Fix an oops during device initialization by correctly setting size_of_priv instead of leaving it 0. The regression was introduced by 8abe4a0a3f6d4217b16a ("[media] dib7000: export just one symbol") and only fixed for one type of dib0700 based devices in 9e334c75642b6e5bfb95 ("[media] Fix regression in some dib0700 based devices"). Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=92301 Fixes: 8abe4a0a3f6d4217b16a ("[media] dib7000: export just one symbol") Cc: stable@vger.kernel.org # for version 3.17+ Signed-off-by: Thomas Reitmayr Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/dib0700_devices.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c index 90cee380d3aa..e87ce835dcbd 100644 --- a/drivers/media/usb/dvb-usb/dib0700_devices.c +++ b/drivers/media/usb/dvb-usb/dib0700_devices.c @@ -3944,6 +3944,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, + .size_of_priv = sizeof(struct + dib0700_adapter_state), }, { .num_frontends = 1, .fe = {{ @@ -3956,6 +3958,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x03), }}, + .size_of_priv = sizeof(struct + dib0700_adapter_state), } }, @@ -4009,6 +4013,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, + .size_of_priv = sizeof(struct + dib0700_adapter_state), }, }, -- cgit v1.2.3-59-g8ed1b From 9195e5b2467b258413750526d5c65c6c22fafb11 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 29 Apr 2015 10:10:01 -0300 Subject: [media] msi001: revise synthesizer calculation Update synthesizer calculation to model I prefer nowadays. It is mostly just renaming some variables, but also minor functionality change how integer and fractional part are divided (using div_u64_rem()). Also, add 'schematic' of synthesizer following my current understanding. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/msi001.c | 74 +++++++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 30 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/msi001.c b/drivers/media/tuners/msi001.c index 74cfc3c98edb..d0ec4e3c9371 100644 --- a/drivers/media/tuners/msi001.c +++ b/drivers/media/tuners/msi001.c @@ -91,15 +91,15 @@ err: static int msi001_set_tuner(struct msi001 *s) { int ret, i; - unsigned int n, m, thresh, frac, vco_step, tmp, f_if1; + unsigned int uitmp, div_n, k, k_thresh, k_frac, div_lo, f_if1; u32 reg; - u64 f_vco, tmp64; - u8 mode, filter_mode, lo_div; + u64 f_vco; + u8 mode, filter_mode; static const struct { u32 rf; u8 mode; - u8 lo_div; + u8 div_lo; } band_lut[] = { { 50000000, 0xe1, 16}, /* AM_MODE2, antenna 2 */ {108000000, 0x42, 32}, /* VHF_MODE */ @@ -144,15 +144,15 @@ static int msi001_set_tuner(struct msi001 *s) */ unsigned int f_if = 0; #define F_REF 24000000 - #define R_REF 4 - #define F_OUT_STEP 1 + #define DIV_PRE_N 4 + #define F_VCO_STEP div_lo dev_dbg(&s->spi->dev, "f_rf=%d f_if=%d\n", f_rf, f_if); for (i = 0; i < ARRAY_SIZE(band_lut); i++) { if (f_rf <= band_lut[i].rf) { mode = band_lut[i].mode; - lo_div = band_lut[i].lo_div; + div_lo = band_lut[i].div_lo; break; } } @@ -200,32 +200,46 @@ static int msi001_set_tuner(struct msi001 *s) dev_dbg(&s->spi->dev, "bandwidth selected=%d\n", bandwidth_lut[i].freq); - f_vco = (u64) (f_rf + f_if + f_if1) * lo_div; - tmp64 = f_vco; - m = do_div(tmp64, F_REF * R_REF); - n = (unsigned int) tmp64; + /* + * Fractional-N synthesizer + * + * +---------------------------------------+ + * v | + * Fref +----+ +-------+ +----+ +------+ +---+ + * ------> | PD | --> | VCO | ------> | /4 | --> | /N.F | <-- | K | + * +----+ +-------+ +----+ +------+ +---+ + * | + * | + * v + * +-------+ Fout + * | /Rout | ------> + * +-------+ + */ - vco_step = F_OUT_STEP * lo_div; - thresh = (F_REF * R_REF) / vco_step; - frac = 1ul * thresh * m / (F_REF * R_REF); + /* Calculate PLL integer and fractional control word. */ + f_vco = (u64) (f_rf + f_if + f_if1) * div_lo; + div_n = div_u64_rem(f_vco, DIV_PRE_N * F_REF, &k); + k_thresh = (DIV_PRE_N * F_REF) / F_VCO_STEP; + k_frac = div_u64((u64) k * k_thresh, (DIV_PRE_N * F_REF)); /* Find out greatest common divisor and divide to smaller. */ - tmp = gcd(thresh, frac); - thresh /= tmp; - frac /= tmp; + uitmp = gcd(k_thresh, k_frac); + k_thresh /= uitmp; + k_frac /= uitmp; /* Force divide to reg max. Resolution will be reduced. */ - tmp = DIV_ROUND_UP(thresh, 4095); - thresh = DIV_ROUND_CLOSEST(thresh, tmp); - frac = DIV_ROUND_CLOSEST(frac, tmp); + uitmp = DIV_ROUND_UP(k_thresh, 4095); + k_thresh = DIV_ROUND_CLOSEST(k_thresh, uitmp); + k_frac = DIV_ROUND_CLOSEST(k_frac, uitmp); - /* calc real RF set */ - tmp = 1ul * F_REF * R_REF * n; - tmp += 1ul * F_REF * R_REF * frac / thresh; - tmp /= lo_div; + /* Calculate real RF set. */ + uitmp = (unsigned int) F_REF * DIV_PRE_N * div_n; + uitmp += (unsigned int) F_REF * DIV_PRE_N * k_frac / k_thresh; + uitmp /= div_lo; - dev_dbg(&s->spi->dev, "rf=%u:%u n=%d thresh=%d frac=%d\n", - f_rf, tmp, n, thresh, frac); + dev_dbg(&s->spi->dev, + "f_rf=%u:%u f_vco=%llu div_n=%u k_thresh=%u k_frac=%u div_lo=%u\n", + f_rf, uitmp, f_vco, div_n, k_thresh, k_frac, div_lo); ret = msi001_wreg(s, 0x00000e); if (ret) @@ -246,7 +260,7 @@ static int msi001_set_tuner(struct msi001 *s) goto err; reg = 5 << 0; - reg |= thresh << 4; + reg |= k_thresh << 4; reg |= 1 << 19; reg |= 1 << 21; ret = msi001_wreg(s, reg); @@ -254,8 +268,8 @@ static int msi001_set_tuner(struct msi001 *s) goto err; reg = 2 << 0; - reg |= frac << 4; - reg |= n << 16; + reg |= k_frac << 4; + reg |= div_n << 16; ret = msi001_wreg(s, reg); if (ret) goto err; @@ -276,7 +290,7 @@ static int msi001_set_tuner(struct msi001 *s) err: dev_dbg(&s->spi->dev, "failed %d\n", ret); return ret; -}; +} static int msi001_s_power(struct v4l2_subdev *sd, int on) { -- cgit v1.2.3-59-g8ed1b From 83e64b4d3fafc8af32173a72b011a958e83d45b4 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 29 Apr 2015 10:57:12 -0300 Subject: [media] msi001: cleanups / renames Rename state from s to dev. Rename some other things. Fix indentations. Disable driver unbind via sysfs. indentation prevent unload Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/msi001.c | 195 ++++++++++++++++++++++-------------------- 1 file changed, 101 insertions(+), 94 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/msi001.c b/drivers/media/tuners/msi001.c index d0ec4e3c9371..b533240f8ec0 100644 --- a/drivers/media/tuners/msi001.c +++ b/drivers/media/tuners/msi001.c @@ -36,7 +36,7 @@ static const struct v4l2_frequency_band bands[] = { }, }; -struct msi001 { +struct msi001_dev { struct spi_device *spi; struct v4l2_subdev sd; @@ -51,25 +51,26 @@ struct msi001 { unsigned int f_tuner; }; -static inline struct msi001 *sd_to_msi001(struct v4l2_subdev *sd) +static inline struct msi001_dev *sd_to_msi001_dev(struct v4l2_subdev *sd) { - return container_of(sd, struct msi001, sd); + return container_of(sd, struct msi001_dev, sd); } -static int msi001_wreg(struct msi001 *s, u32 data) +static int msi001_wreg(struct msi001_dev *dev, u32 data) { /* Register format: 4 bits addr + 20 bits value */ - return spi_write(s->spi, &data, 3); + return spi_write(dev->spi, &data, 3); }; -static int msi001_set_gain(struct msi001 *s, int lna_gain, int mixer_gain, - int if_gain) +static int msi001_set_gain(struct msi001_dev *dev, int lna_gain, int mixer_gain, + int if_gain) { + struct spi_device *spi = dev->spi; int ret; u32 reg; - dev_dbg(&s->spi->dev, "lna=%d mixer=%d if=%d\n", - lna_gain, mixer_gain, if_gain); + dev_dbg(&spi->dev, "lna=%d mixer=%d if=%d\n", + lna_gain, mixer_gain, if_gain); reg = 1 << 0; reg |= (59 - if_gain) << 4; @@ -78,18 +79,19 @@ static int msi001_set_gain(struct msi001 *s, int lna_gain, int mixer_gain, reg |= (1 - lna_gain) << 13; reg |= 4 << 14; reg |= 0 << 17; - ret = msi001_wreg(s, reg); + ret = msi001_wreg(dev, reg); if (ret) goto err; return 0; err: - dev_dbg(&s->spi->dev, "failed %d\n", ret); + dev_dbg(&spi->dev, "failed %d\n", ret); return ret; }; -static int msi001_set_tuner(struct msi001 *s) +static int msi001_set_tuner(struct msi001_dev *dev) { + struct spi_device *spi = dev->spi; int ret, i; unsigned int uitmp, div_n, k, k_thresh, k_frac, div_lo, f_if1; u32 reg; @@ -130,7 +132,7 @@ static int msi001_set_tuner(struct msi001 *s) {8000000, 0x07}, /* 8 MHz */ }; - unsigned int f_rf = s->f_tuner; + unsigned int f_rf = dev->f_tuner; /* * bandwidth (Hz) @@ -147,7 +149,7 @@ static int msi001_set_tuner(struct msi001 *s) #define DIV_PRE_N 4 #define F_VCO_STEP div_lo - dev_dbg(&s->spi->dev, "f_rf=%d f_if=%d\n", f_rf, f_if); + dev_dbg(&spi->dev, "f_rf=%d f_if=%d\n", f_rf, f_if); for (i = 0; i < ARRAY_SIZE(band_lut); i++) { if (f_rf <= band_lut[i].rf) { @@ -156,7 +158,6 @@ static int msi001_set_tuner(struct msi001 *s) break; } } - if (i == ARRAY_SIZE(band_lut)) { ret = -EINVAL; goto err; @@ -174,14 +175,13 @@ static int msi001_set_tuner(struct msi001 *s) break; } } - if (i == ARRAY_SIZE(if_freq_lut)) { ret = -EINVAL; goto err; } /* filters */ - bandwidth = s->bandwidth->val; + bandwidth = dev->bandwidth->val; bandwidth = clamp(bandwidth, 200000U, 8000000U); for (i = 0; i < ARRAY_SIZE(bandwidth_lut); i++) { @@ -190,15 +190,14 @@ static int msi001_set_tuner(struct msi001 *s) break; } } - if (i == ARRAY_SIZE(bandwidth_lut)) { ret = -EINVAL; goto err; } - s->bandwidth->val = bandwidth_lut[i].freq; + dev->bandwidth->val = bandwidth_lut[i].freq; - dev_dbg(&s->spi->dev, "bandwidth selected=%d\n", bandwidth_lut[i].freq); + dev_dbg(&spi->dev, "bandwidth selected=%d\n", bandwidth_lut[i].freq); /* * Fractional-N synthesizer @@ -237,15 +236,15 @@ static int msi001_set_tuner(struct msi001 *s) uitmp += (unsigned int) F_REF * DIV_PRE_N * k_frac / k_thresh; uitmp /= div_lo; - dev_dbg(&s->spi->dev, + dev_dbg(&spi->dev, "f_rf=%u:%u f_vco=%llu div_n=%u k_thresh=%u k_frac=%u div_lo=%u\n", f_rf, uitmp, f_vco, div_n, k_thresh, k_frac, div_lo); - ret = msi001_wreg(s, 0x00000e); + ret = msi001_wreg(dev, 0x00000e); if (ret) goto err; - ret = msi001_wreg(s, 0x000003); + ret = msi001_wreg(dev, 0x000003); if (ret) goto err; @@ -255,7 +254,7 @@ static int msi001_set_tuner(struct msi001 *s) reg |= bandwidth << 14; reg |= 0x02 << 17; reg |= 0x00 << 20; - ret = msi001_wreg(s, reg); + ret = msi001_wreg(dev, reg); if (ret) goto err; @@ -263,46 +262,47 @@ static int msi001_set_tuner(struct msi001 *s) reg |= k_thresh << 4; reg |= 1 << 19; reg |= 1 << 21; - ret = msi001_wreg(s, reg); + ret = msi001_wreg(dev, reg); if (ret) goto err; reg = 2 << 0; reg |= k_frac << 4; reg |= div_n << 16; - ret = msi001_wreg(s, reg); + ret = msi001_wreg(dev, reg); if (ret) goto err; - ret = msi001_set_gain(s, s->lna_gain->cur.val, s->mixer_gain->cur.val, - s->if_gain->cur.val); + ret = msi001_set_gain(dev, dev->lna_gain->cur.val, + dev->mixer_gain->cur.val, dev->if_gain->cur.val); if (ret) goto err; reg = 6 << 0; reg |= 63 << 4; reg |= 4095 << 10; - ret = msi001_wreg(s, reg); + ret = msi001_wreg(dev, reg); if (ret) goto err; return 0; err: - dev_dbg(&s->spi->dev, "failed %d\n", ret); + dev_dbg(&spi->dev, "failed %d\n", ret); return ret; } static int msi001_s_power(struct v4l2_subdev *sd, int on) { - struct msi001 *s = sd_to_msi001(sd); + struct msi001_dev *dev = sd_to_msi001_dev(sd); + struct spi_device *spi = dev->spi; int ret; - dev_dbg(&s->spi->dev, "on=%d\n", on); + dev_dbg(&spi->dev, "on=%d\n", on); if (on) ret = 0; else - ret = msi001_wreg(s, 0x000000); + ret = msi001_wreg(dev, 0x000000); return ret; } @@ -313,9 +313,10 @@ static const struct v4l2_subdev_core_ops msi001_core_ops = { static int msi001_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v) { - struct msi001 *s = sd_to_msi001(sd); + struct msi001_dev *dev = sd_to_msi001_dev(sd); + struct spi_device *spi = dev->spi; - dev_dbg(&s->spi->dev, "index=%d\n", v->index); + dev_dbg(&spi->dev, "index=%d\n", v->index); strlcpy(v->name, "Mirics MSi001", sizeof(v->name)); v->type = V4L2_TUNER_RF; @@ -328,47 +329,51 @@ static int msi001_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v) static int msi001_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *v) { - struct msi001 *s = sd_to_msi001(sd); + struct msi001_dev *dev = sd_to_msi001_dev(sd); + struct spi_device *spi = dev->spi; - dev_dbg(&s->spi->dev, "index=%d\n", v->index); + dev_dbg(&spi->dev, "index=%d\n", v->index); return 0; } static int msi001_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) { - struct msi001 *s = sd_to_msi001(sd); + struct msi001_dev *dev = sd_to_msi001_dev(sd); + struct spi_device *spi = dev->spi; - dev_dbg(&s->spi->dev, "tuner=%d\n", f->tuner); - f->frequency = s->f_tuner; + dev_dbg(&spi->dev, "tuner=%d\n", f->tuner); + f->frequency = dev->f_tuner; return 0; } static int msi001_s_frequency(struct v4l2_subdev *sd, - const struct v4l2_frequency *f) + const struct v4l2_frequency *f) { - struct msi001 *s = sd_to_msi001(sd); + struct msi001_dev *dev = sd_to_msi001_dev(sd); + struct spi_device *spi = dev->spi; unsigned int band; - dev_dbg(&s->spi->dev, "tuner=%d type=%d frequency=%u\n", - f->tuner, f->type, f->frequency); + dev_dbg(&spi->dev, "tuner=%d type=%d frequency=%u\n", + f->tuner, f->type, f->frequency); if (f->frequency < ((bands[0].rangehigh + bands[1].rangelow) / 2)) band = 0; else band = 1; - s->f_tuner = clamp_t(unsigned int, f->frequency, - bands[band].rangelow, bands[band].rangehigh); + dev->f_tuner = clamp_t(unsigned int, f->frequency, + bands[band].rangelow, bands[band].rangehigh); - return msi001_set_tuner(s); + return msi001_set_tuner(dev); } static int msi001_enum_freq_bands(struct v4l2_subdev *sd, - struct v4l2_frequency_band *band) + struct v4l2_frequency_band *band) { - struct msi001 *s = sd_to_msi001(sd); + struct msi001_dev *dev = sd_to_msi001_dev(sd); + struct spi_device *spi = dev->spi; - dev_dbg(&s->spi->dev, "tuner=%d type=%d index=%d\n", - band->tuner, band->type, band->index); + dev_dbg(&spi->dev, "tuner=%d type=%d index=%d\n", + band->tuner, band->type, band->index); if (band->index >= ARRAY_SIZE(bands)) return -EINVAL; @@ -395,34 +400,37 @@ static const struct v4l2_subdev_ops msi001_ops = { static int msi001_s_ctrl(struct v4l2_ctrl *ctrl) { - struct msi001 *s = container_of(ctrl->handler, struct msi001, hdl); + struct msi001_dev *dev = container_of(ctrl->handler, struct msi001_dev, hdl); + struct spi_device *spi = dev->spi; int ret; - dev_dbg(&s->spi->dev, - "id=%d name=%s val=%d min=%lld max=%lld step=%lld\n", - ctrl->id, ctrl->name, ctrl->val, - ctrl->minimum, ctrl->maximum, ctrl->step); + dev_dbg(&spi->dev, "id=%d name=%s val=%d min=%lld max=%lld step=%lld\n", + ctrl->id, ctrl->name, ctrl->val, ctrl->minimum, ctrl->maximum, + ctrl->step); switch (ctrl->id) { case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO: case V4L2_CID_RF_TUNER_BANDWIDTH: - ret = msi001_set_tuner(s); + ret = msi001_set_tuner(dev); break; case V4L2_CID_RF_TUNER_LNA_GAIN: - ret = msi001_set_gain(s, s->lna_gain->val, - s->mixer_gain->cur.val, s->if_gain->cur.val); + ret = msi001_set_gain(dev, dev->lna_gain->val, + dev->mixer_gain->cur.val, + dev->if_gain->cur.val); break; case V4L2_CID_RF_TUNER_MIXER_GAIN: - ret = msi001_set_gain(s, s->lna_gain->cur.val, - s->mixer_gain->val, s->if_gain->cur.val); + ret = msi001_set_gain(dev, dev->lna_gain->cur.val, + dev->mixer_gain->val, + dev->if_gain->cur.val); break; case V4L2_CID_RF_TUNER_IF_GAIN: - ret = msi001_set_gain(s, s->lna_gain->cur.val, - s->mixer_gain->cur.val, s->if_gain->val); + ret = msi001_set_gain(dev, dev->lna_gain->cur.val, + dev->mixer_gain->cur.val, + dev->if_gain->val); break; default: - dev_dbg(&s->spi->dev, "unknown control %d\n", ctrl->id); + dev_dbg(&spi->dev, "unknown control %d\n", ctrl->id); ret = -EINVAL; } @@ -435,56 +443,54 @@ static const struct v4l2_ctrl_ops msi001_ctrl_ops = { static int msi001_probe(struct spi_device *spi) { - struct msi001 *s; + struct msi001_dev *dev; int ret; dev_dbg(&spi->dev, "\n"); - s = kzalloc(sizeof(struct msi001), GFP_KERNEL); - if (s == NULL) { + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) { ret = -ENOMEM; - dev_dbg(&spi->dev, "Could not allocate memory for msi001\n"); - goto err_kfree; + goto err; } - s->spi = spi; - s->f_tuner = bands[0].rangelow; - v4l2_spi_subdev_init(&s->sd, spi, &msi001_ops); + dev->spi = spi; + dev->f_tuner = bands[0].rangelow; + v4l2_spi_subdev_init(&dev->sd, spi, &msi001_ops); /* Register controls */ - v4l2_ctrl_handler_init(&s->hdl, 5); - s->bandwidth_auto = v4l2_ctrl_new_std(&s->hdl, &msi001_ctrl_ops, + v4l2_ctrl_handler_init(&dev->hdl, 5); + dev->bandwidth_auto = v4l2_ctrl_new_std(&dev->hdl, &msi001_ctrl_ops, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1); - s->bandwidth = v4l2_ctrl_new_std(&s->hdl, &msi001_ctrl_ops, + dev->bandwidth = v4l2_ctrl_new_std(&dev->hdl, &msi001_ctrl_ops, V4L2_CID_RF_TUNER_BANDWIDTH, 200000, 8000000, 1, 200000); - v4l2_ctrl_auto_cluster(2, &s->bandwidth_auto, 0, false); - s->lna_gain = v4l2_ctrl_new_std(&s->hdl, &msi001_ctrl_ops, + v4l2_ctrl_auto_cluster(2, &dev->bandwidth_auto, 0, false); + dev->lna_gain = v4l2_ctrl_new_std(&dev->hdl, &msi001_ctrl_ops, V4L2_CID_RF_TUNER_LNA_GAIN, 0, 1, 1, 1); - s->mixer_gain = v4l2_ctrl_new_std(&s->hdl, &msi001_ctrl_ops, + dev->mixer_gain = v4l2_ctrl_new_std(&dev->hdl, &msi001_ctrl_ops, V4L2_CID_RF_TUNER_MIXER_GAIN, 0, 1, 1, 1); - s->if_gain = v4l2_ctrl_new_std(&s->hdl, &msi001_ctrl_ops, + dev->if_gain = v4l2_ctrl_new_std(&dev->hdl, &msi001_ctrl_ops, V4L2_CID_RF_TUNER_IF_GAIN, 0, 59, 1, 0); - if (s->hdl.error) { - ret = s->hdl.error; - dev_err(&s->spi->dev, "Could not initialize controls\n"); + if (dev->hdl.error) { + ret = dev->hdl.error; + dev_err(&spi->dev, "Could not initialize controls\n"); /* control init failed, free handler */ goto err_ctrl_handler_free; } - s->sd.ctrl_handler = &s->hdl; + dev->sd.ctrl_handler = &dev->hdl; return 0; - err_ctrl_handler_free: - v4l2_ctrl_handler_free(&s->hdl); -err_kfree: - kfree(s); + v4l2_ctrl_handler_free(&dev->hdl); + kfree(dev); +err: return ret; } static int msi001_remove(struct spi_device *spi) { struct v4l2_subdev *sd = spi_get_drvdata(spi); - struct msi001 *s = sd_to_msi001(sd); + struct msi001_dev *dev = sd_to_msi001_dev(sd); dev_dbg(&spi->dev, "\n"); @@ -492,26 +498,27 @@ static int msi001_remove(struct spi_device *spi) * Registered by v4l2_spi_new_subdev() from master driver, but we must * unregister it from here. Weird. */ - v4l2_device_unregister_subdev(&s->sd); - v4l2_ctrl_handler_free(&s->hdl); - kfree(s); + v4l2_device_unregister_subdev(&dev->sd); + v4l2_ctrl_handler_free(&dev->hdl); + kfree(dev); return 0; } -static const struct spi_device_id msi001_id[] = { +static const struct spi_device_id msi001_id_table[] = { {"msi001", 0}, {} }; -MODULE_DEVICE_TABLE(spi, msi001_id); +MODULE_DEVICE_TABLE(spi, msi001_id_table); static struct spi_driver msi001_driver = { .driver = { .name = "msi001", .owner = THIS_MODULE, + .suppress_bind_attrs = true, }, .probe = msi001_probe, .remove = msi001_remove, - .id_table = msi001_id, + .id_table = msi001_id_table, }; module_spi_driver(msi001_driver); -- cgit v1.2.3-59-g8ed1b From faf22b13ee7335129e236804b0e532b1872d1fd8 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 29 Apr 2015 13:13:31 -0300 Subject: [media] msi2500: revise synthesizer calculation Update synthesizer calculation to model I prefer nowadays. It is mostly just renaming some variables, but also minor functionality change how integer and fractional part are divided (using div_u64_rem()). Also, add 'schematic' of synthesizer following my current understanding. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/msi2500/msi2500.c | 49 +++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 15 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/msi2500/msi2500.c b/drivers/media/usb/msi2500/msi2500.c index efc761c78f72..8605b96dc0b4 100644 --- a/drivers/media/usb/msi2500/msi2500.c +++ b/drivers/media/usb/msi2500/msi2500.c @@ -682,11 +682,10 @@ static int msi2500_ctrl_msg(struct msi2500_state *s, u8 cmd, u32 data) return ret; } -#define F_REF 24000000 -#define DIV_R_IN 2 static int msi2500_set_usb_adc(struct msi2500_state *s) { - int ret, div_n, div_m, div_r_out, f_sr, f_vco, fract; + int ret; + unsigned int f_vco, f_sr, div_n, k, k_cw, div_out; u32 reg3, reg4, reg7; struct v4l2_ctrl *bandwidth_auto; struct v4l2_ctrl *bandwidth; @@ -727,6 +726,21 @@ static int msi2500_set_usb_adc(struct msi2500_state *s) break; } + /* + * Fractional-N synthesizer + * + * +----------------------------------------+ + * v | + * Fref +----+ +-------+ +-----+ +------+ +---+ + * ------> | PD | --> | VCO | --> | /2 | ------> | /N.F | <-- | K | + * +----+ +-------+ +-----+ +------+ +---+ + * | + * | + * v + * +-------+ +-----+ Fout + * | /Rout | --> | /12 | ------> + * +-------+ +-----+ + */ /* * Synthesizer config is just a educated guess... * @@ -754,10 +768,14 @@ static int msi2500_set_usb_adc(struct msi2500_state *s) * * VCO 202000000 - 720000000++ */ + + #define F_REF 24000000 + #define DIV_PRE_N 2 + #define DIV_LO_OUT 12 reg3 = 0x01000303; reg4 = 0x00000004; - /* XXX: Filters? AGC? */ + /* XXX: Filters? AGC? VCO band? */ if (f_sr < 6000000) reg3 |= 0x1 << 20; else if (f_sr < 7000000) @@ -767,24 +785,25 @@ static int msi2500_set_usb_adc(struct msi2500_state *s) else reg3 |= 0xd << 20; - for (div_r_out = 4; div_r_out < 16; div_r_out += 2) { - f_vco = f_sr * div_r_out * 12; - dev_dbg(s->dev, "div_r_out=%d f_vco=%d\n", div_r_out, f_vco); + for (div_out = 4; div_out < 16; div_out += 2) { + f_vco = f_sr * div_out * DIV_LO_OUT; + dev_dbg(s->dev, "div_out=%d f_vco=%d\n", div_out, f_vco); if (f_vco >= 202000000) break; } - div_n = f_vco / (F_REF * DIV_R_IN); - div_m = f_vco % (F_REF * DIV_R_IN); - fract = 0x200000ul * div_m / (F_REF * DIV_R_IN); + /* Calculate PLL integer and fractional control word. */ + div_n = div_u64_rem(f_vco, DIV_PRE_N * F_REF, &k); + k_cw = div_u64((u64) k * 0x200000, DIV_PRE_N * F_REF); reg3 |= div_n << 16; - reg3 |= (div_r_out / 2 - 1) << 10; - reg3 |= ((fract >> 20) & 0x000001) << 15; /* [20] */ - reg4 |= ((fract >> 0) & 0x0fffff) << 8; /* [19:0] */ + reg3 |= (div_out / 2 - 1) << 10; + reg3 |= ((k_cw >> 20) & 0x000001) << 15; /* [20] */ + reg4 |= ((k_cw >> 0) & 0x0fffff) << 8; /* [19:0] */ - dev_dbg(s->dev, "f_sr=%d f_vco=%d div_n=%d div_m=%d div_r_out=%d reg3=%08x reg4=%08x\n", - f_sr, f_vco, div_n, div_m, div_r_out, reg3, reg4); + dev_dbg(s->dev, + "f_sr=%u f_vco=%u div_n=%u k=%u div_out=%u reg3=%08x reg4=%08x\n", + f_sr, f_vco, div_n, k, div_out, reg3, reg4); ret = msi2500_ctrl_msg(s, CMD_WREG, 0x00608008); if (ret) -- cgit v1.2.3-59-g8ed1b From f7e5a6559640dfac9d96bee74d02066a28107aef Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 29 Apr 2015 13:37:34 -0300 Subject: [media] msi2500: cleanups Rename state to dev. Correct some indentations. Remove FSF address. Fix some style issues reported by checkpatch.pl. Correct some style issues I liked. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/msi2500/msi2500.c | 610 ++++++++++++++++++------------------ 1 file changed, 306 insertions(+), 304 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/msi2500/msi2500.c b/drivers/media/usb/msi2500/msi2500.c index 8605b96dc0b4..3f276d921cca 100644 --- a/drivers/media/usb/msi2500/msi2500.c +++ b/drivers/media/usb/msi2500/msi2500.c @@ -1,4 +1,5 @@ /* + * Mirics MSi2500 driver * Mirics MSi3101 SDR Dongle driver * * Copyright (C) 2013 Antti Palosaari @@ -13,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * That driver is somehow based of pwc driver: * (C) 1999-2004 Nemosoft Unv. * (C) 2004-2006 Luc Saillard (luc@saillard.org) @@ -119,7 +116,7 @@ struct msi2500_frame_buf { struct list_head list; }; -struct msi2500_state { +struct msi2500_dev { struct device *dev; struct video_device vdev; struct v4l2_device v4l2_dev; @@ -158,19 +155,19 @@ struct msi2500_state { /* Private functions */ static struct msi2500_frame_buf *msi2500_get_next_fill_buf( - struct msi2500_state *s) + struct msi2500_dev *dev) { unsigned long flags; struct msi2500_frame_buf *buf = NULL; - spin_lock_irqsave(&s->queued_bufs_lock, flags); - if (list_empty(&s->queued_bufs)) + spin_lock_irqsave(&dev->queued_bufs_lock, flags); + if (list_empty(&dev->queued_bufs)) goto leave; - buf = list_entry(s->queued_bufs.next, struct msi2500_frame_buf, list); + buf = list_entry(dev->queued_bufs.next, struct msi2500_frame_buf, list); list_del(&buf->list); leave: - spin_unlock_irqrestore(&s->queued_bufs_lock, flags); + spin_unlock_irqrestore(&dev->queued_bufs_lock, flags); return buf; } @@ -256,8 +253,8 @@ leave: * signed 14-bit sample */ -static int msi2500_convert_stream(struct msi2500_state *s, u8 *dst, u8 *src, - unsigned int src_len) +static int msi2500_convert_stream(struct msi2500_dev *dev, u8 *dst, u8 *src, + unsigned int src_len) { unsigned int i, j, transactions, dst_len = 0; u32 sample[3]; @@ -268,26 +265,27 @@ static int msi2500_convert_stream(struct msi2500_state *s, u8 *dst, u8 *src, for (i = 0; i < transactions; i++) { sample[i] = src[3] << 24 | src[2] << 16 | src[1] << 8 | src[0] << 0; - if (i == 0 && s->next_sample != sample[0]) { - dev_dbg_ratelimited(s->dev, - "%d samples lost, %d %08x:%08x\n", - sample[0] - s->next_sample, - src_len, s->next_sample, sample[0]); + if (i == 0 && dev->next_sample != sample[0]) { + dev_dbg_ratelimited(dev->dev, + "%d samples lost, %d %08x:%08x\n", + sample[0] - dev->next_sample, + src_len, dev->next_sample, + sample[0]); } /* * Dump all unknown 'garbage' data - maybe we will discover * someday if there is something rational... */ - dev_dbg_ratelimited(s->dev, "%*ph\n", 12, &src[4]); + dev_dbg_ratelimited(dev->dev, "%*ph\n", 12, &src[4]); src += 16; /* skip header */ - switch (s->pixelformat) { + switch (dev->pixelformat) { case V4L2_SDR_FMT_CU8: /* 504 x IQ samples */ { - s8 *s8src = (s8 *) src; - u8 *u8dst = (u8 *) dst; + s8 *s8src = (s8 *)src; + u8 *u8dst = (u8 *)dst; for (j = 0; j < 1008; j++) *u8dst++ = *s8src++ + 128; @@ -295,13 +293,13 @@ static int msi2500_convert_stream(struct msi2500_state *s, u8 *dst, u8 *src, src += 1008; dst += 1008; dst_len += 1008; - s->next_sample = sample[i] + 504; + dev->next_sample = sample[i] + 504; break; } case V4L2_SDR_FMT_CU16LE: /* 252 x IQ samples */ { - s16 *s16src = (s16 *) src; - u16 *u16dst = (u16 *) dst; + s16 *s16src = (s16 *)src; + u16 *u16dst = (u16 *)dst; struct {signed int x:14; } se; /* sign extension */ unsigned int utmp; @@ -317,38 +315,38 @@ static int msi2500_convert_stream(struct msi2500_state *s, u8 *dst, u8 *src, src += 1008; dst += 1008; dst_len += 1008; - s->next_sample = sample[i] + 252; + dev->next_sample = sample[i] + 252; break; } case MSI2500_PIX_FMT_SDR_MSI2500_384: /* 384 x IQ samples */ /* Dump unknown 'garbage' data */ - dev_dbg_ratelimited(s->dev, "%*ph\n", 24, &src[1000]); + dev_dbg_ratelimited(dev->dev, "%*ph\n", 24, &src[1000]); memcpy(dst, src, 984); src += 984 + 24; dst += 984; dst_len += 984; - s->next_sample = sample[i] + 384; + dev->next_sample = sample[i] + 384; break; case V4L2_SDR_FMT_CS8: /* 504 x IQ samples */ memcpy(dst, src, 1008); src += 1008; dst += 1008; dst_len += 1008; - s->next_sample = sample[i] + 504; + dev->next_sample = sample[i] + 504; break; case MSI2500_PIX_FMT_SDR_S12: /* 336 x IQ samples */ memcpy(dst, src, 1008); src += 1008; dst += 1008; dst_len += 1008; - s->next_sample = sample[i] + 336; + dev->next_sample = sample[i] + 336; break; case V4L2_SDR_FMT_CS14LE: /* 252 x IQ samples */ memcpy(dst, src, 1008); src += 1008; dst += 1008; dst_len += 1008; - s->next_sample = sample[i] + 252; + dev->next_sample = sample[i] + 252; break; default: break; @@ -356,17 +354,17 @@ static int msi2500_convert_stream(struct msi2500_state *s, u8 *dst, u8 *src, } /* calculate sample rate and output it in 10 seconds intervals */ - if (unlikely(time_is_before_jiffies(s->jiffies_next))) { + if (unlikely(time_is_before_jiffies(dev->jiffies_next))) { #define MSECS 10000UL unsigned int msecs = jiffies_to_msecs(jiffies - - s->jiffies_next + msecs_to_jiffies(MSECS)); - unsigned int samples = s->next_sample - s->sample; - - s->jiffies_next = jiffies + msecs_to_jiffies(MSECS); - s->sample = s->next_sample; - dev_dbg(s->dev, "size=%u samples=%u msecs=%u sample rate=%lu\n", - src_len, samples, msecs, - samples * 1000UL / msecs); + dev->jiffies_next + msecs_to_jiffies(MSECS)); + unsigned int samples = dev->next_sample - dev->sample; + + dev->jiffies_next = jiffies + msecs_to_jiffies(MSECS); + dev->sample = dev->next_sample; + dev_dbg(dev->dev, "size=%u samples=%u msecs=%u sample rate=%lu\n", + src_len, samples, msecs, + samples * 1000UL / msecs); } return dst_len; @@ -378,27 +376,28 @@ static int msi2500_convert_stream(struct msi2500_state *s, u8 *dst, u8 *src, */ static void msi2500_isoc_handler(struct urb *urb) { - struct msi2500_state *s = (struct msi2500_state *)urb->context; + struct msi2500_dev *dev = (struct msi2500_dev *)urb->context; int i, flen, fstatus; unsigned char *iso_buf = NULL; struct msi2500_frame_buf *fbuf; - if (unlikely(urb->status == -ENOENT || urb->status == -ECONNRESET || - urb->status == -ESHUTDOWN)) { - dev_dbg(s->dev, "URB (%p) unlinked %ssynchronuously\n", - urb, urb->status == -ENOENT ? "" : "a"); + if (unlikely(urb->status == -ENOENT || + urb->status == -ECONNRESET || + urb->status == -ESHUTDOWN)) { + dev_dbg(dev->dev, "URB (%p) unlinked %ssynchronuously\n", + urb, urb->status == -ENOENT ? "" : "a"); return; } if (unlikely(urb->status != 0)) { - dev_dbg(s->dev, "called with status %d\n", urb->status); + dev_dbg(dev->dev, "called with status %d\n", urb->status); /* Give up after a number of contiguous errors */ - if (++s->isoc_errors > MAX_ISOC_ERRORS) - dev_dbg(s->dev, "Too many ISOC errors, bailing out\n"); + if (++dev->isoc_errors > MAX_ISOC_ERRORS) + dev_dbg(dev->dev, "Too many ISOC errors, bailing out\n"); goto handler_end; } else { /* Reset ISOC error counter. We did get here, after all. */ - s->isoc_errors = 0; + dev->isoc_errors = 0; } /* Compact data */ @@ -408,9 +407,9 @@ static void msi2500_isoc_handler(struct urb *urb) /* Check frame error */ fstatus = urb->iso_frame_desc[i].status; if (unlikely(fstatus)) { - dev_dbg_ratelimited(s->dev, - "frame=%d/%d has error %d skipping\n", - i, urb->number_of_packets, fstatus); + dev_dbg_ratelimited(dev->dev, + "frame=%d/%d has error %d skipping\n", + i, urb->number_of_packets, fstatus); continue; } @@ -422,18 +421,18 @@ static void msi2500_isoc_handler(struct urb *urb) iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset; /* Get free framebuffer */ - fbuf = msi2500_get_next_fill_buf(s); + fbuf = msi2500_get_next_fill_buf(dev); if (unlikely(fbuf == NULL)) { - s->vb_full++; - dev_dbg_ratelimited(s->dev, - "videobuf is full, %d packets dropped\n", - s->vb_full); + dev->vb_full++; + dev_dbg_ratelimited(dev->dev, + "videobuf is full, %d packets dropped\n", + dev->vb_full); continue; } /* fill framebuffer */ ptr = vb2_plane_vaddr(&fbuf->vb, 0); - flen = msi2500_convert_stream(s, ptr, iso_buf, flen); + flen = msi2500_convert_stream(dev, ptr, iso_buf, flen); vb2_set_plane_payload(&fbuf->vb, 0, flen); vb2_buffer_done(&fbuf->vb, VB2_BUF_STATE_DONE); } @@ -441,66 +440,66 @@ static void msi2500_isoc_handler(struct urb *urb) handler_end: i = usb_submit_urb(urb, GFP_ATOMIC); if (unlikely(i != 0)) - dev_dbg(s->dev, "Error (%d) re-submitting urb\n", i); + dev_dbg(dev->dev, "Error (%d) re-submitting urb\n", i); } -static void msi2500_iso_stop(struct msi2500_state *s) +static void msi2500_iso_stop(struct msi2500_dev *dev) { int i; - dev_dbg(s->dev, "\n"); + dev_dbg(dev->dev, "\n"); /* Unlinking ISOC buffers one by one */ for (i = 0; i < MAX_ISO_BUFS; i++) { - if (s->urbs[i]) { - dev_dbg(s->dev, "Unlinking URB %p\n", s->urbs[i]); - usb_kill_urb(s->urbs[i]); + if (dev->urbs[i]) { + dev_dbg(dev->dev, "Unlinking URB %p\n", dev->urbs[i]); + usb_kill_urb(dev->urbs[i]); } } } -static void msi2500_iso_free(struct msi2500_state *s) +static void msi2500_iso_free(struct msi2500_dev *dev) { int i; - dev_dbg(s->dev, "\n"); + dev_dbg(dev->dev, "\n"); /* Freeing ISOC buffers one by one */ for (i = 0; i < MAX_ISO_BUFS; i++) { - if (s->urbs[i]) { - dev_dbg(s->dev, "Freeing URB\n"); - if (s->urbs[i]->transfer_buffer) { - usb_free_coherent(s->udev, - s->urbs[i]->transfer_buffer_length, - s->urbs[i]->transfer_buffer, - s->urbs[i]->transfer_dma); + if (dev->urbs[i]) { + dev_dbg(dev->dev, "Freeing URB\n"); + if (dev->urbs[i]->transfer_buffer) { + usb_free_coherent(dev->udev, + dev->urbs[i]->transfer_buffer_length, + dev->urbs[i]->transfer_buffer, + dev->urbs[i]->transfer_dma); } - usb_free_urb(s->urbs[i]); - s->urbs[i] = NULL; + usb_free_urb(dev->urbs[i]); + dev->urbs[i] = NULL; } } } /* Both v4l2_lock and vb_queue_lock should be locked when calling this */ -static void msi2500_isoc_cleanup(struct msi2500_state *s) +static void msi2500_isoc_cleanup(struct msi2500_dev *dev) { - dev_dbg(s->dev, "\n"); + dev_dbg(dev->dev, "\n"); - msi2500_iso_stop(s); - msi2500_iso_free(s); + msi2500_iso_stop(dev); + msi2500_iso_free(dev); } /* Both v4l2_lock and vb_queue_lock should be locked when calling this */ -static int msi2500_isoc_init(struct msi2500_state *s) +static int msi2500_isoc_init(struct msi2500_dev *dev) { struct urb *urb; int i, j, ret; - dev_dbg(s->dev, "\n"); + dev_dbg(dev->dev, "\n"); - s->isoc_errors = 0; + dev->isoc_errors = 0; - ret = usb_set_interface(s->udev, 0, 1); + ret = usb_set_interface(dev->udev, 0, 1); if (ret) return ret; @@ -508,29 +507,29 @@ static int msi2500_isoc_init(struct msi2500_state *s) for (i = 0; i < MAX_ISO_BUFS; i++) { urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL); if (urb == NULL) { - dev_err(s->dev, "Failed to allocate urb %d\n", i); - msi2500_isoc_cleanup(s); + dev_err(dev->dev, "Failed to allocate urb %d\n", i); + msi2500_isoc_cleanup(dev); return -ENOMEM; } - s->urbs[i] = urb; - dev_dbg(s->dev, "Allocated URB at 0x%p\n", urb); + dev->urbs[i] = urb; + dev_dbg(dev->dev, "Allocated URB at 0x%p\n", urb); urb->interval = 1; - urb->dev = s->udev; - urb->pipe = usb_rcvisocpipe(s->udev, 0x81); + urb->dev = dev->udev; + urb->pipe = usb_rcvisocpipe(dev->udev, 0x81); urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; - urb->transfer_buffer = usb_alloc_coherent(s->udev, + urb->transfer_buffer = usb_alloc_coherent(dev->udev, ISO_BUFFER_SIZE, GFP_KERNEL, &urb->transfer_dma); if (urb->transfer_buffer == NULL) { - dev_err(s->dev, "Failed to allocate urb buffer %d\n", - i); - msi2500_isoc_cleanup(s); + dev_err(dev->dev, + "Failed to allocate urb buffer %d\n", i); + msi2500_isoc_cleanup(dev); return -ENOMEM; } urb->transfer_buffer_length = ISO_BUFFER_SIZE; urb->complete = msi2500_isoc_handler; - urb->context = s; + urb->context = dev; urb->start_frame = 0; urb->number_of_packets = ISO_FRAMES_PER_DESC; for (j = 0; j < ISO_FRAMES_PER_DESC; j++) { @@ -541,14 +540,15 @@ static int msi2500_isoc_init(struct msi2500_state *s) /* link */ for (i = 0; i < MAX_ISO_BUFS; i++) { - ret = usb_submit_urb(s->urbs[i], GFP_KERNEL); + ret = usb_submit_urb(dev->urbs[i], GFP_KERNEL); if (ret) { - dev_err(s->dev, "usb_submit_urb %d failed with error %d\n", - i, ret); - msi2500_isoc_cleanup(s); + dev_err(dev->dev, + "usb_submit_urb %d failed with error %d\n", + i, ret); + msi2500_isoc_cleanup(dev); return ret; } - dev_dbg(s->dev, "URB 0x%p submitted.\n", s->urbs[i]); + dev_dbg(dev->dev, "URB 0x%p submitted.\n", dev->urbs[i]); } /* All is done... */ @@ -556,56 +556,56 @@ static int msi2500_isoc_init(struct msi2500_state *s) } /* Must be called with vb_queue_lock hold */ -static void msi2500_cleanup_queued_bufs(struct msi2500_state *s) +static void msi2500_cleanup_queued_bufs(struct msi2500_dev *dev) { unsigned long flags; - dev_dbg(s->dev, "\n"); + dev_dbg(dev->dev, "\n"); - spin_lock_irqsave(&s->queued_bufs_lock, flags); - while (!list_empty(&s->queued_bufs)) { + spin_lock_irqsave(&dev->queued_bufs_lock, flags); + while (!list_empty(&dev->queued_bufs)) { struct msi2500_frame_buf *buf; - buf = list_entry(s->queued_bufs.next, struct msi2500_frame_buf, - list); + buf = list_entry(dev->queued_bufs.next, + struct msi2500_frame_buf, list); list_del(&buf->list); vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); } - spin_unlock_irqrestore(&s->queued_bufs_lock, flags); + spin_unlock_irqrestore(&dev->queued_bufs_lock, flags); } /* The user yanked out the cable... */ static void msi2500_disconnect(struct usb_interface *intf) { struct v4l2_device *v = usb_get_intfdata(intf); - struct msi2500_state *s = - container_of(v, struct msi2500_state, v4l2_dev); + struct msi2500_dev *dev = + container_of(v, struct msi2500_dev, v4l2_dev); - dev_dbg(s->dev, "\n"); + dev_dbg(dev->dev, "\n"); - mutex_lock(&s->vb_queue_lock); - mutex_lock(&s->v4l2_lock); + mutex_lock(&dev->vb_queue_lock); + mutex_lock(&dev->v4l2_lock); /* No need to keep the urbs around after disconnection */ - s->udev = NULL; - v4l2_device_disconnect(&s->v4l2_dev); - video_unregister_device(&s->vdev); - spi_unregister_master(s->master); - mutex_unlock(&s->v4l2_lock); - mutex_unlock(&s->vb_queue_lock); - - v4l2_device_put(&s->v4l2_dev); + dev->udev = NULL; + v4l2_device_disconnect(&dev->v4l2_dev); + video_unregister_device(&dev->vdev); + spi_unregister_master(dev->master); + mutex_unlock(&dev->v4l2_lock); + mutex_unlock(&dev->vb_queue_lock); + + v4l2_device_put(&dev->v4l2_dev); } static int msi2500_querycap(struct file *file, void *fh, - struct v4l2_capability *cap) + struct v4l2_capability *cap) { - struct msi2500_state *s = video_drvdata(file); + struct msi2500_dev *dev = video_drvdata(file); - dev_dbg(s->dev, "\n"); + dev_dbg(dev->dev, "\n"); strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver)); - strlcpy(cap->card, s->vdev.name, sizeof(cap->card)); - usb_make_path(s->udev, cap->bus_info, sizeof(cap->bus_info)); + strlcpy(cap->card, dev->vdev.name, sizeof(cap->card)); + usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); cap->device_caps = V4L2_CAP_SDR_CAPTURE | V4L2_CAP_STREAMING | V4L2_CAP_READWRITE | V4L2_CAP_TUNER; cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; @@ -614,43 +614,46 @@ static int msi2500_querycap(struct file *file, void *fh, /* Videobuf2 operations */ static int msi2500_queue_setup(struct vb2_queue *vq, - const struct v4l2_format *fmt, unsigned int *nbuffers, - unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[]) + const struct v4l2_format *fmt, + unsigned int *nbuffers, + unsigned int *nplanes, unsigned int sizes[], + void *alloc_ctxs[]) { - struct msi2500_state *s = vb2_get_drv_priv(vq); + struct msi2500_dev *dev = vb2_get_drv_priv(vq); - dev_dbg(s->dev, "nbuffers=%d\n", *nbuffers); + dev_dbg(dev->dev, "nbuffers=%d\n", *nbuffers); /* Absolute min and max number of buffers available for mmap() */ *nbuffers = clamp_t(unsigned int, *nbuffers, 8, 32); *nplanes = 1; - sizes[0] = PAGE_ALIGN(s->buffersize); - dev_dbg(s->dev, "nbuffers=%d sizes[0]=%d\n", *nbuffers, sizes[0]); + sizes[0] = PAGE_ALIGN(dev->buffersize); + dev_dbg(dev->dev, "nbuffers=%d sizes[0]=%d\n", *nbuffers, sizes[0]); return 0; } static void msi2500_buf_queue(struct vb2_buffer *vb) { - struct msi2500_state *s = vb2_get_drv_priv(vb->vb2_queue); - struct msi2500_frame_buf *buf = - container_of(vb, struct msi2500_frame_buf, vb); + struct msi2500_dev *dev = vb2_get_drv_priv(vb->vb2_queue); + struct msi2500_frame_buf *buf = container_of(vb, + struct msi2500_frame_buf, + vb); unsigned long flags; /* Check the device has not disconnected between prep and queuing */ - if (unlikely(!s->udev)) { + if (unlikely(!dev->udev)) { vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); return; } - spin_lock_irqsave(&s->queued_bufs_lock, flags); - list_add_tail(&buf->list, &s->queued_bufs); - spin_unlock_irqrestore(&s->queued_bufs_lock, flags); + spin_lock_irqsave(&dev->queued_bufs_lock, flags); + list_add_tail(&buf->list, &dev->queued_bufs); + spin_unlock_irqrestore(&dev->queued_bufs_lock, flags); } #define CMD_WREG 0x41 #define CMD_START_STREAMING 0x43 #define CMD_STOP_STREAMING 0x45 -#define CMD_READ_UNKNOW 0x48 +#define CMD_READ_UNKNOWN 0x48 #define msi2500_dbg_usb_control_msg(_dev, _r, _t, _v, _i, _b, _l) { \ char *_direction; \ @@ -663,7 +666,7 @@ static void msi2500_buf_queue(struct vb2_buffer *vb) _l & 0xff, _l >> 8, _direction, _l, _b); \ } -static int msi2500_ctrl_msg(struct msi2500_state *s, u8 cmd, u32 data) +static int msi2500_ctrl_msg(struct msi2500_dev *dev, u8 cmd, u32 data) { int ret; u8 request = cmd; @@ -671,18 +674,18 @@ static int msi2500_ctrl_msg(struct msi2500_state *s, u8 cmd, u32 data) u16 value = (data >> 0) & 0xffff; u16 index = (data >> 16) & 0xffff; - msi2500_dbg_usb_control_msg(s->dev, - request, requesttype, value, index, NULL, 0); - ret = usb_control_msg(s->udev, usb_sndctrlpipe(s->udev, 0), - request, requesttype, value, index, NULL, 0, 2000); + msi2500_dbg_usb_control_msg(dev->dev, request, requesttype, + value, index, NULL, 0); + ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), request, + requesttype, value, index, NULL, 0, 2000); if (ret) - dev_err(s->dev, "failed %d, cmd %02x, data %04x\n", - ret, cmd, data); + dev_err(dev->dev, "failed %d, cmd %02x, data %04x\n", + ret, cmd, data); return ret; } -static int msi2500_set_usb_adc(struct msi2500_state *s) +static int msi2500_set_usb_adc(struct msi2500_dev *dev) { int ret; unsigned int f_vco, f_sr, div_n, k, k_cw, div_out; @@ -690,19 +693,19 @@ static int msi2500_set_usb_adc(struct msi2500_state *s) struct v4l2_ctrl *bandwidth_auto; struct v4l2_ctrl *bandwidth; - f_sr = s->f_adc; + f_sr = dev->f_adc; /* set tuner, subdev, filters according to sampling rate */ - bandwidth_auto = v4l2_ctrl_find(&s->hdl, + bandwidth_auto = v4l2_ctrl_find(&dev->hdl, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO); if (v4l2_ctrl_g_ctrl(bandwidth_auto)) { - bandwidth = v4l2_ctrl_find(&s->hdl, + bandwidth = v4l2_ctrl_find(&dev->hdl, V4L2_CID_RF_TUNER_BANDWIDTH); - v4l2_ctrl_s_ctrl(bandwidth, s->f_adc); + v4l2_ctrl_s_ctrl(bandwidth, dev->f_adc); } /* select stream format */ - switch (s->pixelformat) { + switch (dev->pixelformat) { case V4L2_SDR_FMT_CU8: reg7 = 0x000c9407; /* 504 */ break; @@ -787,7 +790,7 @@ static int msi2500_set_usb_adc(struct msi2500_state *s) for (div_out = 4; div_out < 16; div_out += 2) { f_vco = f_sr * div_out * DIV_LO_OUT; - dev_dbg(s->dev, "div_out=%d f_vco=%d\n", div_out, f_vco); + dev_dbg(dev->dev, "div_out=%u f_vco=%u\n", div_out, f_vco); if (f_vco >= 202000000) break; } @@ -801,39 +804,39 @@ static int msi2500_set_usb_adc(struct msi2500_state *s) reg3 |= ((k_cw >> 20) & 0x000001) << 15; /* [20] */ reg4 |= ((k_cw >> 0) & 0x0fffff) << 8; /* [19:0] */ - dev_dbg(s->dev, + dev_dbg(dev->dev, "f_sr=%u f_vco=%u div_n=%u k=%u div_out=%u reg3=%08x reg4=%08x\n", f_sr, f_vco, div_n, k, div_out, reg3, reg4); - ret = msi2500_ctrl_msg(s, CMD_WREG, 0x00608008); + ret = msi2500_ctrl_msg(dev, CMD_WREG, 0x00608008); if (ret) goto err; - ret = msi2500_ctrl_msg(s, CMD_WREG, 0x00000c05); + ret = msi2500_ctrl_msg(dev, CMD_WREG, 0x00000c05); if (ret) goto err; - ret = msi2500_ctrl_msg(s, CMD_WREG, 0x00020000); + ret = msi2500_ctrl_msg(dev, CMD_WREG, 0x00020000); if (ret) goto err; - ret = msi2500_ctrl_msg(s, CMD_WREG, 0x00480102); + ret = msi2500_ctrl_msg(dev, CMD_WREG, 0x00480102); if (ret) goto err; - ret = msi2500_ctrl_msg(s, CMD_WREG, 0x00f38008); + ret = msi2500_ctrl_msg(dev, CMD_WREG, 0x00f38008); if (ret) goto err; - ret = msi2500_ctrl_msg(s, CMD_WREG, reg7); + ret = msi2500_ctrl_msg(dev, CMD_WREG, reg7); if (ret) goto err; - ret = msi2500_ctrl_msg(s, CMD_WREG, reg4); + ret = msi2500_ctrl_msg(dev, CMD_WREG, reg4); if (ret) goto err; - ret = msi2500_ctrl_msg(s, CMD_WREG, reg3); + ret = msi2500_ctrl_msg(dev, CMD_WREG, reg3); if (ret) goto err; err: @@ -842,57 +845,57 @@ err: static int msi2500_start_streaming(struct vb2_queue *vq, unsigned int count) { - struct msi2500_state *s = vb2_get_drv_priv(vq); + struct msi2500_dev *dev = vb2_get_drv_priv(vq); int ret; - dev_dbg(s->dev, "\n"); + dev_dbg(dev->dev, "\n"); - if (!s->udev) + if (!dev->udev) return -ENODEV; - if (mutex_lock_interruptible(&s->v4l2_lock)) + if (mutex_lock_interruptible(&dev->v4l2_lock)) return -ERESTARTSYS; /* wake-up tuner */ - v4l2_subdev_call(s->v4l2_subdev, core, s_power, 1); + v4l2_subdev_call(dev->v4l2_subdev, core, s_power, 1); - ret = msi2500_set_usb_adc(s); + ret = msi2500_set_usb_adc(dev); - ret = msi2500_isoc_init(s); + ret = msi2500_isoc_init(dev); if (ret) - msi2500_cleanup_queued_bufs(s); + msi2500_cleanup_queued_bufs(dev); - ret = msi2500_ctrl_msg(s, CMD_START_STREAMING, 0); + ret = msi2500_ctrl_msg(dev, CMD_START_STREAMING, 0); - mutex_unlock(&s->v4l2_lock); + mutex_unlock(&dev->v4l2_lock); return ret; } static void msi2500_stop_streaming(struct vb2_queue *vq) { - struct msi2500_state *s = vb2_get_drv_priv(vq); + struct msi2500_dev *dev = vb2_get_drv_priv(vq); - dev_dbg(s->dev, "\n"); + dev_dbg(dev->dev, "\n"); - mutex_lock(&s->v4l2_lock); + mutex_lock(&dev->v4l2_lock); - if (s->udev) - msi2500_isoc_cleanup(s); + if (dev->udev) + msi2500_isoc_cleanup(dev); - msi2500_cleanup_queued_bufs(s); + msi2500_cleanup_queued_bufs(dev); /* according to tests, at least 700us delay is required */ msleep(20); - if (!msi2500_ctrl_msg(s, CMD_STOP_STREAMING, 0)) { + if (!msi2500_ctrl_msg(dev, CMD_STOP_STREAMING, 0)) { /* sleep USB IF / ADC */ - msi2500_ctrl_msg(s, CMD_WREG, 0x01000003); + msi2500_ctrl_msg(dev, CMD_WREG, 0x01000003); } /* sleep tuner */ - v4l2_subdev_call(s->v4l2_subdev, core, s_power, 0); + v4l2_subdev_call(dev->v4l2_subdev, core, s_power, 0); - mutex_unlock(&s->v4l2_lock); + mutex_unlock(&dev->v4l2_lock); } static struct vb2_ops msi2500_vb2_ops = { @@ -905,13 +908,13 @@ static struct vb2_ops msi2500_vb2_ops = { }; static int msi2500_enum_fmt_sdr_cap(struct file *file, void *priv, - struct v4l2_fmtdesc *f) + struct v4l2_fmtdesc *f) { - struct msi2500_state *s = video_drvdata(file); + struct msi2500_dev *dev = video_drvdata(file); - dev_dbg(s->dev, "index=%d\n", f->index); + dev_dbg(dev->dev, "index=%d\n", f->index); - if (f->index >= s->num_formats) + if (f->index >= dev->num_formats) return -EINVAL; strlcpy(f->description, formats[f->index].name, sizeof(f->description)); @@ -921,45 +924,45 @@ static int msi2500_enum_fmt_sdr_cap(struct file *file, void *priv, } static int msi2500_g_fmt_sdr_cap(struct file *file, void *priv, - struct v4l2_format *f) + struct v4l2_format *f) { - struct msi2500_state *s = video_drvdata(file); + struct msi2500_dev *dev = video_drvdata(file); - dev_dbg(s->dev, "pixelformat fourcc %4.4s\n", - (char *)&s->pixelformat); + dev_dbg(dev->dev, "pixelformat fourcc %4.4s\n", + (char *)&dev->pixelformat); - f->fmt.sdr.pixelformat = s->pixelformat; - f->fmt.sdr.buffersize = s->buffersize; + f->fmt.sdr.pixelformat = dev->pixelformat; + f->fmt.sdr.buffersize = dev->buffersize; memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); return 0; } static int msi2500_s_fmt_sdr_cap(struct file *file, void *priv, - struct v4l2_format *f) + struct v4l2_format *f) { - struct msi2500_state *s = video_drvdata(file); - struct vb2_queue *q = &s->vb_queue; + struct msi2500_dev *dev = video_drvdata(file); + struct vb2_queue *q = &dev->vb_queue; int i; - dev_dbg(s->dev, "pixelformat fourcc %4.4s\n", - (char *)&f->fmt.sdr.pixelformat); + dev_dbg(dev->dev, "pixelformat fourcc %4.4s\n", + (char *)&f->fmt.sdr.pixelformat); if (vb2_is_busy(q)) return -EBUSY; memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); - for (i = 0; i < s->num_formats; i++) { + for (i = 0; i < dev->num_formats; i++) { if (formats[i].pixelformat == f->fmt.sdr.pixelformat) { - s->pixelformat = formats[i].pixelformat; - s->buffersize = formats[i].buffersize; + dev->pixelformat = formats[i].pixelformat; + dev->buffersize = formats[i].buffersize; f->fmt.sdr.buffersize = formats[i].buffersize; return 0; } } - s->pixelformat = formats[0].pixelformat; - s->buffersize = formats[0].buffersize; + dev->pixelformat = formats[0].pixelformat; + dev->buffersize = formats[0].buffersize; f->fmt.sdr.pixelformat = formats[0].pixelformat; f->fmt.sdr.buffersize = formats[0].buffersize; @@ -967,16 +970,16 @@ static int msi2500_s_fmt_sdr_cap(struct file *file, void *priv, } static int msi2500_try_fmt_sdr_cap(struct file *file, void *priv, - struct v4l2_format *f) + struct v4l2_format *f) { - struct msi2500_state *s = video_drvdata(file); + struct msi2500_dev *dev = video_drvdata(file); int i; - dev_dbg(s->dev, "pixelformat fourcc %4.4s\n", - (char *)&f->fmt.sdr.pixelformat); + dev_dbg(dev->dev, "pixelformat fourcc %4.4s\n", + (char *)&f->fmt.sdr.pixelformat); memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); - for (i = 0; i < s->num_formats; i++) { + for (i = 0; i < dev->num_formats; i++) { if (formats[i].pixelformat == f->fmt.sdr.pixelformat) { f->fmt.sdr.buffersize = formats[i].buffersize; return 0; @@ -990,17 +993,17 @@ static int msi2500_try_fmt_sdr_cap(struct file *file, void *priv, } static int msi2500_s_tuner(struct file *file, void *priv, - const struct v4l2_tuner *v) + const struct v4l2_tuner *v) { - struct msi2500_state *s = video_drvdata(file); + struct msi2500_dev *dev = video_drvdata(file); int ret; - dev_dbg(s->dev, "index=%d\n", v->index); + dev_dbg(dev->dev, "index=%d\n", v->index); if (v->index == 0) ret = 0; else if (v->index == 1) - ret = v4l2_subdev_call(s->v4l2_subdev, tuner, s_tuner, v); + ret = v4l2_subdev_call(dev->v4l2_subdev, tuner, s_tuner, v); else ret = -EINVAL; @@ -1009,10 +1012,10 @@ static int msi2500_s_tuner(struct file *file, void *priv, static int msi2500_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - struct msi2500_state *s = video_drvdata(file); + struct msi2500_dev *dev = video_drvdata(file); int ret; - dev_dbg(s->dev, "index=%d\n", v->index); + dev_dbg(dev->dev, "index=%d\n", v->index); if (v->index == 0) { strlcpy(v->name, "Mirics MSi2500", sizeof(v->name)); @@ -1022,7 +1025,7 @@ static int msi2500_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) v->rangehigh = 15000000; ret = 0; } else if (v->index == 1) { - ret = v4l2_subdev_call(s->v4l2_subdev, tuner, g_tuner, v); + ret = v4l2_subdev_call(dev->v4l2_subdev, tuner, g_tuner, v); } else { ret = -EINVAL; } @@ -1031,19 +1034,19 @@ static int msi2500_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) } static int msi2500_g_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) + struct v4l2_frequency *f) { - struct msi2500_state *s = video_drvdata(file); + struct msi2500_dev *dev = video_drvdata(file); int ret = 0; - dev_dbg(s->dev, "tuner=%d type=%d\n", f->tuner, f->type); + dev_dbg(dev->dev, "tuner=%d type=%d\n", f->tuner, f->type); if (f->tuner == 0) { - f->frequency = s->f_adc; + f->frequency = dev->f_adc; ret = 0; } else if (f->tuner == 1) { f->type = V4L2_TUNER_RF; - ret = v4l2_subdev_call(s->v4l2_subdev, tuner, g_frequency, f); + ret = v4l2_subdev_call(dev->v4l2_subdev, tuner, g_frequency, f); } else { ret = -EINVAL; } @@ -1052,22 +1055,22 @@ static int msi2500_g_frequency(struct file *file, void *priv, } static int msi2500_s_frequency(struct file *file, void *priv, - const struct v4l2_frequency *f) + const struct v4l2_frequency *f) { - struct msi2500_state *s = video_drvdata(file); + struct msi2500_dev *dev = video_drvdata(file); int ret; - dev_dbg(s->dev, "tuner=%d type=%d frequency=%u\n", - f->tuner, f->type, f->frequency); + dev_dbg(dev->dev, "tuner=%d type=%d frequency=%u\n", + f->tuner, f->type, f->frequency); if (f->tuner == 0) { - s->f_adc = clamp_t(unsigned int, f->frequency, - bands[0].rangelow, - bands[0].rangehigh); - dev_dbg(s->dev, "ADC frequency=%u Hz\n", s->f_adc); - ret = msi2500_set_usb_adc(s); + dev->f_adc = clamp_t(unsigned int, f->frequency, + bands[0].rangelow, + bands[0].rangehigh); + dev_dbg(dev->dev, "ADC frequency=%u Hz\n", dev->f_adc); + ret = msi2500_set_usb_adc(dev); } else if (f->tuner == 1) { - ret = v4l2_subdev_call(s->v4l2_subdev, tuner, s_frequency, f); + ret = v4l2_subdev_call(dev->v4l2_subdev, tuner, s_frequency, f); } else { ret = -EINVAL; } @@ -1076,13 +1079,13 @@ static int msi2500_s_frequency(struct file *file, void *priv, } static int msi2500_enum_freq_bands(struct file *file, void *priv, - struct v4l2_frequency_band *band) + struct v4l2_frequency_band *band) { - struct msi2500_state *s = video_drvdata(file); + struct msi2500_dev *dev = video_drvdata(file); int ret; - dev_dbg(s->dev, "tuner=%d type=%d index=%d\n", - band->tuner, band->type, band->index); + dev_dbg(dev->dev, "tuner=%d type=%d index=%d\n", + band->tuner, band->type, band->index); if (band->tuner == 0) { if (band->index >= ARRAY_SIZE(bands)) { @@ -1092,8 +1095,8 @@ static int msi2500_enum_freq_bands(struct file *file, void *priv, ret = 0; } } else if (band->tuner == 1) { - ret = v4l2_subdev_call(s->v4l2_subdev, tuner, - enum_freq_bands, band); + ret = v4l2_subdev_call(dev->v4l2_subdev, tuner, + enum_freq_bands, band); } else { ret = -EINVAL; } @@ -1150,29 +1153,28 @@ static struct video_device msi2500_template = { static void msi2500_video_release(struct v4l2_device *v) { - struct msi2500_state *s = - container_of(v, struct msi2500_state, v4l2_dev); + struct msi2500_dev *dev = container_of(v, struct msi2500_dev, v4l2_dev); - v4l2_ctrl_handler_free(&s->hdl); - v4l2_device_unregister(&s->v4l2_dev); - kfree(s); + v4l2_ctrl_handler_free(&dev->hdl); + v4l2_device_unregister(&dev->v4l2_dev); + kfree(dev); } static int msi2500_transfer_one_message(struct spi_master *master, - struct spi_message *m) + struct spi_message *m) { - struct msi2500_state *s = spi_master_get_devdata(master); + struct msi2500_dev *dev = spi_master_get_devdata(master); struct spi_transfer *t; int ret = 0; u32 data; list_for_each_entry(t, &m->transfers, transfer_list) { - dev_dbg(s->dev, "msg=%*ph\n", t->len, t->tx_buf); + dev_dbg(dev->dev, "msg=%*ph\n", t->len, t->tx_buf); data = 0x09; /* reg 9 is SPI adapter */ data |= ((u8 *)t->tx_buf)[0] << 8; data |= ((u8 *)t->tx_buf)[1] << 16; data |= ((u8 *)t->tx_buf)[2] << 24; - ret = msi2500_ctrl_msg(s, CMD_WREG, data); + ret = msi2500_ctrl_msg(dev, CMD_WREG, data); } m->status = ret; @@ -1181,9 +1183,9 @@ static int msi2500_transfer_one_message(struct spi_master *master, } static int msi2500_probe(struct usb_interface *intf, - const struct usb_device_id *id) + const struct usb_device_id *id) { - struct msi2500_state *s; + struct msi2500_dev *dev; struct v4l2_subdev *sd; struct spi_master *master; int ret; @@ -1194,65 +1196,65 @@ static int msi2500_probe(struct usb_interface *intf, .max_speed_hz = 12000000, }; - s = kzalloc(sizeof(struct msi2500_state), GFP_KERNEL); - if (s == NULL) { - dev_err(&intf->dev, "Could not allocate memory for state\n"); - return -ENOMEM; + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) { + ret = -ENOMEM; + goto err; } - mutex_init(&s->v4l2_lock); - mutex_init(&s->vb_queue_lock); - spin_lock_init(&s->queued_bufs_lock); - INIT_LIST_HEAD(&s->queued_bufs); - s->dev = &intf->dev; - s->udev = interface_to_usbdev(intf); - s->f_adc = bands[0].rangelow; - s->pixelformat = formats[0].pixelformat; - s->buffersize = formats[0].buffersize; - s->num_formats = NUM_FORMATS; + mutex_init(&dev->v4l2_lock); + mutex_init(&dev->vb_queue_lock); + spin_lock_init(&dev->queued_bufs_lock); + INIT_LIST_HEAD(&dev->queued_bufs); + dev->dev = &intf->dev; + dev->udev = interface_to_usbdev(intf); + dev->f_adc = bands[0].rangelow; + dev->pixelformat = formats[0].pixelformat; + dev->buffersize = formats[0].buffersize; + dev->num_formats = NUM_FORMATS; if (!msi2500_emulated_fmt) - s->num_formats -= 2; + dev->num_formats -= 2; /* Init videobuf2 queue structure */ - s->vb_queue.type = V4L2_BUF_TYPE_SDR_CAPTURE; - s->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; - s->vb_queue.drv_priv = s; - s->vb_queue.buf_struct_size = sizeof(struct msi2500_frame_buf); - s->vb_queue.ops = &msi2500_vb2_ops; - s->vb_queue.mem_ops = &vb2_vmalloc_memops; - s->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; - ret = vb2_queue_init(&s->vb_queue); + dev->vb_queue.type = V4L2_BUF_TYPE_SDR_CAPTURE; + dev->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; + dev->vb_queue.drv_priv = dev; + dev->vb_queue.buf_struct_size = sizeof(struct msi2500_frame_buf); + dev->vb_queue.ops = &msi2500_vb2_ops; + dev->vb_queue.mem_ops = &vb2_vmalloc_memops; + dev->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + ret = vb2_queue_init(&dev->vb_queue); if (ret) { - dev_err(s->dev, "Could not initialize vb2 queue\n"); + dev_err(dev->dev, "Could not initialize vb2 queue\n"); goto err_free_mem; } /* Init video_device structure */ - s->vdev = msi2500_template; - s->vdev.queue = &s->vb_queue; - s->vdev.queue->lock = &s->vb_queue_lock; - video_set_drvdata(&s->vdev, s); + dev->vdev = msi2500_template; + dev->vdev.queue = &dev->vb_queue; + dev->vdev.queue->lock = &dev->vb_queue_lock; + video_set_drvdata(&dev->vdev, dev); /* Register the v4l2_device structure */ - s->v4l2_dev.release = msi2500_video_release; - ret = v4l2_device_register(&intf->dev, &s->v4l2_dev); + dev->v4l2_dev.release = msi2500_video_release; + ret = v4l2_device_register(&intf->dev, &dev->v4l2_dev); if (ret) { - dev_err(s->dev, "Failed to register v4l2-device (%d)\n", ret); + dev_err(dev->dev, "Failed to register v4l2-device (%d)\n", ret); goto err_free_mem; } /* SPI master adapter */ - master = spi_alloc_master(s->dev, 0); + master = spi_alloc_master(dev->dev, 0); if (master == NULL) { ret = -ENOMEM; goto err_unregister_v4l2_dev; } - s->master = master; + dev->master = master; master->bus_num = 0; master->num_chipselect = 1; master->transfer_one_message = msi2500_transfer_one_message; - spi_master_set_devdata(master, s); + spi_master_set_devdata(master, dev); ret = spi_register_master(master); if (ret) { spi_master_put(master); @@ -1260,57 +1262,57 @@ static int msi2500_probe(struct usb_interface *intf, } /* load v4l2 subdevice */ - sd = v4l2_spi_new_subdev(&s->v4l2_dev, master, &board_info); - s->v4l2_subdev = sd; + sd = v4l2_spi_new_subdev(&dev->v4l2_dev, master, &board_info); + dev->v4l2_subdev = sd; if (sd == NULL) { - dev_err(s->dev, "cannot get v4l2 subdevice\n"); + dev_err(dev->dev, "cannot get v4l2 subdevice\n"); ret = -ENODEV; goto err_unregister_master; } /* Register controls */ - v4l2_ctrl_handler_init(&s->hdl, 0); - if (s->hdl.error) { - ret = s->hdl.error; - dev_err(s->dev, "Could not initialize controls\n"); + v4l2_ctrl_handler_init(&dev->hdl, 0); + if (dev->hdl.error) { + ret = dev->hdl.error; + dev_err(dev->dev, "Could not initialize controls\n"); goto err_free_controls; } /* currently all controls are from subdev */ - v4l2_ctrl_add_handler(&s->hdl, sd->ctrl_handler, NULL); + v4l2_ctrl_add_handler(&dev->hdl, sd->ctrl_handler, NULL); - s->v4l2_dev.ctrl_handler = &s->hdl; - s->vdev.v4l2_dev = &s->v4l2_dev; - s->vdev.lock = &s->v4l2_lock; + dev->v4l2_dev.ctrl_handler = &dev->hdl; + dev->vdev.v4l2_dev = &dev->v4l2_dev; + dev->vdev.lock = &dev->v4l2_lock; - ret = video_register_device(&s->vdev, VFL_TYPE_SDR, -1); + ret = video_register_device(&dev->vdev, VFL_TYPE_SDR, -1); if (ret) { - dev_err(s->dev, "Failed to register as video device (%d)\n", - ret); + dev_err(dev->dev, + "Failed to register as video device (%d)\n", ret); goto err_unregister_v4l2_dev; } - dev_info(s->dev, "Registered as %s\n", - video_device_node_name(&s->vdev)); - dev_notice(s->dev, "SDR API is still slightly experimental and functionality changes may follow\n"); - + dev_info(dev->dev, "Registered as %s\n", + video_device_node_name(&dev->vdev)); + dev_notice(dev->dev, + "SDR API is still slightly experimental and functionality changes may follow\n"); return 0; - err_free_controls: - v4l2_ctrl_handler_free(&s->hdl); + v4l2_ctrl_handler_free(&dev->hdl); err_unregister_master: - spi_unregister_master(s->master); + spi_unregister_master(dev->master); err_unregister_v4l2_dev: - v4l2_device_unregister(&s->v4l2_dev); + v4l2_device_unregister(&dev->v4l2_dev); err_free_mem: - kfree(s); + kfree(dev); +err: return ret; } /* USB device ID list */ static struct usb_device_id msi2500_id_table[] = { - { USB_DEVICE(0x1df7, 0x2500) }, /* Mirics MSi3101 SDR Dongle */ - { USB_DEVICE(0x2040, 0xd300) }, /* Hauppauge WinTV 133559 LF */ - { } + {USB_DEVICE(0x1df7, 0x2500)}, /* Mirics MSi3101 SDR Dongle */ + {USB_DEVICE(0x2040, 0xd300)}, /* Hauppauge WinTV 133559 LF */ + {} }; MODULE_DEVICE_TABLE(usb, msi2500_id_table); -- cgit v1.2.3-59-g8ed1b From 9869da5bacc5c9b865a183bd36c04be76cdd325d Mon Sep 17 00:00:00 2001 From: James Hogan Date: Tue, 31 Mar 2015 14:48:06 -0300 Subject: [media] rc: rc-ir-raw: Add scancode encoder callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a callback to raw ir handlers for encoding and modulating a scancode to a set of raw events. This could be used for transmit, or for converting a wakeup scancode filter to a form that is more suitable for raw hardware wake up filters. Signed-off-by: James Hogan Signed-off-by: Antti Seppälä Cc: David Härdeman Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/rc-core-priv.h | 2 ++ drivers/media/rc/rc-ir-raw.c | 37 +++++++++++++++++++++++++++++++++++++ include/media/rc-core.h | 3 +++ 3 files changed, 42 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index b68d4f762734..122c25fe91e0 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -25,6 +25,8 @@ struct ir_raw_handler { u64 protocols; /* which are handled by this handler */ int (*decode)(struct rc_dev *dev, struct ir_raw_event event); + int (*encode)(u64 protocols, const struct rc_scancode_filter *scancode, + struct ir_raw_event *events, unsigned int max); /* These two should only be used by the lirc decoder */ int (*raw_register)(struct rc_dev *dev); diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index b732ac6a26d8..dd47fe567f03 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -246,6 +246,43 @@ static int change_protocol(struct rc_dev *dev, u64 *rc_type) return 0; } +/** + * ir_raw_encode_scancode() - Encode a scancode as raw events + * + * @protocols: permitted protocols + * @scancode: scancode filter describing a single scancode + * @events: array of raw events to write into + * @max: max number of raw events + * + * Attempts to encode the scancode as raw events. + * + * Returns: The number of events written. + * -ENOBUFS if there isn't enough space in the array to fit the + * encoding. In this case all @max events will have been written. + * -EINVAL if the scancode is ambiguous or invalid, or if no + * compatible encoder was found. + */ +int ir_raw_encode_scancode(u64 protocols, + const struct rc_scancode_filter *scancode, + struct ir_raw_event *events, unsigned int max) +{ + struct ir_raw_handler *handler; + int ret = -EINVAL; + + mutex_lock(&ir_raw_handler_lock); + list_for_each_entry(handler, &ir_raw_handler_list, list) { + if (handler->protocols & protocols && handler->encode) { + ret = handler->encode(protocols, scancode, events, max); + if (ret >= 0 || ret == -ENOBUFS) + break; + } + } + mutex_unlock(&ir_raw_handler_lock); + + return ret; +} +EXPORT_SYMBOL(ir_raw_encode_scancode); + /* * Used to (un)register raw event clients */ diff --git a/include/media/rc-core.h b/include/media/rc-core.h index 2c7fbca40b69..5703c082fba6 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -250,6 +250,9 @@ int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type); int ir_raw_event_store_with_filter(struct rc_dev *dev, struct ir_raw_event *ev); void ir_raw_event_set_idle(struct rc_dev *dev, bool idle); +int ir_raw_encode_scancode(u64 protocols, + const struct rc_scancode_filter *scancode, + struct ir_raw_event *events, unsigned int max); static inline void ir_raw_event_reset(struct rc_dev *dev) { -- cgit v1.2.3-59-g8ed1b From 1d971d927efa2e10194c96ed0475b6d6054342d8 Mon Sep 17 00:00:00 2001 From: Antti Seppälä Date: Tue, 31 Mar 2015 14:48:07 -0300 Subject: [media] rc: rc-ir-raw: Add Manchester encoder (phase encoder) helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adding a simple Manchester encoder to rc-core. Manchester coding is used by at least RC-5 and RC-6 protocols and their variants. Signed-off-by: Antti Seppälä Signed-off-by: James Hogan Cc: David Härdeman Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/rc-core-priv.h | 33 ++++++++++++++++ drivers/media/rc/rc-ir-raw.c | 85 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index 122c25fe91e0..5266ecc73f05 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -152,6 +152,39 @@ static inline bool is_timing_event(struct ir_raw_event ev) #define TO_US(duration) DIV_ROUND_CLOSEST((duration), 1000) #define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space") +/* functions for IR encoders */ + +static inline void init_ir_raw_event_duration(struct ir_raw_event *ev, + unsigned int pulse, + u32 duration) +{ + init_ir_raw_event(ev); + ev->duration = duration; + ev->pulse = pulse; +} + +/** + * struct ir_raw_timings_manchester - Manchester coding timings + * @leader: duration of leader pulse (if any) 0 if continuing + * existing signal (see @pulse_space_start) + * @pulse_space_start: 1 for starting with pulse (0 for starting with space) + * @clock: duration of each pulse/space in ns + * @invert: if set clock logic is inverted + * (0 = space + pulse, 1 = pulse + space) + * @trailer_space: duration of trailer space in ns + */ +struct ir_raw_timings_manchester { + unsigned int leader; + unsigned int pulse_space_start:1; + unsigned int clock; + unsigned int invert:1; + unsigned int trailer_space; +}; + +int ir_raw_gen_manchester(struct ir_raw_event **ev, unsigned int max, + const struct ir_raw_timings_manchester *timings, + unsigned int n, unsigned int data); + /* * Routines from rc-raw.c to be used internally and by decoders */ diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index dd47fe567f03..6c9580e4cac5 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -246,6 +246,91 @@ static int change_protocol(struct rc_dev *dev, u64 *rc_type) return 0; } +/** + * ir_raw_gen_manchester() - Encode data with Manchester (bi-phase) modulation. + * @ev: Pointer to pointer to next free event. *@ev is incremented for + * each raw event filled. + * @max: Maximum number of raw events to fill. + * @timings: Manchester modulation timings. + * @n: Number of bits of data. + * @data: Data bits to encode. + * + * Encodes the @n least significant bits of @data using Manchester (bi-phase) + * modulation with the timing characteristics described by @timings, writing up + * to @max raw IR events using the *@ev pointer. + * + * Returns: 0 on success. + * -ENOBUFS if there isn't enough space in the array to fit the + * full encoded data. In this case all @max events will have been + * written. + */ +int ir_raw_gen_manchester(struct ir_raw_event **ev, unsigned int max, + const struct ir_raw_timings_manchester *timings, + unsigned int n, unsigned int data) +{ + bool need_pulse; + unsigned int i; + int ret = -ENOBUFS; + + i = 1 << (n - 1); + + if (timings->leader) { + if (!max--) + return ret; + if (timings->pulse_space_start) { + init_ir_raw_event_duration((*ev)++, 1, timings->leader); + + if (!max--) + return ret; + init_ir_raw_event_duration((*ev), 0, timings->leader); + } else { + init_ir_raw_event_duration((*ev), 1, timings->leader); + } + i >>= 1; + } else { + /* continue existing signal */ + --(*ev); + } + /* from here on *ev will point to the last event rather than the next */ + + while (n && i > 0) { + need_pulse = !(data & i); + if (timings->invert) + need_pulse = !need_pulse; + if (need_pulse == !!(*ev)->pulse) { + (*ev)->duration += timings->clock; + } else { + if (!max--) + goto nobufs; + init_ir_raw_event_duration(++(*ev), need_pulse, + timings->clock); + } + + if (!max--) + goto nobufs; + init_ir_raw_event_duration(++(*ev), !need_pulse, + timings->clock); + i >>= 1; + } + + if (timings->trailer_space) { + if (!(*ev)->pulse) + (*ev)->duration += timings->trailer_space; + else if (!max--) + goto nobufs; + else + init_ir_raw_event_duration(++(*ev), 0, + timings->trailer_space); + } + + ret = 0; +nobufs: + /* point to the next event rather than last event before returning */ + ++(*ev); + return ret; +} +EXPORT_SYMBOL(ir_raw_gen_manchester); + /** * ir_raw_encode_scancode() - Encode a scancode as raw events * -- cgit v1.2.3-59-g8ed1b From a0466f15b4654cf1ac9e387d7c1a401eff494b4f Mon Sep 17 00:00:00 2001 From: James Hogan Date: Tue, 31 Mar 2015 14:48:08 -0300 Subject: [media] rc: ir-rc5-decoder: Add encode capability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the capability to encode RC-5, RC-5X and RC-5-SZ scancodes as raw events. The protocol is chosen based on the specified protocol mask, and whether all the required bits are set in the scancode mask, and none of the unused bits are set in the scancode data. For example a scancode filter with bit 16 set in both data and mask is unambiguously RC-5X. The Manchester modulation helper is used, and for RC-5X it is used twice with two sets of timings, the first with a short trailer space for the space in the middle, and the second with no leader so that it can continue the space. The encoding in RC-5-SZ first inserts a pulse and then simply utilizes the generic Manchester encoder available in rc-core. Signed-off-by: James Hogan Signed-off-by: Antti Seppälä Cc: David Härdeman Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/ir-rc5-decoder.c | 116 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/rc/ir-rc5-decoder.c b/drivers/media/rc/ir-rc5-decoder.c index 84fa6e9b59a1..8939ebd74391 100644 --- a/drivers/media/rc/ir-rc5-decoder.c +++ b/drivers/media/rc/ir-rc5-decoder.c @@ -184,9 +184,125 @@ out: return -EINVAL; } +static struct ir_raw_timings_manchester ir_rc5_timings = { + .leader = RC5_UNIT, + .pulse_space_start = 0, + .clock = RC5_UNIT, + .trailer_space = RC5_UNIT * 10, +}; + +static struct ir_raw_timings_manchester ir_rc5x_timings[2] = { + { + .leader = RC5_UNIT, + .pulse_space_start = 0, + .clock = RC5_UNIT, + .trailer_space = RC5X_SPACE, + }, + { + .clock = RC5_UNIT, + .trailer_space = RC5_UNIT * 10, + }, +}; + +static struct ir_raw_timings_manchester ir_rc5_sz_timings = { + .leader = RC5_UNIT, + .pulse_space_start = 0, + .clock = RC5_UNIT, + .trailer_space = RC5_UNIT * 10, +}; + +static int ir_rc5_validate_filter(const struct rc_scancode_filter *scancode, + unsigned int important_bits) +{ + /* all important bits of scancode should be set in mask */ + if (~scancode->mask & important_bits) + return -EINVAL; + /* extra bits in mask should be zero in data */ + if (scancode->mask & scancode->data & ~important_bits) + return -EINVAL; + return 0; +} + +/** + * ir_rc5_encode() - Encode a scancode as a stream of raw events + * + * @protocols: allowed protocols + * @scancode: scancode filter describing scancode (helps distinguish between + * protocol subtypes when scancode is ambiguous) + * @events: array of raw ir events to write into + * @max: maximum size of @events + * + * Returns: The number of events written. + * -ENOBUFS if there isn't enough space in the array to fit the + * encoding. In this case all @max events will have been written. + * -EINVAL if the scancode is ambiguous or invalid. + */ +static int ir_rc5_encode(u64 protocols, + const struct rc_scancode_filter *scancode, + struct ir_raw_event *events, unsigned int max) +{ + int ret; + struct ir_raw_event *e = events; + unsigned int data, xdata, command, commandx, system; + + /* Detect protocol and convert scancode to raw data */ + if (protocols & RC_BIT_RC5 && + !ir_rc5_validate_filter(scancode, 0x1f7f)) { + /* decode scancode */ + command = (scancode->data & 0x003f) >> 0; + commandx = (scancode->data & 0x0040) >> 6; + system = (scancode->data & 0x1f00) >> 8; + /* encode data */ + data = !commandx << 12 | system << 6 | command; + + /* Modulate the data */ + ret = ir_raw_gen_manchester(&e, max, &ir_rc5_timings, RC5_NBITS, + data); + if (ret < 0) + return ret; + } else if (protocols & RC_BIT_RC5X && + !ir_rc5_validate_filter(scancode, 0x1f7f3f)) { + /* decode scancode */ + xdata = (scancode->data & 0x00003f) >> 0; + command = (scancode->data & 0x003f00) >> 8; + commandx = (scancode->data & 0x004000) >> 14; + system = (scancode->data & 0x1f0000) >> 16; + /* commandx and system overlap, bits must match when encoded */ + if (commandx == (system & 0x1)) + return -EINVAL; + /* encode data */ + data = 1 << 18 | system << 12 | command << 6 | xdata; + + /* Modulate the data */ + ret = ir_raw_gen_manchester(&e, max, &ir_rc5x_timings[0], + CHECK_RC5X_NBITS, + data >> (RC5X_NBITS-CHECK_RC5X_NBITS)); + if (ret < 0) + return ret; + ret = ir_raw_gen_manchester(&e, max - (e - events), + &ir_rc5x_timings[1], + RC5X_NBITS - CHECK_RC5X_NBITS, + data); + if (ret < 0) + return ret; + } else if (protocols & RC_BIT_RC5_SZ && + !ir_rc5_validate_filter(scancode, 0x2fff)) { + /* RC5-SZ scancode is raw enough for Manchester as it is */ + ret = ir_raw_gen_manchester(&e, max, &ir_rc5_sz_timings, + RC5_SZ_NBITS, scancode->data & 0x2fff); + if (ret < 0) + return ret; + } else { + return -EINVAL; + } + + return e - events; +} + static struct ir_raw_handler rc5_handler = { .protocols = RC_BIT_RC5 | RC_BIT_RC5X | RC_BIT_RC5_SZ, .decode = ir_rc5_decode, + .encode = ir_rc5_encode, }; static int __init ir_rc5_decode_init(void) -- cgit v1.2.3-59-g8ed1b From cf257e288ad3a134d4bb809c542a3ae6c87ddfa3 Mon Sep 17 00:00:00 2001 From: Antti Seppälä Date: Tue, 31 Mar 2015 14:48:09 -0300 Subject: [media] rc: ir-rc6-decoder: Add encode capability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the capability to encode RC-6 and RC-6A scancodes as raw events. The protocol is chosen based on the specified protocol mask, and whether all the required bits are set in the scancode mask, and none of the unused bits are set in the scancode data. The Manchester modulation helper is used several times with various timings so that RC-6 header preamble, the header, header trailing bit and the data itself can be modulated correctly. Signed-off-by: Antti Seppälä Cc: James Hogan Cc: David Härdeman Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/ir-rc6-decoder.c | 122 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/rc/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c index d16bc67af732..f9c70baf6e0c 100644 --- a/drivers/media/rc/ir-rc6-decoder.c +++ b/drivers/media/rc/ir-rc6-decoder.c @@ -291,11 +291,133 @@ out: return -EINVAL; } +static struct ir_raw_timings_manchester ir_rc6_timings[4] = { + { + .leader = RC6_PREFIX_PULSE, + .pulse_space_start = 0, + .clock = RC6_UNIT, + .invert = 1, + .trailer_space = RC6_PREFIX_SPACE, + }, + { + .clock = RC6_UNIT, + .invert = 1, + }, + { + .clock = RC6_UNIT * 2, + .invert = 1, + }, + { + .clock = RC6_UNIT, + .invert = 1, + .trailer_space = RC6_SUFFIX_SPACE, + }, +}; + +static int ir_rc6_validate_filter(const struct rc_scancode_filter *scancode, + unsigned int important_bits) +{ + /* all important bits of scancode should be set in mask */ + if (~scancode->mask & important_bits) + return -EINVAL; + /* extra bits in mask should be zero in data */ + if (scancode->mask & scancode->data & ~important_bits) + return -EINVAL; + return 0; +} + +/** + * ir_rc6_encode() - Encode a scancode as a stream of raw events + * + * @protocols: allowed protocols + * @scancode: scancode filter describing scancode (helps distinguish between + * protocol subtypes when scancode is ambiguous) + * @events: array of raw ir events to write into + * @max: maximum size of @events + * + * Returns: The number of events written. + * -ENOBUFS if there isn't enough space in the array to fit the + * encoding. In this case all @max events will have been written. + * -EINVAL if the scancode is ambiguous or invalid. + */ +static int ir_rc6_encode(u64 protocols, + const struct rc_scancode_filter *scancode, + struct ir_raw_event *events, unsigned int max) +{ + int ret; + struct ir_raw_event *e = events; + + if (protocols & RC_BIT_RC6_0 && + !ir_rc6_validate_filter(scancode, 0xffff)) { + + /* Modulate the preamble */ + ret = ir_raw_gen_manchester(&e, max, &ir_rc6_timings[0], 0, 0); + if (ret < 0) + return ret; + + /* Modulate the header (Start Bit & Mode-0) */ + ret = ir_raw_gen_manchester(&e, max - (e - events), + &ir_rc6_timings[1], + RC6_HEADER_NBITS, (1 << 3)); + if (ret < 0) + return ret; + + /* Modulate Trailer Bit */ + ret = ir_raw_gen_manchester(&e, max - (e - events), + &ir_rc6_timings[2], 1, 0); + if (ret < 0) + return ret; + + /* Modulate rest of the data */ + ret = ir_raw_gen_manchester(&e, max - (e - events), + &ir_rc6_timings[3], RC6_0_NBITS, + scancode->data); + if (ret < 0) + return ret; + + } else if (protocols & (RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | + RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE) && + !ir_rc6_validate_filter(scancode, 0x8fffffff)) { + + /* Modulate the preamble */ + ret = ir_raw_gen_manchester(&e, max, &ir_rc6_timings[0], 0, 0); + if (ret < 0) + return ret; + + /* Modulate the header (Start Bit & Header-version 6 */ + ret = ir_raw_gen_manchester(&e, max - (e - events), + &ir_rc6_timings[1], + RC6_HEADER_NBITS, (1 << 3 | 6)); + if (ret < 0) + return ret; + + /* Modulate Trailer Bit */ + ret = ir_raw_gen_manchester(&e, max - (e - events), + &ir_rc6_timings[2], 1, 0); + if (ret < 0) + return ret; + + /* Modulate rest of the data */ + ret = ir_raw_gen_manchester(&e, max - (e - events), + &ir_rc6_timings[3], + fls(scancode->mask), + scancode->data); + if (ret < 0) + return ret; + + } else { + return -EINVAL; + } + + return e - events; +} + static struct ir_raw_handler rc6_handler = { .protocols = RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE, .decode = ir_rc6_decode, + .encode = ir_rc6_encode, }; static int __init ir_rc6_decode_init(void) -- cgit v1.2.3-59-g8ed1b From 0d830b2d1295fee82546d57185da5a6604f11ae2 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Tue, 31 Mar 2015 14:48:10 -0300 Subject: [media] rc: rc-core: Add support for encode_wakeup drivers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support in rc-core for drivers which implement the wakeup scancode filter by encoding the scancode using the raw IR encoders. This is by way of rc_dev::encode_wakeup which should be set to true to make the allowed wakeup protocols the same as the set of raw IR encoders. As well as updating the sysfs interface to know which wakeup protocols are allowed for encode_wakeup drivers, also ensure that the IR decoders/encoders are loaded when an encode_wakeup driver is registered. Signed-off-by: James Hogan Signed-off-by: Antti Seppälä Cc: David Härdeman Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/rc-core-priv.h | 1 + drivers/media/rc/rc-ir-raw.c | 17 +++++++++++++++++ drivers/media/rc/rc-main.c | 7 ++++++- include/media/rc-core.h | 3 +++ 4 files changed, 27 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index 5266ecc73f05..4b994aa2f2a7 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -189,6 +189,7 @@ int ir_raw_gen_manchester(struct ir_raw_event **ev, unsigned int max, * Routines from rc-raw.c to be used internally and by decoders */ u64 ir_raw_get_allowed_protocols(void); +u64 ir_raw_get_encode_protocols(void); int ir_raw_event_register(struct rc_dev *dev); void ir_raw_event_unregister(struct rc_dev *dev); int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler); diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index 6c9580e4cac5..b9e4645c731c 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -30,6 +30,7 @@ static LIST_HEAD(ir_raw_client_list); static DEFINE_MUTEX(ir_raw_handler_lock); static LIST_HEAD(ir_raw_handler_list); static u64 available_protocols; +static u64 encode_protocols; static int ir_raw_event_thread(void *data) { @@ -240,6 +241,18 @@ ir_raw_get_allowed_protocols(void) return protocols; } +/* used internally by the sysfs interface */ +u64 +ir_raw_get_encode_protocols(void) +{ + u64 protocols; + + mutex_lock(&ir_raw_handler_lock); + protocols = encode_protocols; + mutex_unlock(&ir_raw_handler_lock); + return protocols; +} + static int change_protocol(struct rc_dev *dev, u64 *rc_type) { /* the caller will update dev->enabled_protocols */ @@ -450,6 +463,8 @@ int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler) list_for_each_entry(raw, &ir_raw_client_list, list) ir_raw_handler->raw_register(raw->dev); available_protocols |= ir_raw_handler->protocols; + if (ir_raw_handler->encode) + encode_protocols |= ir_raw_handler->protocols; mutex_unlock(&ir_raw_handler_lock); return 0; @@ -466,6 +481,8 @@ void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler) list_for_each_entry(raw, &ir_raw_client_list, list) ir_raw_handler->raw_unregister(raw->dev); available_protocols &= ~ir_raw_handler->protocols; + if (ir_raw_handler->encode) + encode_protocols &= ~ir_raw_handler->protocols; mutex_unlock(&ir_raw_handler_lock); } EXPORT_SYMBOL(ir_raw_handler_unregister); diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 0ff388a16168..9d015db65280 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -865,6 +865,8 @@ static ssize_t show_protocols(struct device *device, } else { enabled = dev->enabled_wakeup_protocols; allowed = dev->allowed_wakeup_protocols; + if (dev->encode_wakeup && !allowed) + allowed = ir_raw_get_encode_protocols(); } mutex_unlock(&dev->lock); @@ -1406,13 +1408,16 @@ int rc_register_device(struct rc_dev *dev) path ? path : "N/A"); kfree(path); - if (dev->driver_type == RC_DRIVER_IR_RAW) { + if (dev->driver_type == RC_DRIVER_IR_RAW || dev->encode_wakeup) { /* Load raw decoders, if they aren't already */ if (!raw_init) { IR_dprintk(1, "Loading raw decoders\n"); ir_raw_init(); raw_init = true; } + } + + if (dev->driver_type == RC_DRIVER_IR_RAW) { /* calls ir_register_device so unlock mutex here*/ mutex_unlock(&dev->lock); rc = ir_raw_event_register(dev); diff --git a/include/media/rc-core.h b/include/media/rc-core.h index 5703c082fba6..9ae433c7f14b 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -74,6 +74,8 @@ enum rc_filter_type { * @input_dev: the input child device used to communicate events to userspace * @driver_type: specifies if protocol decoding is done in hardware or software * @idle: used to keep track of RX state + * @encode_wakeup: wakeup filtering uses IR encode API, therefore the allowed + * wakeup protocols is the set of all raw encoders * @allowed_protocols: bitmask with the supported RC_BIT_* protocols * @enabled_protocols: bitmask with the enabled RC_BIT_* protocols * @allowed_wakeup_protocols: bitmask with the supported RC_BIT_* wakeup protocols @@ -134,6 +136,7 @@ struct rc_dev { struct input_dev *input_dev; enum rc_driver_type driver_type; bool idle; + bool encode_wakeup; u64 allowed_protocols; u64 enabled_protocols; u64 allowed_wakeup_protocols; -- cgit v1.2.3-59-g8ed1b From 2e4ebde269236da2a41183522127715b6d9d80ce Mon Sep 17 00:00:00 2001 From: James Hogan Date: Tue, 31 Mar 2015 14:48:11 -0300 Subject: [media] rc: rc-loopback: Add loopback of filter scancodes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the s_wakeup_filter callback to the rc-loopback driver, which instead of setting the filter just feeds the scancode back through the input device so that it can be verified. Signed-off-by: James Hogan Signed-off-by: Antti Seppälä Cc: David Härdeman Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/rc-loopback.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c index 63dace8198b0..d8bdf63ce985 100644 --- a/drivers/media/rc/rc-loopback.c +++ b/drivers/media/rc/rc-loopback.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #define DRIVER_NAME "rc-loopback" @@ -176,6 +177,39 @@ static int loop_set_carrier_report(struct rc_dev *dev, int enable) return 0; } +static int loop_set_wakeup_filter(struct rc_dev *dev, + struct rc_scancode_filter *sc_filter) +{ + static const unsigned int max = 512; + struct ir_raw_event *raw; + int ret; + int i; + + /* fine to disable filter */ + if (!sc_filter->mask) + return 0; + + /* encode the specified filter and loop it back */ + raw = kmalloc_array(max, sizeof(*raw), GFP_KERNEL); + ret = ir_raw_encode_scancode(dev->enabled_wakeup_protocols, sc_filter, + raw, max); + /* still loop back the partial raw IR even if it's incomplete */ + if (ret == -ENOBUFS) + ret = max; + if (ret >= 0) { + /* do the loopback */ + for (i = 0; i < ret; ++i) + ir_raw_event_store(dev, &raw[i]); + ir_raw_event_handle(dev); + + ret = 0; + } + + kfree(raw); + + return ret; +} + static int __init loop_init(void) { struct rc_dev *rc; @@ -195,6 +229,7 @@ static int __init loop_init(void) rc->map_name = RC_MAP_EMPTY; rc->priv = &loopdev; rc->driver_type = RC_DRIVER_IR_RAW; + rc->encode_wakeup = true; rc->allowed_protocols = RC_BIT_ALL; rc->timeout = 100 * 1000 * 1000; /* 100 ms */ rc->min_timeout = 1; @@ -209,6 +244,7 @@ static int __init loop_init(void) rc->s_idle = loop_set_idle; rc->s_learning_mode = loop_set_learning_mode; rc->s_carrier_report = loop_set_carrier_report; + rc->s_wakeup_filter = loop_set_wakeup_filter; loopdev.txmask = RXMASK_REGULAR; loopdev.txcarrier = 36000; -- cgit v1.2.3-59-g8ed1b From da7ee60b03bd66bb10974d7444aa444de6391312 Mon Sep 17 00:00:00 2001 From: Antti Seppälä Date: Tue, 31 Mar 2015 14:48:12 -0300 Subject: [media] rc: nuvoton-cir: Add support for writing wakeup samples via sysfs filter callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nuvoton-cir utilizes the encoding capabilities of rc-core to convert scancodes from user space to pulse/space format understood by the underlying hardware. Converted samples are then written to the wakeup fifo along with other necessary configuration to enable wake up functionality. Signed-off-by: Antti Seppälä Signed-off-by: James Hogan Cc: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/nuvoton-cir.c | 127 +++++++++++++++++++++++++++++++++++++++++ drivers/media/rc/nuvoton-cir.h | 1 + include/media/rc-core.h | 1 + 3 files changed, 129 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index 85af7a869167..baeb5971fd52 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -526,6 +526,130 @@ static int nvt_set_tx_carrier(struct rc_dev *dev, u32 carrier) return 0; } +static int nvt_write_wakeup_codes(struct rc_dev *dev, + const u8 *wakeup_sample_buf, int count) +{ + int i = 0; + u8 reg, reg_learn_mode; + unsigned long flags; + struct nvt_dev *nvt = dev->priv; + + nvt_dbg_wake("writing wakeup samples"); + + reg = nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRCON); + reg_learn_mode = reg & ~CIR_WAKE_IRCON_MODE0; + reg_learn_mode |= CIR_WAKE_IRCON_MODE1; + + /* Lock the learn area to prevent racing with wake-isr */ + spin_lock_irqsave(&nvt->nvt_lock, flags); + + /* Enable fifo writes */ + nvt_cir_wake_reg_write(nvt, reg_learn_mode, CIR_WAKE_IRCON); + + /* Clear cir wake rx fifo */ + nvt_clear_cir_wake_fifo(nvt); + + if (count > WAKE_FIFO_LEN) { + nvt_dbg_wake("HW FIFO too small for all wake samples"); + count = WAKE_FIFO_LEN; + } + + if (count) + pr_info("Wake samples (%d) =", count); + else + pr_info("Wake sample fifo cleared"); + + /* Write wake samples to fifo */ + for (i = 0; i < count; i++) { + pr_cont(" %02x", wakeup_sample_buf[i]); + nvt_cir_wake_reg_write(nvt, wakeup_sample_buf[i], + CIR_WAKE_WR_FIFO_DATA); + } + pr_cont("\n"); + + /* Switch cir to wakeup mode and disable fifo writing */ + nvt_cir_wake_reg_write(nvt, reg, CIR_WAKE_IRCON); + + /* Set number of bytes needed for wake */ + nvt_cir_wake_reg_write(nvt, count ? count : + CIR_WAKE_FIFO_CMP_BYTES, + CIR_WAKE_FIFO_CMP_DEEP); + + spin_unlock_irqrestore(&nvt->nvt_lock, flags); + + return 0; +} + +static int nvt_ir_raw_set_wakeup_filter(struct rc_dev *dev, + struct rc_scancode_filter *sc_filter) +{ + u8 *reg_buf; + u8 buf_val; + int i, ret, count; + unsigned int val; + struct ir_raw_event *raw; + bool complete; + + /* Require both mask and data to be set before actually committing */ + if (!sc_filter->mask || !sc_filter->data) + return 0; + + raw = kmalloc_array(WAKE_FIFO_LEN, sizeof(*raw), GFP_KERNEL); + if (!raw) + return -ENOMEM; + + ret = ir_raw_encode_scancode(dev->enabled_wakeup_protocols, sc_filter, + raw, WAKE_FIFO_LEN); + complete = (ret != -ENOBUFS); + if (!complete) + ret = WAKE_FIFO_LEN; + else if (ret < 0) + goto out_raw; + + reg_buf = kmalloc_array(WAKE_FIFO_LEN, sizeof(*reg_buf), GFP_KERNEL); + if (!reg_buf) { + ret = -ENOMEM; + goto out_raw; + } + + /* Inspect the ir samples */ + for (i = 0, count = 0; i < ret && count < WAKE_FIFO_LEN; ++i) { + val = NS_TO_US((raw[i]).duration) / SAMPLE_PERIOD; + + /* Split too large values into several smaller ones */ + while (val > 0 && count < WAKE_FIFO_LEN) { + + /* Skip last value for better comparison tolerance */ + if (complete && i == ret - 1 && val < BUF_LEN_MASK) + break; + + /* Clamp values to BUF_LEN_MASK at most */ + buf_val = (val > BUF_LEN_MASK) ? BUF_LEN_MASK : val; + + reg_buf[count] = buf_val; + val -= buf_val; + if ((raw[i]).pulse) + reg_buf[count] |= BUF_PULSE_BIT; + count++; + } + } + + ret = nvt_write_wakeup_codes(dev, reg_buf, count); + + kfree(reg_buf); +out_raw: + kfree(raw); + + return ret; +} + +/* Dummy implementation. nuvoton is agnostic to the protocol used */ +static int nvt_ir_raw_change_wakeup_protocol(struct rc_dev *dev, + u64 *rc_type) +{ + return 0; +} + /* * nvt_tx_ir * @@ -1043,11 +1167,14 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) /* Set up the rc device */ rdev->priv = nvt; rdev->driver_type = RC_DRIVER_IR_RAW; + rdev->encode_wakeup = true; rdev->allowed_protocols = RC_BIT_ALL; rdev->open = nvt_open; rdev->close = nvt_close; rdev->tx_ir = nvt_tx_ir; rdev->s_tx_carrier = nvt_set_tx_carrier; + rdev->s_wakeup_filter = nvt_ir_raw_set_wakeup_filter; + rdev->change_wakeup_protocol = nvt_ir_raw_change_wakeup_protocol; rdev->input_name = "Nuvoton w836x7hg Infrared Remote Transceiver"; rdev->input_phys = "nuvoton/cir0"; rdev->input_id.bustype = BUS_HOST; diff --git a/drivers/media/rc/nuvoton-cir.h b/drivers/media/rc/nuvoton-cir.h index e1cf23c3875b..9d0e161c2a88 100644 --- a/drivers/media/rc/nuvoton-cir.h +++ b/drivers/media/rc/nuvoton-cir.h @@ -63,6 +63,7 @@ static int debug; */ #define TX_BUF_LEN 256 #define RX_BUF_LEN 32 +#define WAKE_FIFO_LEN 67 struct nvt_dev { struct pnp_dev *pdev; diff --git a/include/media/rc-core.h b/include/media/rc-core.h index 9ae433c7f14b..f1cb9daba489 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -246,6 +246,7 @@ static inline void init_ir_raw_event(struct ir_raw_event *ev) #define US_TO_NS(usec) ((usec) * 1000) #define MS_TO_US(msec) ((msec) * 1000) #define MS_TO_NS(msec) ((msec) * 1000 * 1000) +#define NS_TO_US(nsec) DIV_ROUND_UP(nsec, 1000L) void ir_raw_event_handle(struct rc_dev *dev); int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev); -- cgit v1.2.3-59-g8ed1b From 24d795d361b2cd5cb6a6915ad4df61db7a2a9bef Mon Sep 17 00:00:00 2001 From: Laurent Navet Date: Thu, 2 Apr 2015 17:33:28 -0300 Subject: [media] fc0013: remove unneeded test The same code is executed if ret is true or false, so this test can be removed. Fix Coverity CID 1268782. Signed-off-by: Laurent Navet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/fc0013.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/fc0013.c b/drivers/media/tuners/fc0013.c index b4162315773d..522690d97b42 100644 --- a/drivers/media/tuners/fc0013.c +++ b/drivers/media/tuners/fc0013.c @@ -217,8 +217,6 @@ static int fc0013_set_vhf_track(struct fc0013_priv *priv, u32 freq) } else { /* UHF and GPS */ ret = fc0013_writereg(priv, 0x1d, tmp | 0x1c); } - if (ret) - goto error_out; error_out: return ret; } -- cgit v1.2.3-59-g8ed1b From 77978089ddc90347644cc057e6b6cd169ac9abd4 Mon Sep 17 00:00:00 2001 From: Brendan McGrath Date: Fri, 10 Apr 2015 03:39:22 -0300 Subject: [media] saa7164: use an MSI interrupt when available Enhances driver to use an MSI interrupt when available. Adds the module option 'enable_msi' (type bool) which by default is enabled. Can be set to 'N' to disable. Fixes (or can reduce the occurrence of) a crash which is most commonly reported when both digital tuners of the saa7164 chip is in use. A reported example can be found here: http://permalink.gmane.org/gmane.linux.drivers.video-input-infrastructure/83948 Reviewed-by: Steven Toth Signed-off-by: Brendan McGrath Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7164/saa7164-core.c | 66 ++++++++++++++++++++++++++++---- drivers/media/pci/saa7164/saa7164.h | 1 + 2 files changed, 60 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index 90de80726f0a..3206a826b80d 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -85,6 +85,11 @@ module_param(guard_checking, int, 0644); MODULE_PARM_DESC(guard_checking, "enable dma sanity checking for buffer overruns"); +static bool enable_msi = true; +module_param(enable_msi, bool, 0444); +MODULE_PARM_DESC(enable_msi, + "enable the use of an msi interrupt if available"); + static unsigned int saa7164_devcount; static DEFINE_MUTEX(devlist); @@ -1186,6 +1191,39 @@ static int saa7164_thread_function(void *data) return 0; } +static bool saa7164_enable_msi(struct pci_dev *pci_dev, struct saa7164_dev *dev) +{ + int err; + + if (!enable_msi) { + printk(KERN_WARNING "%s() MSI disabled by module parameter 'enable_msi'" + , __func__); + return false; + } + + err = pci_enable_msi(pci_dev); + + if (err) { + printk(KERN_ERR "%s() Failed to enable MSI interrupt." + " Falling back to a shared IRQ\n", __func__); + return false; + } + + /* no error - so request an msi interrupt */ + err = request_irq(pci_dev->irq, saa7164_irq, 0, + dev->name, dev); + + if (err) { + /* fall back to legacy interrupt */ + printk(KERN_ERR "%s() Failed to get an MSI interrupt." + " Falling back to a shared IRQ\n", __func__); + pci_disable_msi(pci_dev); + return false; + } + + return true; +} + static int saa7164_initdev(struct pci_dev *pci_dev, const struct pci_device_id *pci_id) { @@ -1232,13 +1270,22 @@ static int saa7164_initdev(struct pci_dev *pci_dev, goto fail_irq; } - err = request_irq(pci_dev->irq, saa7164_irq, - IRQF_SHARED, dev->name, dev); - if (err < 0) { - printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name, - pci_dev->irq); - err = -EIO; - goto fail_irq; + /* irq bit */ + if (saa7164_enable_msi(pci_dev, dev)) { + dev->msi = true; + } else { + /* if we have an error (i.e. we don't have an interrupt) + or msi is not enabled - fallback to shared interrupt */ + + err = request_irq(pci_dev->irq, saa7164_irq, + IRQF_SHARED, dev->name, dev); + + if (err < 0) { + printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name, + pci_dev->irq); + err = -EIO; + goto fail_irq; + } } pci_set_drvdata(pci_dev, dev); @@ -1441,6 +1488,11 @@ static void saa7164_finidev(struct pci_dev *pci_dev) /* unregister stuff */ free_irq(pci_dev->irq, dev); + if (dev->msi) { + pci_disable_msi(pci_dev); + dev->msi = false; + } + pci_disable_device(pci_dev); mutex_lock(&devlist); diff --git a/drivers/media/pci/saa7164/saa7164.h b/drivers/media/pci/saa7164/saa7164.h index 138f7f93ee7d..18906e0c80e1 100644 --- a/drivers/media/pci/saa7164/saa7164.h +++ b/drivers/media/pci/saa7164/saa7164.h @@ -464,6 +464,7 @@ struct saa7164_dev { /* Interrupt status and ack registers */ u32 int_status; u32 int_ack; + bool msi; struct cmd cmds[SAA_CMD_MAX_MSG_UNITS]; struct mutex lock; -- cgit v1.2.3-59-g8ed1b From 0fae1997f09796aca8ada5edc028aef587f6716c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 13 May 2015 18:51:19 -0300 Subject: [media] dib0700: avoid the risk of forgetting to add the adapter's size For every frontend entry, we need to add the adapter's size. There are already two patches fixing it. So, it doesn't seem trivial to keep it there at the right place. Also, currently, the indentation is wrong on all places. So, it seems that keeping it right is not too trivial. Better to use a macro that would do it for us, at least while this is not converted to dvb-usb-v2. Compile-tested only. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/dib0700_devices.c | 117 +++++++++------------------- 1 file changed, 35 insertions(+), 82 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c index e87ce835dcbd..5a3dbb8c7658 100644 --- a/drivers/media/usb/dvb-usb/dib0700_devices.c +++ b/drivers/media/usb/dvb-usb/dib0700_devices.c @@ -3821,6 +3821,10 @@ MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); } \ } +#define DIB0700_NUM_FRONTENDS(n) \ + .num_frontends = n, \ + .size_of_priv = sizeof(struct dib0700_adapter_state) + struct dvb_usb_device_properties dib0700_devices[] = { { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -3828,7 +3832,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -3839,7 +3843,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = sizeof(struct dib0700_adapter_state), }, }, @@ -3893,7 +3896,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 2, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .frontend_attach = bristol_frontend_attach, .tuner_attach = bristol_tuner_attach, @@ -3901,7 +3904,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, }, { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .frontend_attach = bristol_frontend_attach, .tuner_attach = bristol_tuner_attach, @@ -3933,7 +3936,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 2, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -3944,10 +3947,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = sizeof(struct - dib0700_adapter_state), }, { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -3958,8 +3959,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x03), }}, - .size_of_priv = sizeof(struct - dib0700_adapter_state), } }, @@ -4002,7 +4001,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -4013,8 +4012,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = sizeof(struct - dib0700_adapter_state), }, }, @@ -4049,7 +4046,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -4060,7 +4057,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = sizeof(struct dib0700_adapter_state), }, }, @@ -4131,7 +4127,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -4142,7 +4138,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = sizeof(struct dib0700_adapter_state), }, }, @@ -4177,7 +4172,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 2, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -4188,9 +4183,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = sizeof(struct dib0700_adapter_state), }, { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -4201,7 +4195,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x03), }}, - .size_of_priv = sizeof(struct dib0700_adapter_state), } }, @@ -4236,7 +4229,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 2, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -4247,9 +4240,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = sizeof(struct dib0700_adapter_state), }, { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -4260,7 +4252,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x03), }}, - .size_of_priv = sizeof(struct dib0700_adapter_state), } }, @@ -4304,7 +4295,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 2, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -4315,9 +4306,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = sizeof(struct dib0700_adapter_state), }, { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -4328,7 +4318,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x03), }}, - .size_of_priv = sizeof(struct dib0700_adapter_state), } }, @@ -4355,7 +4344,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -4366,8 +4355,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = sizeof(struct - dib0700_adapter_state), }, }, @@ -4425,15 +4412,13 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .frontend_attach = s5h1411_frontend_attach, .tuner_attach = xc5000_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = sizeof(struct - dib0700_adapter_state), }, }, @@ -4463,15 +4448,13 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .frontend_attach = lgdt3305_frontend_attach, .tuner_attach = mxl5007t_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = sizeof(struct - dib0700_adapter_state), }, }, @@ -4491,7 +4474,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -4502,8 +4485,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, }, @@ -4543,7 +4524,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -4554,8 +4535,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, }, @@ -4589,7 +4568,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 2, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -4600,11 +4579,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -4615,8 +4592,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x03), }}, - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, }, @@ -4642,7 +4617,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -4654,8 +4629,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, }, @@ -4681,7 +4654,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -4693,8 +4666,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, }, @@ -4720,7 +4691,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -4732,8 +4703,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, }, @@ -4759,7 +4728,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -4771,8 +4740,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, }, @@ -4798,7 +4765,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -4810,8 +4777,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, }, @@ -4837,7 +4802,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 2, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -4849,11 +4814,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x03), }}, - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -4865,8 +4828,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, }, @@ -4892,15 +4853,13 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .frontend_attach = pctv340e_frontend_attach, .tuner_attach = xc4000_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), }}, - .size_of_priv = sizeof(struct - dib0700_adapter_state), }, }, @@ -4929,7 +4888,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -4941,9 +4900,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x03), } }, - - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, }, @@ -4969,7 +4925,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { - .num_frontends = 1, + DIB0700_NUM_FRONTENDS(1), .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -4982,9 +4938,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { DIB0700_DEFAULT_STREAMING_CONFIG(0x02), } }, - - .size_of_priv = - sizeof(struct dib0700_adapter_state), }, }, -- cgit v1.2.3-59-g8ed1b From 6802fc0b8126d8e2e5e982a9772d757e61e47c72 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 14 Apr 2015 19:52:16 -0300 Subject: [media] fc2580: implement I2C client bindings Add I2C client bindings to driver. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/fc2580.c | 101 +++++++++++++++++++++++++++++++++---- drivers/media/tuners/fc2580.h | 15 ++++++ drivers/media/tuners/fc2580_priv.h | 4 +- 3 files changed, 110 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/fc2580.c b/drivers/media/tuners/fc2580.c index f0c9c42867de..d01fba8df3c0 100644 --- a/drivers/media/tuners/fc2580.c +++ b/drivers/media/tuners/fc2580.c @@ -47,7 +47,7 @@ static int fc2580_wr_regs(struct fc2580_priv *priv, u8 reg, u8 *val, int len) u8 buf[MAX_XFER_SIZE]; struct i2c_msg msg[1] = { { - .addr = priv->cfg->i2c_addr, + .addr = priv->i2c_addr, .flags = 0, .len = 1 + len, .buf = buf, @@ -82,12 +82,12 @@ static int fc2580_rd_regs(struct fc2580_priv *priv, u8 reg, u8 *val, int len) u8 buf[MAX_XFER_SIZE]; struct i2c_msg msg[2] = { { - .addr = priv->cfg->i2c_addr, + .addr = priv->i2c_addr, .flags = 0, .len = 1, .buf = ®, }, { - .addr = priv->cfg->i2c_addr, + .addr = priv->i2c_addr, .flags = I2C_M_RD, .len = len, .buf = buf, @@ -182,10 +182,10 @@ static int fc2580_set_params(struct dvb_frontend *fe) if (ret < 0) goto err; - if (f_vco >= 2UL * 76 * priv->cfg->clock) { + if (f_vco >= 2UL * 76 * priv->clk) { r_val = 1; r18_val = 0x00; - } else if (f_vco >= 1UL * 76 * priv->cfg->clock) { + } else if (f_vco >= 1UL * 76 * priv->clk) { r_val = 2; r18_val = 0x10; } else { @@ -193,7 +193,7 @@ static int fc2580_set_params(struct dvb_frontend *fe) r18_val = 0x20; } - f_ref = 2UL * priv->cfg->clock / r_val; + f_ref = 2UL * priv->clk / r_val; n_val = div_u64_rem(f_vco, f_ref, &k_val); k_val_reg = div_u64(1ULL * k_val * (1 << 20), f_ref); @@ -213,7 +213,7 @@ static int fc2580_set_params(struct dvb_frontend *fe) if (ret < 0) goto err; - if (priv->cfg->clock >= 28000000) { + if (priv->clk >= 28000000) { ret = fc2580_wr_reg(priv, 0x4b, 0x22); if (ret < 0) goto err; @@ -348,7 +348,7 @@ static int fc2580_set_params(struct dvb_frontend *fe) if (ret < 0) goto err; - ret = fc2580_wr_reg(priv, 0x37, div_u64(1ULL * priv->cfg->clock * + ret = fc2580_wr_reg(priv, 0x37, div_u64(1ULL * priv->clk * fc2580_if_filter_lut[i].mul, 1000000000)); if (ret < 0) goto err; @@ -510,8 +510,9 @@ struct dvb_frontend *fc2580_attach(struct dvb_frontend *fe, goto err; } - priv->cfg = cfg; + priv->clk = cfg->clock; priv->i2c = i2c; + priv->i2c_addr = cfg->i2c_addr; /* check if the tuner is there */ ret = fc2580_rd_reg(priv, 0x01, &chip_id); @@ -550,6 +551,88 @@ err: } EXPORT_SYMBOL(fc2580_attach); +static int fc2580_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct fc2580_priv *dev; + struct fc2580_platform_data *pdata = client->dev.platform_data; + struct dvb_frontend *fe = pdata->dvb_frontend; + int ret; + u8 chip_id; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) { + ret = -ENOMEM; + goto err; + } + + if (pdata->clk) + dev->clk = pdata->clk; + else + dev->clk = 16384000; /* internal clock */ + dev->client = client; + dev->i2c = client->adapter; + dev->i2c_addr = client->addr; + + /* check if the tuner is there */ + ret = fc2580_rd_reg(dev, 0x01, &chip_id); + if (ret < 0) + goto err_kfree; + + dev_dbg(&client->dev, "chip_id=%02x\n", chip_id); + + switch (chip_id) { + case 0x56: + case 0x5a: + break; + default: + goto err_kfree; + } + + fe->tuner_priv = dev; + memcpy(&fe->ops.tuner_ops, &fc2580_tuner_ops, + sizeof(struct dvb_tuner_ops)); + fe->ops.tuner_ops.release = NULL; + i2c_set_clientdata(client, dev); + + dev_info(&client->dev, "FCI FC2580 successfully identified\n"); + return 0; +err_kfree: + kfree(dev); +err: + dev_dbg(&client->dev, "failed=%d\n", ret); + return ret; +} + +static int fc2580_remove(struct i2c_client *client) +{ + struct fc2580_priv *dev = i2c_get_clientdata(client); + + dev_dbg(&client->dev, "\n"); + + kfree(dev); + return 0; +} + +static const struct i2c_device_id fc2580_id_table[] = { + {"fc2580", 0}, + {} +}; +MODULE_DEVICE_TABLE(i2c, fc2580_id_table); + +static struct i2c_driver fc2580_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "fc2580", + .suppress_bind_attrs = true, + }, + .probe = fc2580_probe, + .remove = fc2580_remove, + .id_table = fc2580_id_table, +}; + +module_i2c_driver(fc2580_driver); + MODULE_DESCRIPTION("FCI FC2580 silicon tuner driver"); MODULE_AUTHOR("Antti Palosaari "); MODULE_LICENSE("GPL"); diff --git a/drivers/media/tuners/fc2580.h b/drivers/media/tuners/fc2580.h index b1ce6770f88e..5679e44980f9 100644 --- a/drivers/media/tuners/fc2580.h +++ b/drivers/media/tuners/fc2580.h @@ -24,6 +24,21 @@ #include #include "dvb_frontend.h" +/* + * I2C address + * 0x56, ... + */ + +/** + * struct fc2580_platform_data - Platform data for the fc2580 driver + * @clk: Clock frequency (0 = internal clock). + * @dvb_frontend: DVB frontend. + */ +struct fc2580_platform_data { + u32 clk; + struct dvb_frontend *dvb_frontend; +}; + struct fc2580_config { /* * I2C address diff --git a/drivers/media/tuners/fc2580_priv.h b/drivers/media/tuners/fc2580_priv.h index 646c99452136..a22ffc63749f 100644 --- a/drivers/media/tuners/fc2580_priv.h +++ b/drivers/media/tuners/fc2580_priv.h @@ -128,8 +128,10 @@ static const struct fc2580_freq_regs fc2580_freq_regs_lut[] = { }; struct fc2580_priv { - const struct fc2580_config *cfg; + u32 clk; + struct i2c_client *client; struct i2c_adapter *i2c; + u8 i2c_addr; }; #endif -- cgit v1.2.3-59-g8ed1b From 35fc0e0fcb9479a15422240050ca39aa68796a41 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 14 Apr 2015 19:55:51 -0300 Subject: [media] rtl28xxu: bind fc2580 using I2C binding Change fc2580 driver from media binding to I2C client binding. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index bcd7e0f4e978..3ff4362585df 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -1100,11 +1100,6 @@ err: return ret; } -static const struct fc2580_config rtl2832u_fc2580_config = { - .i2c_addr = 0x56, - .clock = 16384000, -}; - static struct tua9001_config rtl2832u_tua9001_config = { .i2c_addr = 0x60, }; @@ -1187,10 +1182,26 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) subdev = i2c_get_clientdata(client); } break; - case TUNER_RTL2832_FC2580: - fe = dvb_attach(fc2580_attach, adap->fe[0], - dev->demod_i2c_adapter, - &rtl2832u_fc2580_config); + case TUNER_RTL2832_FC2580: { + struct fc2580_platform_data fc2580_pdata = { + .dvb_frontend = adap->fe[0], + }; + struct i2c_board_info board_info = {}; + + strlcpy(board_info.type, "fc2580", I2C_NAME_SIZE); + board_info.addr = 0x56; + board_info.platform_data = &fc2580_pdata; + request_module("fc2580"); + client = i2c_new_device(dev->demod_i2c_adapter, + &board_info); + if (client == NULL || client->dev.driver == NULL) + break; + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + break; + } + dev->i2c_client_tuner = client; + } break; case TUNER_RTL2832_TUA9001: /* enable GPIO1 and GPIO4 as output */ -- cgit v1.2.3-59-g8ed1b From 7a893ba9c8aea4d2bd802c030cbec9dd921ef613 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 14 Apr 2015 20:07:16 -0300 Subject: [media] af9035: bind fc2580 using I2C binding Change fc2580 driver from media binding to I2C client binding. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/af9035.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index 7b7f75d8216e..5b583ff2ee8e 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c @@ -1265,11 +1265,6 @@ static struct tda18218_config af9035_tda18218_config = { .i2c_wr_max = 21, }; -static const struct fc2580_config af9035_fc2580_config = { - .i2c_addr = 0x56, - .clock = 16384000, -}; - static const struct fc0012_config af9035_fc0012_config[] = { { .i2c_address = 0x63, @@ -1390,7 +1385,11 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap) fe = dvb_attach(tda18218_attach, adap->fe[0], &d->i2c_adap, &af9035_tda18218_config); break; - case AF9033_TUNER_FC2580: + case AF9033_TUNER_FC2580: { + struct fc2580_platform_data fc2580_pdata = { + .dvb_frontend = adap->fe[0], + }; + /* Tuner enable using gpiot2_o, gpiot2_en and gpiot2_on */ ret = af9035_wr_reg_mask(d, 0xd8eb, 0x01, 0x01); if (ret < 0) @@ -1406,9 +1405,14 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap) usleep_range(10000, 50000); /* attach tuner */ - fe = dvb_attach(fc2580_attach, adap->fe[0], - &d->i2c_adap, &af9035_fc2580_config); + ret = af9035_add_i2c_dev(d, "fc2580", 0x56, &fc2580_pdata, + &d->i2c_adap); + if (ret) + goto err; + + fe = adap->fe[0]; break; + } case AF9033_TUNER_FC0012: /* * AF9035 gpiot2 = FC0012 enable @@ -1612,6 +1616,7 @@ static int af9035_tuner_detach(struct dvb_usb_adapter *adap) dev_dbg(&d->udev->dev, "%s: adap->id=%d\n", __func__, adap->id); switch (state->af9033_config[adap->id].tuner) { + case AF9033_TUNER_FC2580: case AF9033_TUNER_IT9135_38: case AF9033_TUNER_IT9135_51: case AF9033_TUNER_IT9135_52: -- cgit v1.2.3-59-g8ed1b From ef39830dda3dfa16a7fade96c0625cda55eb6209 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 14 Apr 2015 20:15:09 -0300 Subject: [media] fc2580: remove obsolete media attach All users are using driver via I2C client binding so lets remove unneeded media binding. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/fc2580.c | 72 ------------------------------------------- drivers/media/tuners/fc2580.h | 26 ---------------- 2 files changed, 98 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/fc2580.c b/drivers/media/tuners/fc2580.c index d01fba8df3c0..48e4dae37493 100644 --- a/drivers/media/tuners/fc2580.c +++ b/drivers/media/tuners/fc2580.c @@ -466,17 +466,6 @@ static int fc2580_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) return 0; } -static int fc2580_release(struct dvb_frontend *fe) -{ - struct fc2580_priv *priv = fe->tuner_priv; - - dev_dbg(&priv->i2c->dev, "%s:\n", __func__); - - kfree(fe->tuner_priv); - - return 0; -} - static const struct dvb_tuner_ops fc2580_tuner_ops = { .info = { .name = "FCI FC2580", @@ -484,8 +473,6 @@ static const struct dvb_tuner_ops fc2580_tuner_ops = { .frequency_max = 862000000, }, - .release = fc2580_release, - .init = fc2580_init, .sleep = fc2580_sleep, .set_params = fc2580_set_params, @@ -493,64 +480,6 @@ static const struct dvb_tuner_ops fc2580_tuner_ops = { .get_if_frequency = fc2580_get_if_frequency, }; -struct dvb_frontend *fc2580_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, const struct fc2580_config *cfg) -{ - struct fc2580_priv *priv; - int ret; - u8 chip_id; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - priv = kzalloc(sizeof(struct fc2580_priv), GFP_KERNEL); - if (!priv) { - ret = -ENOMEM; - dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME); - goto err; - } - - priv->clk = cfg->clock; - priv->i2c = i2c; - priv->i2c_addr = cfg->i2c_addr; - - /* check if the tuner is there */ - ret = fc2580_rd_reg(priv, 0x01, &chip_id); - if (ret < 0) - goto err; - - dev_dbg(&priv->i2c->dev, "%s: chip_id=%02x\n", __func__, chip_id); - - switch (chip_id) { - case 0x56: - case 0x5a: - break; - default: - goto err; - } - - dev_info(&priv->i2c->dev, - "%s: FCI FC2580 successfully identified\n", - KBUILD_MODNAME); - - fe->tuner_priv = priv; - memcpy(&fe->ops.tuner_ops, &fc2580_tuner_ops, - sizeof(struct dvb_tuner_ops)); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - return fe; -err: - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret); - kfree(priv); - return NULL; -} -EXPORT_SYMBOL(fc2580_attach); - static int fc2580_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -592,7 +521,6 @@ static int fc2580_probe(struct i2c_client *client, fe->tuner_priv = dev; memcpy(&fe->ops.tuner_ops, &fc2580_tuner_ops, sizeof(struct dvb_tuner_ops)); - fe->ops.tuner_ops.release = NULL; i2c_set_clientdata(client, dev); dev_info(&client->dev, "FCI FC2580 successfully identified\n"); diff --git a/drivers/media/tuners/fc2580.h b/drivers/media/tuners/fc2580.h index 5679e44980f9..61ee0e826cb9 100644 --- a/drivers/media/tuners/fc2580.h +++ b/drivers/media/tuners/fc2580.h @@ -21,7 +21,6 @@ #ifndef FC2580_H #define FC2580_H -#include #include "dvb_frontend.h" /* @@ -39,29 +38,4 @@ struct fc2580_platform_data { struct dvb_frontend *dvb_frontend; }; -struct fc2580_config { - /* - * I2C address - * 0x56, ... - */ - u8 i2c_addr; - - /* - * clock - */ - u32 clock; -}; - -#if IS_REACHABLE(CONFIG_MEDIA_TUNER_FC2580) -extern struct dvb_frontend *fc2580_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, const struct fc2580_config *cfg); -#else -static inline struct dvb_frontend *fc2580_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, const struct fc2580_config *cfg) -{ - pr_warn("%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - #endif -- cgit v1.2.3-59-g8ed1b From 46de761572b86953133776db494f6aa870183319 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 15 Apr 2015 12:10:54 -0300 Subject: [media] fc2580: improve set params logic Calculate PLL dividers slightly differently, most likely it is now correct. Move some register values to innitab. Use jiffies to poll filter lock. Fix logging. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/fc2580.c | 179 +++++++++++++++++-------------------- drivers/media/tuners/fc2580_priv.h | 8 +- 2 files changed, 88 insertions(+), 99 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/fc2580.c b/drivers/media/tuners/fc2580.c index 48e4dae37493..9324855216f5 100644 --- a/drivers/media/tuners/fc2580.c +++ b/drivers/media/tuners/fc2580.c @@ -33,11 +33,6 @@ * fc2580_wr_regs() * fc2580_rd_regs() * could not be used for accessing more than one register at once. - * - * TODO: - * Currently it blind writes bunch of static registers from the - * fc2580_freq_regs_lut[] when fc2580_set_params() is called. Add some - * logic to reduce unneeded register writes. */ /* write multiple registers */ @@ -137,107 +132,110 @@ static int fc2580_wr_reg_ff(struct fc2580_priv *priv, u8 reg, u8 val) return fc2580_wr_regs(priv, reg, &val, 1); } + static int fc2580_set_params(struct dvb_frontend *fe) { struct fc2580_priv *priv = fe->tuner_priv; + struct i2c_client *client = priv->client; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int ret = 0, i; - unsigned int r_val, n_val, k_val, k_val_reg, f_ref; - u8 tmp_val, r18_val; + int ret, i; + unsigned int uitmp, div_ref, div_ref_val, div_n, k, k_cw, div_out; u64 f_vco; + u8 u8tmp, synth_config; + unsigned long timeout; - /* - * Fractional-N synthesizer/PLL. - * Most likely all those PLL calculations are not correct. I am not - * sure, but it looks like it is divider based Fractional-N synthesizer. - * There is divider for reference clock too? - * Anyhow, synthesizer calculation results seems to be quite correct. - */ - - dev_dbg(&priv->i2c->dev, "%s: delivery_system=%d frequency=%d " \ - "bandwidth_hz=%d\n", __func__, - c->delivery_system, c->frequency, c->bandwidth_hz); + dev_dbg(&client->dev, + "delivery_system=%u frequency=%u bandwidth_hz=%u\n", + c->delivery_system, c->frequency, c->bandwidth_hz); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - /* PLL */ + /* + * Fractional-N synthesizer + * + * +---------------------------------------+ + * v | + * Fref +----+ +----+ +-------+ +----+ +------+ +---+ + * ------> | /R | --> | PD | --> | VCO | ------> | /2 | --> | /N.F | <-- | K | + * +----+ +----+ +-------+ +----+ +------+ +---+ + * | + * | + * v + * +-------+ Fout + * | /Rout | ------> + * +-------+ + */ for (i = 0; i < ARRAY_SIZE(fc2580_pll_lut); i++) { if (c->frequency <= fc2580_pll_lut[i].freq) break; } - - if (i == ARRAY_SIZE(fc2580_pll_lut)) + if (i == ARRAY_SIZE(fc2580_pll_lut)) { + ret = -EINVAL; goto err; + } - f_vco = c->frequency; - f_vco *= fc2580_pll_lut[i].div; - - if (f_vco >= 2600000000UL) - tmp_val = 0x0e | fc2580_pll_lut[i].band; + #define DIV_PRE_N 2 + #define F_REF priv->clk + div_out = fc2580_pll_lut[i].div_out; + f_vco = (u64) c->frequency * div_out; + synth_config = fc2580_pll_lut[i].band; + if (f_vco < 2600000000ULL) + synth_config |= 0x06; else - tmp_val = 0x06 | fc2580_pll_lut[i].band; - - ret = fc2580_wr_reg(priv, 0x02, tmp_val); - if (ret < 0) - goto err; - - if (f_vco >= 2UL * 76 * priv->clk) { - r_val = 1; - r18_val = 0x00; - } else if (f_vco >= 1UL * 76 * priv->clk) { - r_val = 2; - r18_val = 0x10; + synth_config |= 0x0e; + + /* select reference divider R (keep PLL div N in valid range) */ + #define DIV_N_MIN 76 + if (f_vco >= div_u64((u64) DIV_PRE_N * DIV_N_MIN * F_REF, 1)) { + div_ref = 1; + div_ref_val = 0x00; + } else if (f_vco >= div_u64((u64) DIV_PRE_N * DIV_N_MIN * F_REF, 2)) { + div_ref = 2; + div_ref_val = 0x10; } else { - r_val = 4; - r18_val = 0x20; + div_ref = 4; + div_ref_val = 0x20; } - f_ref = 2UL * priv->clk / r_val; - n_val = div_u64_rem(f_vco, f_ref, &k_val); - k_val_reg = div_u64(1ULL * k_val * (1 << 20), f_ref); + /* calculate PLL integer and fractional control word */ + uitmp = DIV_PRE_N * F_REF / div_ref; + div_n = div_u64_rem(f_vco, uitmp, &k); + k_cw = div_u64((u64) k * 0x100000, uitmp); - ret = fc2580_wr_reg(priv, 0x18, r18_val | ((k_val_reg >> 16) & 0xff)); + dev_dbg(&client->dev, + "frequency=%u f_vco=%llu F_REF=%u div_ref=%u div_n=%u k=%u div_out=%u k_cw=%0x\n", + c->frequency, f_vco, F_REF, div_ref, div_n, k, div_out, k_cw); + + ret = fc2580_wr_reg(priv, 0x02, synth_config); if (ret < 0) goto err; - ret = fc2580_wr_reg(priv, 0x1a, (k_val_reg >> 8) & 0xff); + ret = fc2580_wr_reg(priv, 0x18, div_ref_val << 0 | k_cw >> 16); if (ret < 0) goto err; - ret = fc2580_wr_reg(priv, 0x1b, (k_val_reg >> 0) & 0xff); + ret = fc2580_wr_reg(priv, 0x1a, (k_cw >> 8) & 0xff); if (ret < 0) goto err; - ret = fc2580_wr_reg(priv, 0x1c, n_val); + ret = fc2580_wr_reg(priv, 0x1b, (k_cw >> 0) & 0xff); if (ret < 0) goto err; - if (priv->clk >= 28000000) { - ret = fc2580_wr_reg(priv, 0x4b, 0x22); - if (ret < 0) - goto err; - } - - if (fc2580_pll_lut[i].band == 0x00) { - if (c->frequency <= 794000000) - tmp_val = 0x9f; - else - tmp_val = 0x8f; - - ret = fc2580_wr_reg(priv, 0x2d, tmp_val); - if (ret < 0) - goto err; - } + ret = fc2580_wr_reg(priv, 0x1c, div_n); + if (ret < 0) + goto err; /* registers */ for (i = 0; i < ARRAY_SIZE(fc2580_freq_regs_lut); i++) { if (c->frequency <= fc2580_freq_regs_lut[i].freq) break; } - - if (i == ARRAY_SIZE(fc2580_freq_regs_lut)) + if (i == ARRAY_SIZE(fc2580_freq_regs_lut)) { + ret = -EINVAL; goto err; + } ret = fc2580_wr_reg_ff(priv, 0x25, fc2580_freq_regs_lut[i].r25_val); if (ret < 0) @@ -340,16 +338,18 @@ static int fc2580_set_params(struct dvb_frontend *fe) if (c->bandwidth_hz <= fc2580_if_filter_lut[i].freq) break; } - - if (i == ARRAY_SIZE(fc2580_if_filter_lut)) + if (i == ARRAY_SIZE(fc2580_if_filter_lut)) { + ret = -EINVAL; goto err; + } ret = fc2580_wr_reg(priv, 0x36, fc2580_if_filter_lut[i].r36_val); if (ret < 0) goto err; - ret = fc2580_wr_reg(priv, 0x37, div_u64(1ULL * priv->clk * - fc2580_if_filter_lut[i].mul, 1000000000)); + u8tmp = div_u64((u64) priv->clk * fc2580_if_filter_lut[i].mul, + 1000000000); + ret = fc2580_wr_reg(priv, 0x37, u8tmp); if (ret < 0) goto err; @@ -357,36 +357,25 @@ static int fc2580_set_params(struct dvb_frontend *fe) if (ret < 0) goto err; - /* calibration? */ - ret = fc2580_wr_reg(priv, 0x2e, 0x09); - if (ret < 0) - goto err; - - for (i = 0; i < 5; i++) { - ret = fc2580_rd_reg(priv, 0x2f, &tmp_val); - if (ret < 0) + timeout = jiffies + msecs_to_jiffies(30); + for (uitmp = ~0xc0; !time_after(jiffies, timeout) && uitmp != 0xc0;) { + /* trigger filter */ + ret = fc2580_wr_reg(priv, 0x2e, 0x09); + if (ret) goto err; - /* done when [7:6] are set */ - if ((tmp_val & 0xc0) == 0xc0) - break; - - ret = fc2580_wr_reg(priv, 0x2e, 0x01); - if (ret < 0) + /* locked when [7:6] are set (val: d7 6MHz, d5 7MHz, cd 8MHz) */ + ret = fc2580_rd_reg(priv, 0x2f, &u8tmp); + if (ret) goto err; + uitmp = u8tmp & 0xc0; - ret = fc2580_wr_reg(priv, 0x2e, 0x09); - if (ret < 0) + ret = fc2580_wr_reg(priv, 0x2e, 0x01); + if (ret) goto err; - - usleep_range(5000, 25000); } - - dev_dbg(&priv->i2c->dev, "%s: loop=%i\n", __func__, i); - - ret = fc2580_wr_reg(priv, 0x2e, 0x01); - if (ret < 0) - goto err; + if (uitmp != 0xc0) + dev_dbg(&client->dev, "filter did not lock %02x\n", uitmp); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); @@ -396,7 +385,7 @@ err: if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } diff --git a/drivers/media/tuners/fc2580_priv.h b/drivers/media/tuners/fc2580_priv.h index a22ffc63749f..068531b70078 100644 --- a/drivers/media/tuners/fc2580_priv.h +++ b/drivers/media/tuners/fc2580_priv.h @@ -50,7 +50,7 @@ static const struct fc2580_reg_val fc2580_init_reg_vals[] = { struct fc2580_pll { u32 freq; - u8 div; + u8 div_out; u8 band; }; @@ -110,15 +110,15 @@ static const struct fc2580_freq_regs fc2580_freq_regs_lut[] = { 0x50, 0x0f, 0x07, 0x00, 0x15, 0x03, 0x05, 0x10, 0x12, 0x08, 0x0a, 0x78, 0x32, 0x54}, { 538000000, - 0xf0, 0x77, 0x53, 0x60, 0xff, 0xff, 0xff, 0x09, 0xff, 0x8c, + 0xf0, 0x77, 0x53, 0x60, 0xff, 0xff, 0x9f, 0x09, 0xff, 0x8c, 0x50, 0x13, 0x07, 0x06, 0x15, 0x06, 0x08, 0x10, 0x12, 0x0b, 0x0c, 0x78, 0x32, 0x14}, { 794000000, - 0xf0, 0x77, 0x53, 0x60, 0xff, 0xff, 0xff, 0x09, 0xff, 0x8c, + 0xf0, 0x77, 0x53, 0x60, 0xff, 0xff, 0x9f, 0x09, 0xff, 0x8c, 0x50, 0x15, 0x03, 0x03, 0x15, 0x03, 0x05, 0x0c, 0x0e, 0x0b, 0x0c, 0x78, 0x32, 0x14}, {1000000000, - 0xf0, 0x77, 0x53, 0x60, 0xff, 0xff, 0xff, 0x09, 0xff, 0x8c, + 0xf0, 0x77, 0x53, 0x60, 0xff, 0xff, 0x8f, 0x09, 0xff, 0x8c, 0x50, 0x15, 0x07, 0x06, 0x15, 0x07, 0x09, 0x10, 0x12, 0x0b, 0x0c, 0x78, 0x32, 0x14}, {0xffffffff, -- cgit v1.2.3-59-g8ed1b From 154cdfb03df77dc09ab07243dc531ad0ff1cc044 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 15 Apr 2015 12:35:47 -0300 Subject: [media] fc2580: cleanups and variable renames Rename driver state from priv to dev. Remove legacy i2c-gate control. Use I2C client for proper dev_() logging. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/fc2580.c | 172 ++++++++++++++++--------------------- drivers/media/tuners/fc2580_priv.h | 2 +- 2 files changed, 76 insertions(+), 98 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/fc2580.c b/drivers/media/tuners/fc2580.c index 9324855216f5..f4b31db5f826 100644 --- a/drivers/media/tuners/fc2580.c +++ b/drivers/media/tuners/fc2580.c @@ -36,13 +36,14 @@ */ /* write multiple registers */ -static int fc2580_wr_regs(struct fc2580_priv *priv, u8 reg, u8 *val, int len) +static int fc2580_wr_regs(struct fc2580_dev *dev, u8 reg, u8 *val, int len) { + struct i2c_client *client = dev->client; int ret; u8 buf[MAX_XFER_SIZE]; struct i2c_msg msg[1] = { { - .addr = priv->i2c_addr, + .addr = dev->i2c_addr, .flags = 0, .len = 1 + len, .buf = buf, @@ -50,7 +51,7 @@ static int fc2580_wr_regs(struct fc2580_priv *priv, u8 reg, u8 *val, int len) }; if (1 + len > sizeof(buf)) { - dev_warn(&priv->i2c->dev, + dev_warn(&client->dev, "%s: i2c wr reg=%04x: len=%d is too big!\n", KBUILD_MODNAME, reg, len); return -EINVAL; @@ -59,30 +60,31 @@ static int fc2580_wr_regs(struct fc2580_priv *priv, u8 reg, u8 *val, int len) buf[0] = reg; memcpy(&buf[1], val, len); - ret = i2c_transfer(priv->i2c, msg, 1); + ret = i2c_transfer(dev->i2c, msg, 1); if (ret == 1) { ret = 0; } else { - dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \ - "len=%d\n", KBUILD_MODNAME, ret, reg, len); + dev_warn(&dev->i2c->dev, "%s: i2c wr failed=%d reg=%02x len=%d\n", + KBUILD_MODNAME, ret, reg, len); ret = -EREMOTEIO; } return ret; } /* read multiple registers */ -static int fc2580_rd_regs(struct fc2580_priv *priv, u8 reg, u8 *val, int len) +static int fc2580_rd_regs(struct fc2580_dev *dev, u8 reg, u8 *val, int len) { + struct i2c_client *client = dev->client; int ret; u8 buf[MAX_XFER_SIZE]; struct i2c_msg msg[2] = { { - .addr = priv->i2c_addr, + .addr = dev->i2c_addr, .flags = 0, .len = 1, .buf = ®, }, { - .addr = priv->i2c_addr, + .addr = dev->i2c_addr, .flags = I2C_M_RD, .len = len, .buf = buf, @@ -90,19 +92,19 @@ static int fc2580_rd_regs(struct fc2580_priv *priv, u8 reg, u8 *val, int len) }; if (len > sizeof(buf)) { - dev_warn(&priv->i2c->dev, + dev_warn(&client->dev, "%s: i2c rd reg=%04x: len=%d is too big!\n", KBUILD_MODNAME, reg, len); return -EINVAL; } - ret = i2c_transfer(priv->i2c, msg, 2); + ret = i2c_transfer(dev->i2c, msg, 2); if (ret == 2) { memcpy(val, buf, len); ret = 0; } else { - dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \ - "len=%d\n", KBUILD_MODNAME, ret, reg, len); + dev_warn(&client->dev, "%s: i2c rd failed=%d reg=%02x len=%d\n", + KBUILD_MODNAME, ret, reg, len); ret = -EREMOTEIO; } @@ -110,33 +112,33 @@ static int fc2580_rd_regs(struct fc2580_priv *priv, u8 reg, u8 *val, int len) } /* write single register */ -static int fc2580_wr_reg(struct fc2580_priv *priv, u8 reg, u8 val) +static int fc2580_wr_reg(struct fc2580_dev *dev, u8 reg, u8 val) { - return fc2580_wr_regs(priv, reg, &val, 1); + return fc2580_wr_regs(dev, reg, &val, 1); } /* read single register */ -static int fc2580_rd_reg(struct fc2580_priv *priv, u8 reg, u8 *val) +static int fc2580_rd_reg(struct fc2580_dev *dev, u8 reg, u8 *val) { - return fc2580_rd_regs(priv, reg, val, 1); + return fc2580_rd_regs(dev, reg, val, 1); } /* write single register conditionally only when value differs from 0xff * XXX: This is special routine meant only for writing fc2580_freq_regs_lut[] * values. Do not use for the other purposes. */ -static int fc2580_wr_reg_ff(struct fc2580_priv *priv, u8 reg, u8 val) +static int fc2580_wr_reg_ff(struct fc2580_dev *dev, u8 reg, u8 val) { if (val == 0xff) return 0; else - return fc2580_wr_regs(priv, reg, &val, 1); + return fc2580_wr_regs(dev, reg, &val, 1); } static int fc2580_set_params(struct dvb_frontend *fe) { - struct fc2580_priv *priv = fe->tuner_priv; - struct i2c_client *client = priv->client; + struct fc2580_dev *dev = fe->tuner_priv; + struct i2c_client *client = dev->client; struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, i; unsigned int uitmp, div_ref, div_ref_val, div_n, k, k_cw, div_out; @@ -148,9 +150,6 @@ static int fc2580_set_params(struct dvb_frontend *fe) "delivery_system=%u frequency=%u bandwidth_hz=%u\n", c->delivery_system, c->frequency, c->bandwidth_hz); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - /* * Fractional-N synthesizer * @@ -176,7 +175,7 @@ static int fc2580_set_params(struct dvb_frontend *fe) } #define DIV_PRE_N 2 - #define F_REF priv->clk + #define F_REF dev->clk div_out = fc2580_pll_lut[i].div_out; f_vco = (u64) c->frequency * div_out; synth_config = fc2580_pll_lut[i].band; @@ -207,23 +206,23 @@ static int fc2580_set_params(struct dvb_frontend *fe) "frequency=%u f_vco=%llu F_REF=%u div_ref=%u div_n=%u k=%u div_out=%u k_cw=%0x\n", c->frequency, f_vco, F_REF, div_ref, div_n, k, div_out, k_cw); - ret = fc2580_wr_reg(priv, 0x02, synth_config); + ret = fc2580_wr_reg(dev, 0x02, synth_config); if (ret < 0) goto err; - ret = fc2580_wr_reg(priv, 0x18, div_ref_val << 0 | k_cw >> 16); + ret = fc2580_wr_reg(dev, 0x18, div_ref_val << 0 | k_cw >> 16); if (ret < 0) goto err; - ret = fc2580_wr_reg(priv, 0x1a, (k_cw >> 8) & 0xff); + ret = fc2580_wr_reg(dev, 0x1a, (k_cw >> 8) & 0xff); if (ret < 0) goto err; - ret = fc2580_wr_reg(priv, 0x1b, (k_cw >> 0) & 0xff); + ret = fc2580_wr_reg(dev, 0x1b, (k_cw >> 0) & 0xff); if (ret < 0) goto err; - ret = fc2580_wr_reg(priv, 0x1c, div_n); + ret = fc2580_wr_reg(dev, 0x1c, div_n); if (ret < 0) goto err; @@ -237,99 +236,99 @@ static int fc2580_set_params(struct dvb_frontend *fe) goto err; } - ret = fc2580_wr_reg_ff(priv, 0x25, fc2580_freq_regs_lut[i].r25_val); + ret = fc2580_wr_reg_ff(dev, 0x25, fc2580_freq_regs_lut[i].r25_val); if (ret < 0) goto err; - ret = fc2580_wr_reg_ff(priv, 0x27, fc2580_freq_regs_lut[i].r27_val); + ret = fc2580_wr_reg_ff(dev, 0x27, fc2580_freq_regs_lut[i].r27_val); if (ret < 0) goto err; - ret = fc2580_wr_reg_ff(priv, 0x28, fc2580_freq_regs_lut[i].r28_val); + ret = fc2580_wr_reg_ff(dev, 0x28, fc2580_freq_regs_lut[i].r28_val); if (ret < 0) goto err; - ret = fc2580_wr_reg_ff(priv, 0x29, fc2580_freq_regs_lut[i].r29_val); + ret = fc2580_wr_reg_ff(dev, 0x29, fc2580_freq_regs_lut[i].r29_val); if (ret < 0) goto err; - ret = fc2580_wr_reg_ff(priv, 0x2b, fc2580_freq_regs_lut[i].r2b_val); + ret = fc2580_wr_reg_ff(dev, 0x2b, fc2580_freq_regs_lut[i].r2b_val); if (ret < 0) goto err; - ret = fc2580_wr_reg_ff(priv, 0x2c, fc2580_freq_regs_lut[i].r2c_val); + ret = fc2580_wr_reg_ff(dev, 0x2c, fc2580_freq_regs_lut[i].r2c_val); if (ret < 0) goto err; - ret = fc2580_wr_reg_ff(priv, 0x2d, fc2580_freq_regs_lut[i].r2d_val); + ret = fc2580_wr_reg_ff(dev, 0x2d, fc2580_freq_regs_lut[i].r2d_val); if (ret < 0) goto err; - ret = fc2580_wr_reg_ff(priv, 0x30, fc2580_freq_regs_lut[i].r30_val); + ret = fc2580_wr_reg_ff(dev, 0x30, fc2580_freq_regs_lut[i].r30_val); if (ret < 0) goto err; - ret = fc2580_wr_reg_ff(priv, 0x44, fc2580_freq_regs_lut[i].r44_val); + ret = fc2580_wr_reg_ff(dev, 0x44, fc2580_freq_regs_lut[i].r44_val); if (ret < 0) goto err; - ret = fc2580_wr_reg_ff(priv, 0x50, fc2580_freq_regs_lut[i].r50_val); + ret = fc2580_wr_reg_ff(dev, 0x50, fc2580_freq_regs_lut[i].r50_val); if (ret < 0) goto err; - ret = fc2580_wr_reg_ff(priv, 0x53, fc2580_freq_regs_lut[i].r53_val); + ret = fc2580_wr_reg_ff(dev, 0x53, fc2580_freq_regs_lut[i].r53_val); if (ret < 0) goto err; - ret = fc2580_wr_reg_ff(priv, 0x5f, fc2580_freq_regs_lut[i].r5f_val); + ret = fc2580_wr_reg_ff(dev, 0x5f, fc2580_freq_regs_lut[i].r5f_val); if (ret < 0) goto err; - ret = fc2580_wr_reg_ff(priv, 0x61, fc2580_freq_regs_lut[i].r61_val); + ret = fc2580_wr_reg_ff(dev, 0x61, fc2580_freq_regs_lut[i].r61_val); if (ret < 0) goto err; - ret = fc2580_wr_reg_ff(priv, 0x62, fc2580_freq_regs_lut[i].r62_val); + ret = fc2580_wr_reg_ff(dev, 0x62, fc2580_freq_regs_lut[i].r62_val); if (ret < 0) goto err; - ret = fc2580_wr_reg_ff(priv, 0x63, fc2580_freq_regs_lut[i].r63_val); + ret = fc2580_wr_reg_ff(dev, 0x63, fc2580_freq_regs_lut[i].r63_val); if (ret < 0) goto err; - ret = fc2580_wr_reg_ff(priv, 0x67, fc2580_freq_regs_lut[i].r67_val); + ret = fc2580_wr_reg_ff(dev, 0x67, fc2580_freq_regs_lut[i].r67_val); if (ret < 0) goto err; - ret = fc2580_wr_reg_ff(priv, 0x68, fc2580_freq_regs_lut[i].r68_val); + ret = fc2580_wr_reg_ff(dev, 0x68, fc2580_freq_regs_lut[i].r68_val); if (ret < 0) goto err; - ret = fc2580_wr_reg_ff(priv, 0x69, fc2580_freq_regs_lut[i].r69_val); + ret = fc2580_wr_reg_ff(dev, 0x69, fc2580_freq_regs_lut[i].r69_val); if (ret < 0) goto err; - ret = fc2580_wr_reg_ff(priv, 0x6a, fc2580_freq_regs_lut[i].r6a_val); + ret = fc2580_wr_reg_ff(dev, 0x6a, fc2580_freq_regs_lut[i].r6a_val); if (ret < 0) goto err; - ret = fc2580_wr_reg_ff(priv, 0x6b, fc2580_freq_regs_lut[i].r6b_val); + ret = fc2580_wr_reg_ff(dev, 0x6b, fc2580_freq_regs_lut[i].r6b_val); if (ret < 0) goto err; - ret = fc2580_wr_reg_ff(priv, 0x6c, fc2580_freq_regs_lut[i].r6c_val); + ret = fc2580_wr_reg_ff(dev, 0x6c, fc2580_freq_regs_lut[i].r6c_val); if (ret < 0) goto err; - ret = fc2580_wr_reg_ff(priv, 0x6d, fc2580_freq_regs_lut[i].r6d_val); + ret = fc2580_wr_reg_ff(dev, 0x6d, fc2580_freq_regs_lut[i].r6d_val); if (ret < 0) goto err; - ret = fc2580_wr_reg_ff(priv, 0x6e, fc2580_freq_regs_lut[i].r6e_val); + ret = fc2580_wr_reg_ff(dev, 0x6e, fc2580_freq_regs_lut[i].r6e_val); if (ret < 0) goto err; - ret = fc2580_wr_reg_ff(priv, 0x6f, fc2580_freq_regs_lut[i].r6f_val); + ret = fc2580_wr_reg_ff(dev, 0x6f, fc2580_freq_regs_lut[i].r6f_val); if (ret < 0) goto err; @@ -343,112 +342,91 @@ static int fc2580_set_params(struct dvb_frontend *fe) goto err; } - ret = fc2580_wr_reg(priv, 0x36, fc2580_if_filter_lut[i].r36_val); + ret = fc2580_wr_reg(dev, 0x36, fc2580_if_filter_lut[i].r36_val); if (ret < 0) goto err; - u8tmp = div_u64((u64) priv->clk * fc2580_if_filter_lut[i].mul, + u8tmp = div_u64((u64) dev->clk * fc2580_if_filter_lut[i].mul, 1000000000); - ret = fc2580_wr_reg(priv, 0x37, u8tmp); + ret = fc2580_wr_reg(dev, 0x37, u8tmp); if (ret < 0) goto err; - ret = fc2580_wr_reg(priv, 0x39, fc2580_if_filter_lut[i].r39_val); + ret = fc2580_wr_reg(dev, 0x39, fc2580_if_filter_lut[i].r39_val); if (ret < 0) goto err; timeout = jiffies + msecs_to_jiffies(30); for (uitmp = ~0xc0; !time_after(jiffies, timeout) && uitmp != 0xc0;) { /* trigger filter */ - ret = fc2580_wr_reg(priv, 0x2e, 0x09); + ret = fc2580_wr_reg(dev, 0x2e, 0x09); if (ret) goto err; /* locked when [7:6] are set (val: d7 6MHz, d5 7MHz, cd 8MHz) */ - ret = fc2580_rd_reg(priv, 0x2f, &u8tmp); + ret = fc2580_rd_reg(dev, 0x2f, &u8tmp); if (ret) goto err; uitmp = u8tmp & 0xc0; - ret = fc2580_wr_reg(priv, 0x2e, 0x01); + ret = fc2580_wr_reg(dev, 0x2e, 0x01); if (ret) goto err; } if (uitmp != 0xc0) dev_dbg(&client->dev, "filter did not lock %02x\n", uitmp); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - return 0; err: - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int fc2580_init(struct dvb_frontend *fe) { - struct fc2580_priv *priv = fe->tuner_priv; + struct fc2580_dev *dev = fe->tuner_priv; + struct i2c_client *client = dev->client; int ret, i; - dev_dbg(&priv->i2c->dev, "%s:\n", __func__); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); + dev_dbg(&client->dev, "\n"); for (i = 0; i < ARRAY_SIZE(fc2580_init_reg_vals); i++) { - ret = fc2580_wr_reg(priv, fc2580_init_reg_vals[i].reg, + ret = fc2580_wr_reg(dev, fc2580_init_reg_vals[i].reg, fc2580_init_reg_vals[i].val); if (ret < 0) goto err; } - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - return 0; err: - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int fc2580_sleep(struct dvb_frontend *fe) { - struct fc2580_priv *priv = fe->tuner_priv; + struct fc2580_dev *dev = fe->tuner_priv; + struct i2c_client *client = dev->client; int ret; - dev_dbg(&priv->i2c->dev, "%s:\n", __func__); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); + dev_dbg(&client->dev, "\n"); - ret = fc2580_wr_reg(priv, 0x02, 0x0a); + ret = fc2580_wr_reg(dev, 0x02, 0x0a); if (ret < 0) goto err; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - return 0; err: - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int fc2580_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) { - struct fc2580_priv *priv = fe->tuner_priv; + struct fc2580_dev *dev = fe->tuner_priv; + struct i2c_client *client = dev->client; - dev_dbg(&priv->i2c->dev, "%s:\n", __func__); + dev_dbg(&client->dev, "\n"); *frequency = 0; /* Zero-IF */ @@ -472,7 +450,7 @@ static const struct dvb_tuner_ops fc2580_tuner_ops = { static int fc2580_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct fc2580_priv *dev; + struct fc2580_dev *dev; struct fc2580_platform_data *pdata = client->dev.platform_data; struct dvb_frontend *fe = pdata->dvb_frontend; int ret; @@ -523,7 +501,7 @@ err: static int fc2580_remove(struct i2c_client *client) { - struct fc2580_priv *dev = i2c_get_clientdata(client); + struct fc2580_dev *dev = i2c_get_clientdata(client); dev_dbg(&client->dev, "\n"); diff --git a/drivers/media/tuners/fc2580_priv.h b/drivers/media/tuners/fc2580_priv.h index 068531b70078..16245ee878b1 100644 --- a/drivers/media/tuners/fc2580_priv.h +++ b/drivers/media/tuners/fc2580_priv.h @@ -127,7 +127,7 @@ static const struct fc2580_freq_regs fc2580_freq_regs_lut[] = { 0x0a, 0xa0, 0x50, 0x14}, }; -struct fc2580_priv { +struct fc2580_dev { u32 clk; struct i2c_client *client; struct i2c_adapter *i2c; -- cgit v1.2.3-59-g8ed1b From 35fe4c65334bc88321450a8418ce37b69e2e09cb Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 15 Apr 2015 13:51:29 -0300 Subject: [media] fc2580: use regmap for register I2C access Replace home made register access routines with regmap. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/Kconfig | 1 + drivers/media/tuners/fc2580.c | 216 +++++++++++-------------------------- drivers/media/tuners/fc2580_priv.h | 4 +- 3 files changed, 66 insertions(+), 155 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig index db4caf2b4669..26961da7ac03 100644 --- a/drivers/media/tuners/Kconfig +++ b/drivers/media/tuners/Kconfig @@ -220,6 +220,7 @@ config MEDIA_TUNER_E4000 config MEDIA_TUNER_FC2580 tristate "FCI FC2580 silicon tuner" depends on MEDIA_SUPPORT && I2C + select REGMAP_I2C default m if !MEDIA_SUBDRV_AUTOSELECT help FCI FC2580 silicon tuner driver. diff --git a/drivers/media/tuners/fc2580.c b/drivers/media/tuners/fc2580.c index f4b31db5f826..08838b4b4821 100644 --- a/drivers/media/tuners/fc2580.c +++ b/drivers/media/tuners/fc2580.c @@ -20,109 +20,13 @@ #include "fc2580_priv.h" -/* Max transfer size done by I2C transfer functions */ -#define MAX_XFER_SIZE 64 - /* * TODO: * I2C write and read works only for one single register. Multiple registers * could not be accessed using normal register address auto-increment. * There could be (very likely) register to change that behavior.... - * - * Due to that limitation functions: - * fc2580_wr_regs() - * fc2580_rd_regs() - * could not be used for accessing more than one register at once. */ -/* write multiple registers */ -static int fc2580_wr_regs(struct fc2580_dev *dev, u8 reg, u8 *val, int len) -{ - struct i2c_client *client = dev->client; - int ret; - u8 buf[MAX_XFER_SIZE]; - struct i2c_msg msg[1] = { - { - .addr = dev->i2c_addr, - .flags = 0, - .len = 1 + len, - .buf = buf, - } - }; - - if (1 + len > sizeof(buf)) { - dev_warn(&client->dev, - "%s: i2c wr reg=%04x: len=%d is too big!\n", - KBUILD_MODNAME, reg, len); - return -EINVAL; - } - - buf[0] = reg; - memcpy(&buf[1], val, len); - - ret = i2c_transfer(dev->i2c, msg, 1); - if (ret == 1) { - ret = 0; - } else { - dev_warn(&dev->i2c->dev, "%s: i2c wr failed=%d reg=%02x len=%d\n", - KBUILD_MODNAME, ret, reg, len); - ret = -EREMOTEIO; - } - return ret; -} - -/* read multiple registers */ -static int fc2580_rd_regs(struct fc2580_dev *dev, u8 reg, u8 *val, int len) -{ - struct i2c_client *client = dev->client; - int ret; - u8 buf[MAX_XFER_SIZE]; - struct i2c_msg msg[2] = { - { - .addr = dev->i2c_addr, - .flags = 0, - .len = 1, - .buf = ®, - }, { - .addr = dev->i2c_addr, - .flags = I2C_M_RD, - .len = len, - .buf = buf, - } - }; - - if (len > sizeof(buf)) { - dev_warn(&client->dev, - "%s: i2c rd reg=%04x: len=%d is too big!\n", - KBUILD_MODNAME, reg, len); - return -EINVAL; - } - - ret = i2c_transfer(dev->i2c, msg, 2); - if (ret == 2) { - memcpy(val, buf, len); - ret = 0; - } else { - dev_warn(&client->dev, "%s: i2c rd failed=%d reg=%02x len=%d\n", - KBUILD_MODNAME, ret, reg, len); - ret = -EREMOTEIO; - } - - return ret; -} - -/* write single register */ -static int fc2580_wr_reg(struct fc2580_dev *dev, u8 reg, u8 val) -{ - return fc2580_wr_regs(dev, reg, &val, 1); -} - -/* read single register */ -static int fc2580_rd_reg(struct fc2580_dev *dev, u8 reg, u8 *val) -{ - return fc2580_rd_regs(dev, reg, val, 1); -} - /* write single register conditionally only when value differs from 0xff * XXX: This is special routine meant only for writing fc2580_freq_regs_lut[] * values. Do not use for the other purposes. */ @@ -131,10 +35,9 @@ static int fc2580_wr_reg_ff(struct fc2580_dev *dev, u8 reg, u8 val) if (val == 0xff) return 0; else - return fc2580_wr_regs(dev, reg, &val, 1); + return regmap_write(dev->regmap, reg, val); } - static int fc2580_set_params(struct dvb_frontend *fe) { struct fc2580_dev *dev = fe->tuner_priv; @@ -206,24 +109,24 @@ static int fc2580_set_params(struct dvb_frontend *fe) "frequency=%u f_vco=%llu F_REF=%u div_ref=%u div_n=%u k=%u div_out=%u k_cw=%0x\n", c->frequency, f_vco, F_REF, div_ref, div_n, k, div_out, k_cw); - ret = fc2580_wr_reg(dev, 0x02, synth_config); - if (ret < 0) + ret = regmap_write(dev->regmap, 0x02, synth_config); + if (ret) goto err; - ret = fc2580_wr_reg(dev, 0x18, div_ref_val << 0 | k_cw >> 16); - if (ret < 0) + ret = regmap_write(dev->regmap, 0x18, div_ref_val << 0 | k_cw >> 16); + if (ret) goto err; - ret = fc2580_wr_reg(dev, 0x1a, (k_cw >> 8) & 0xff); - if (ret < 0) + ret = regmap_write(dev->regmap, 0x1a, (k_cw >> 8) & 0xff); + if (ret) goto err; - ret = fc2580_wr_reg(dev, 0x1b, (k_cw >> 0) & 0xff); - if (ret < 0) + ret = regmap_write(dev->regmap, 0x1b, (k_cw >> 0) & 0xff); + if (ret) goto err; - ret = fc2580_wr_reg(dev, 0x1c, div_n); - if (ret < 0) + ret = regmap_write(dev->regmap, 0x1c, div_n); + if (ret) goto err; /* registers */ @@ -237,99 +140,99 @@ static int fc2580_set_params(struct dvb_frontend *fe) } ret = fc2580_wr_reg_ff(dev, 0x25, fc2580_freq_regs_lut[i].r25_val); - if (ret < 0) + if (ret) goto err; ret = fc2580_wr_reg_ff(dev, 0x27, fc2580_freq_regs_lut[i].r27_val); - if (ret < 0) + if (ret) goto err; ret = fc2580_wr_reg_ff(dev, 0x28, fc2580_freq_regs_lut[i].r28_val); - if (ret < 0) + if (ret) goto err; ret = fc2580_wr_reg_ff(dev, 0x29, fc2580_freq_regs_lut[i].r29_val); - if (ret < 0) + if (ret) goto err; ret = fc2580_wr_reg_ff(dev, 0x2b, fc2580_freq_regs_lut[i].r2b_val); - if (ret < 0) + if (ret) goto err; ret = fc2580_wr_reg_ff(dev, 0x2c, fc2580_freq_regs_lut[i].r2c_val); - if (ret < 0) + if (ret) goto err; ret = fc2580_wr_reg_ff(dev, 0x2d, fc2580_freq_regs_lut[i].r2d_val); - if (ret < 0) + if (ret) goto err; ret = fc2580_wr_reg_ff(dev, 0x30, fc2580_freq_regs_lut[i].r30_val); - if (ret < 0) + if (ret) goto err; ret = fc2580_wr_reg_ff(dev, 0x44, fc2580_freq_regs_lut[i].r44_val); - if (ret < 0) + if (ret) goto err; ret = fc2580_wr_reg_ff(dev, 0x50, fc2580_freq_regs_lut[i].r50_val); - if (ret < 0) + if (ret) goto err; ret = fc2580_wr_reg_ff(dev, 0x53, fc2580_freq_regs_lut[i].r53_val); - if (ret < 0) + if (ret) goto err; ret = fc2580_wr_reg_ff(dev, 0x5f, fc2580_freq_regs_lut[i].r5f_val); - if (ret < 0) + if (ret) goto err; ret = fc2580_wr_reg_ff(dev, 0x61, fc2580_freq_regs_lut[i].r61_val); - if (ret < 0) + if (ret) goto err; ret = fc2580_wr_reg_ff(dev, 0x62, fc2580_freq_regs_lut[i].r62_val); - if (ret < 0) + if (ret) goto err; ret = fc2580_wr_reg_ff(dev, 0x63, fc2580_freq_regs_lut[i].r63_val); - if (ret < 0) + if (ret) goto err; ret = fc2580_wr_reg_ff(dev, 0x67, fc2580_freq_regs_lut[i].r67_val); - if (ret < 0) + if (ret) goto err; ret = fc2580_wr_reg_ff(dev, 0x68, fc2580_freq_regs_lut[i].r68_val); - if (ret < 0) + if (ret) goto err; ret = fc2580_wr_reg_ff(dev, 0x69, fc2580_freq_regs_lut[i].r69_val); - if (ret < 0) + if (ret) goto err; ret = fc2580_wr_reg_ff(dev, 0x6a, fc2580_freq_regs_lut[i].r6a_val); - if (ret < 0) + if (ret) goto err; ret = fc2580_wr_reg_ff(dev, 0x6b, fc2580_freq_regs_lut[i].r6b_val); - if (ret < 0) + if (ret) goto err; ret = fc2580_wr_reg_ff(dev, 0x6c, fc2580_freq_regs_lut[i].r6c_val); - if (ret < 0) + if (ret) goto err; ret = fc2580_wr_reg_ff(dev, 0x6d, fc2580_freq_regs_lut[i].r6d_val); - if (ret < 0) + if (ret) goto err; ret = fc2580_wr_reg_ff(dev, 0x6e, fc2580_freq_regs_lut[i].r6e_val); - if (ret < 0) + if (ret) goto err; ret = fc2580_wr_reg_ff(dev, 0x6f, fc2580_freq_regs_lut[i].r6f_val); - if (ret < 0) + if (ret) goto err; /* IF filters */ @@ -342,34 +245,34 @@ static int fc2580_set_params(struct dvb_frontend *fe) goto err; } - ret = fc2580_wr_reg(dev, 0x36, fc2580_if_filter_lut[i].r36_val); - if (ret < 0) + ret = regmap_write(dev->regmap, 0x36, fc2580_if_filter_lut[i].r36_val); + if (ret) goto err; u8tmp = div_u64((u64) dev->clk * fc2580_if_filter_lut[i].mul, 1000000000); - ret = fc2580_wr_reg(dev, 0x37, u8tmp); - if (ret < 0) + ret = regmap_write(dev->regmap, 0x37, u8tmp); + if (ret) goto err; - ret = fc2580_wr_reg(dev, 0x39, fc2580_if_filter_lut[i].r39_val); - if (ret < 0) + ret = regmap_write(dev->regmap, 0x39, fc2580_if_filter_lut[i].r39_val); + if (ret) goto err; timeout = jiffies + msecs_to_jiffies(30); for (uitmp = ~0xc0; !time_after(jiffies, timeout) && uitmp != 0xc0;) { /* trigger filter */ - ret = fc2580_wr_reg(dev, 0x2e, 0x09); + ret = regmap_write(dev->regmap, 0x2e, 0x09); if (ret) goto err; /* locked when [7:6] are set (val: d7 6MHz, d5 7MHz, cd 8MHz) */ - ret = fc2580_rd_reg(dev, 0x2f, &u8tmp); + ret = regmap_read(dev->regmap, 0x2f, &uitmp); if (ret) goto err; - uitmp = u8tmp & 0xc0; + uitmp &= 0xc0; - ret = fc2580_wr_reg(dev, 0x2e, 0x01); + ret = regmap_write(dev->regmap, 0x2e, 0x01); if (ret) goto err; } @@ -391,9 +294,9 @@ static int fc2580_init(struct dvb_frontend *fe) dev_dbg(&client->dev, "\n"); for (i = 0; i < ARRAY_SIZE(fc2580_init_reg_vals); i++) { - ret = fc2580_wr_reg(dev, fc2580_init_reg_vals[i].reg, + ret = regmap_write(dev->regmap, fc2580_init_reg_vals[i].reg, fc2580_init_reg_vals[i].val); - if (ret < 0) + if (ret) goto err; } @@ -411,8 +314,8 @@ static int fc2580_sleep(struct dvb_frontend *fe) dev_dbg(&client->dev, "\n"); - ret = fc2580_wr_reg(dev, 0x02, 0x0a); - if (ret < 0) + ret = regmap_write(dev->regmap, 0x02, 0x0a); + if (ret) goto err; return 0; @@ -454,7 +357,11 @@ static int fc2580_probe(struct i2c_client *client, struct fc2580_platform_data *pdata = client->dev.platform_data; struct dvb_frontend *fe = pdata->dvb_frontend; int ret; - u8 chip_id; + unsigned int uitmp; + static const struct regmap_config regmap_config = { + .reg_bits = 8, + .val_bits = 8, + }; dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { @@ -467,17 +374,20 @@ static int fc2580_probe(struct i2c_client *client, else dev->clk = 16384000; /* internal clock */ dev->client = client; - dev->i2c = client->adapter; - dev->i2c_addr = client->addr; + dev->regmap = devm_regmap_init_i2c(client, ®map_config); + if (IS_ERR(dev->regmap)) { + ret = PTR_ERR(dev->regmap); + goto err_kfree; + } /* check if the tuner is there */ - ret = fc2580_rd_reg(dev, 0x01, &chip_id); - if (ret < 0) + ret = regmap_read(dev->regmap, 0x01, &uitmp); + if (ret) goto err_kfree; - dev_dbg(&client->dev, "chip_id=%02x\n", chip_id); + dev_dbg(&client->dev, "chip_id=%02x\n", uitmp); - switch (chip_id) { + switch (uitmp) { case 0x56: case 0x5a: break; diff --git a/drivers/media/tuners/fc2580_priv.h b/drivers/media/tuners/fc2580_priv.h index 16245ee878b1..60f8f6caca11 100644 --- a/drivers/media/tuners/fc2580_priv.h +++ b/drivers/media/tuners/fc2580_priv.h @@ -22,6 +22,7 @@ #define FC2580_PRIV_H #include "fc2580.h" +#include #include struct fc2580_reg_val { @@ -130,8 +131,7 @@ static const struct fc2580_freq_regs fc2580_freq_regs_lut[] = { struct fc2580_dev { u32 clk; struct i2c_client *client; - struct i2c_adapter *i2c; - u8 i2c_addr; + struct regmap *regmap; }; #endif -- cgit v1.2.3-59-g8ed1b From b3f02270b2618833fd44f8e5a8c1f82ab47741c2 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 15 Apr 2015 15:01:22 -0300 Subject: [media] af9035: fix device order in ID list Driver supports multiple chipset versions. Devices are ordered to ID table per used chipset type. "ITE 9303 Generic" device uses IT9303 chipset and was added mistakenly between IT9135 IDs. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/af9035.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index 5b583ff2ee8e..2ae1f2e8f2ab 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c @@ -2027,6 +2027,7 @@ static const struct usb_device_id af9035_id_table[] = { &af9035_props, "Asus U3100Mini Plus", NULL) }, { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00aa, &af9035_props, "TerraTec Cinergy T Stick (rev. 2)", NULL) }, + /* IT9135 devices */ { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135, &af9035_props, "ITE 9135 Generic", RC_MAP_IT913X_V1) }, @@ -2052,9 +2053,6 @@ static const struct usb_device_id af9035_id_table[] = { { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CTVDIGDUAL_V2, &af9035_props, "Digital Dual TV Receiver CTVDIGDUAL_V2", RC_MAP_IT913X_V1) }, - /* IT930x devices */ - { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9303, - &it930x_props, "ITE 9303 Generic", NULL) }, /* XXX: that same ID [0ccd:0099] is used by af9015 driver too */ { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x0099, &af9035_props, "TerraTec Cinergy T Stick Dual RC (rev. 2)", @@ -2067,6 +2065,10 @@ static const struct usb_device_id af9035_id_table[] = { &af9035_props, "PCTV AndroiDTV (78e)", RC_MAP_IT913X_V1) }, { DVB_USB_DEVICE(USB_VID_PCTV, USB_PID_PCTV_79E, &af9035_props, "PCTV microStick (79e)", RC_MAP_IT913X_V2) }, + + /* IT930x devices */ + { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9303, + &it930x_props, "ITE 9303 Generic", NULL) }, { } }; MODULE_DEVICE_TABLE(usb, af9035_id_table); -- cgit v1.2.3-59-g8ed1b From fc851c66b275e4092bb79c888a80dcdd1920c0b8 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 15 Apr 2015 19:12:34 -0300 Subject: [media] tua9001: add I2C bindings Add I2C bindings. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/tua9001.c | 100 +++++++++++++++++++++++++++++++++++- drivers/media/tuners/tua9001.h | 13 +++++ drivers/media/tuners/tua9001_priv.h | 4 +- 3 files changed, 114 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/tua9001.c b/drivers/media/tuners/tua9001.c index 83a6240f64d3..55cac20ae034 100644 --- a/drivers/media/tuners/tua9001.c +++ b/drivers/media/tuners/tua9001.c @@ -28,7 +28,7 @@ static int tua9001_wr_reg(struct tua9001_priv *priv, u8 reg, u16 val) u8 buf[3] = { reg, (val >> 8) & 0xff, (val >> 0) & 0xff }; struct i2c_msg msg[1] = { { - .addr = priv->cfg->i2c_addr, + .addr = priv->i2c_addr, .flags = 0, .len = sizeof(buf), .buf = buf, @@ -253,7 +253,7 @@ struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe, if (priv == NULL) return NULL; - priv->cfg = cfg; + priv->i2c_addr = cfg->i2c_addr; priv->i2c = i2c; if (fe->callback) { @@ -289,6 +289,102 @@ err: } EXPORT_SYMBOL(tua9001_attach); +static int tua9001_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct tua9001_priv *dev; + struct tua9001_platform_data *pdata = client->dev.platform_data; + struct dvb_frontend *fe = pdata->dvb_frontend; + int ret; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) { + ret = -ENOMEM; + goto err; + } + + dev->client = client; + dev->i2c_addr = client->addr; + dev->i2c = client->adapter; + dev->fe = pdata->dvb_frontend; + + if (fe->callback) { + ret = fe->callback(client->adapter, + DVB_FRONTEND_COMPONENT_TUNER, + TUA9001_CMD_CEN, 1); + if (ret) + goto err_kfree; + + ret = fe->callback(client->adapter, + DVB_FRONTEND_COMPONENT_TUNER, + TUA9001_CMD_RXEN, 0); + if (ret) + goto err_kfree; + + ret = fe->callback(client->adapter, + DVB_FRONTEND_COMPONENT_TUNER, + TUA9001_CMD_RESETN, 1); + if (ret) + goto err_kfree; + } + + fe->tuner_priv = dev; + memcpy(&fe->ops.tuner_ops, &tua9001_tuner_ops, + sizeof(struct dvb_tuner_ops)); + fe->ops.tuner_ops.release = NULL; + i2c_set_clientdata(client, dev); + + dev_info(&client->dev, "Infineon TUA 9001 successfully attached\n"); + return 0; +err_kfree: + kfree(dev); +err: + dev_dbg(&client->dev, "failed=%d\n", ret); + return ret; +} + +static int tua9001_remove(struct i2c_client *client) +{ + struct tua9001_priv *dev = i2c_get_clientdata(client); + struct dvb_frontend *fe = dev->fe; + int ret; + + dev_dbg(&client->dev, "\n"); + + if (fe->callback) { + ret = fe->callback(client->adapter, + DVB_FRONTEND_COMPONENT_TUNER, + TUA9001_CMD_CEN, 0); + if (ret) + goto err_kfree; + } + kfree(dev); + return 0; +err_kfree: + kfree(dev); + dev_dbg(&client->dev, "failed=%d\n", ret); + return ret; +} + +static const struct i2c_device_id tua9001_id_table[] = { + {"tua9001", 0}, + {} +}; +MODULE_DEVICE_TABLE(i2c, tua9001_id_table); + +static struct i2c_driver tua9001_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "tua9001", + .suppress_bind_attrs = true, + }, + .probe = tua9001_probe, + .remove = tua9001_remove, + .id_table = tua9001_id_table, +}; + +module_i2c_driver(tua9001_driver); + MODULE_DESCRIPTION("Infineon TUA 9001 silicon tuner driver"); MODULE_AUTHOR("Antti Palosaari "); MODULE_LICENSE("GPL"); diff --git a/drivers/media/tuners/tua9001.h b/drivers/media/tuners/tua9001.h index 2c3375c7aeb9..0b4fc8d26f52 100644 --- a/drivers/media/tuners/tua9001.h +++ b/drivers/media/tuners/tua9001.h @@ -24,6 +24,19 @@ #include #include "dvb_frontend.h" +/* + * I2C address + * 0x60, + */ + +/** + * struct tua9001_platform_data - Platform data for the tua9001 driver + * @dvb_frontend: DVB frontend. + */ +struct tua9001_platform_data { + struct dvb_frontend *dvb_frontend; +}; + struct tua9001_config { /* * I2C address diff --git a/drivers/media/tuners/tua9001_priv.h b/drivers/media/tuners/tua9001_priv.h index 73cc1ce0575c..3282a1a12e86 100644 --- a/drivers/media/tuners/tua9001_priv.h +++ b/drivers/media/tuners/tua9001_priv.h @@ -27,8 +27,10 @@ struct reg_val { }; struct tua9001_priv { - struct tua9001_config *cfg; + struct i2c_client *client; struct i2c_adapter *i2c; + u8 i2c_addr; + struct dvb_frontend *fe; }; #endif -- cgit v1.2.3-59-g8ed1b From b6c5fe70a7902dc9749991ac57e6e47d4471ecce Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 15 Apr 2015 19:18:40 -0300 Subject: [media] af9035: bind tua9001 using I2C binding Change tua9001 driver from media binding to I2C client binding. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/af9035.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index 2ae1f2e8f2ab..be077f2fd3ab 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c @@ -1234,10 +1234,6 @@ static int af9035_frontend_detach(struct dvb_usb_adapter *adap) return 0; } -static struct tua9001_config af9035_tua9001_config = { - .i2c_addr = 0x60, -}; - static const struct fc0011_config af9035_fc0011_config = { .i2c_address = 0x60, }; @@ -1296,9 +1292,15 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap) */ switch (state->af9033_config[adap->id].tuner) { - case AF9033_TUNER_TUA9001: - /* AF9035 gpiot3 = TUA9001 RESETN - AF9035 gpiot2 = TUA9001 RXEN */ + case AF9033_TUNER_TUA9001: { + struct tua9001_platform_data tua9001_pdata = { + .dvb_frontend = adap->fe[0], + }; + + /* + * AF9035 gpiot3 = TUA9001 RESETN + * AF9035 gpiot2 = TUA9001 RXEN + */ /* configure gpiot2 and gpiot2 as output */ ret = af9035_wr_reg_mask(d, 0x00d8ec, 0x01, 0x01); @@ -1318,9 +1320,14 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap) goto err; /* attach tuner */ - fe = dvb_attach(tua9001_attach, adap->fe[0], - &d->i2c_adap, &af9035_tua9001_config); + ret = af9035_add_i2c_dev(d, "tua9001", 0x60, &tua9001_pdata, + &d->i2c_adap); + if (ret) + goto err; + + fe = adap->fe[0]; break; + } case AF9033_TUNER_FC0011: fe = dvb_attach(fc0011_attach, adap->fe[0], &d->i2c_adap, &af9035_fc0011_config); @@ -1616,6 +1623,7 @@ static int af9035_tuner_detach(struct dvb_usb_adapter *adap) dev_dbg(&d->udev->dev, "%s: adap->id=%d\n", __func__, adap->id); switch (state->af9033_config[adap->id].tuner) { + case AF9033_TUNER_TUA9001: case AF9033_TUNER_FC2580: case AF9033_TUNER_IT9135_38: case AF9033_TUNER_IT9135_51: -- cgit v1.2.3-59-g8ed1b From 88ffe55ae3e5d012ddb80488d8bd1104d7b6e0aa Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 15 Apr 2015 19:25:32 -0300 Subject: [media] rtl28xxu: bind tua9001 using I2C binding Change tua9001 driver from media binding to I2C client binding. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 3ff4362585df..2bb71056ec3b 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -1100,10 +1100,6 @@ err: return ret; } -static struct tua9001_config rtl2832u_tua9001_config = { - .i2c_addr = 0x60, -}; - static const struct fc0012_config rtl2832u_fc0012_config = { .i2c_address = 0x63, /* 0xc6 >> 1 */ .xtal_freq = FC_XTAL_28_8_MHZ, @@ -1203,7 +1199,12 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) dev->i2c_client_tuner = client; } break; - case TUNER_RTL2832_TUA9001: + case TUNER_RTL2832_TUA9001: { + struct tua9001_platform_data tua9001_pdata = { + .dvb_frontend = adap->fe[0], + }; + struct i2c_board_info board_info = {}; + /* enable GPIO1 and GPIO4 as output */ ret = rtl28xxu_wr_reg_mask(d, SYS_GPIO_DIR, 0x00, 0x12); if (ret) @@ -1213,10 +1214,20 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) if (ret) goto err; - fe = dvb_attach(tua9001_attach, adap->fe[0], - dev->demod_i2c_adapter, - &rtl2832u_tua9001_config); + strlcpy(board_info.type, "tua9001", I2C_NAME_SIZE); + board_info.addr = 0x60; + board_info.platform_data = &tua9001_pdata; + request_module("tua9001"); + client = i2c_new_device(dev->demod_i2c_adapter, &board_info); + if (client == NULL || client->dev.driver == NULL) + break; + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + break; + } + dev->i2c_client_tuner = client; break; + } case TUNER_RTL2832_R820T: fe = dvb_attach(r820t_attach, adap->fe[0], dev->demod_i2c_adapter, -- cgit v1.2.3-59-g8ed1b From 96676239f59ca7d3db6afaf4911a4139dbeff858 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 15 Apr 2015 19:33:13 -0300 Subject: [media] tua9001: remove media attach We are using I2C client binding now, so remove old media attach. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/tua9001.c | 88 ++---------------------------------------- drivers/media/tuners/tua9001.h | 20 ---------- 2 files changed, 4 insertions(+), 104 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/tua9001.c b/drivers/media/tuners/tua9001.c index 55cac20ae034..87e85181e78a 100644 --- a/drivers/media/tuners/tua9001.c +++ b/drivers/media/tuners/tua9001.c @@ -47,23 +47,6 @@ static int tua9001_wr_reg(struct tua9001_priv *priv, u8 reg, u16 val) return ret; } -static int tua9001_release(struct dvb_frontend *fe) -{ - struct tua9001_priv *priv = fe->tuner_priv; - int ret = 0; - - dev_dbg(&priv->i2c->dev, "%s:\n", __func__); - - if (fe->callback) - ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER, - TUA9001_CMD_CEN, 0); - - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - - return ret; -} - static int tua9001_init(struct dvb_frontend *fe) { struct tua9001_priv *priv = fe->tuner_priv; @@ -96,18 +79,11 @@ static int tua9001_init(struct dvb_frontend *fe) goto err; } - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c-gate */ - for (i = 0; i < ARRAY_SIZE(data); i++) { ret = tua9001_wr_reg(priv, data[i].reg, data[i].val); if (ret < 0) - goto err_i2c_gate_ctrl; + goto err; } - -err_i2c_gate_ctrl: - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c-gate */ err: if (ret < 0) dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); @@ -181,32 +157,25 @@ static int tua9001_set_params(struct dvb_frontend *fe) data[1].reg = 0x1f; data[1].val = frequency; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c-gate */ - if (fe->callback) { ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER, TUA9001_CMD_RXEN, 0); if (ret < 0) - goto err_i2c_gate_ctrl; + goto err; } for (i = 0; i < ARRAY_SIZE(data); i++) { ret = tua9001_wr_reg(priv, data[i].reg, data[i].val); if (ret < 0) - goto err_i2c_gate_ctrl; + goto err; } if (fe->callback) { ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER, TUA9001_CMD_RXEN, 1); if (ret < 0) - goto err_i2c_gate_ctrl; + goto err; } - -err_i2c_gate_ctrl: - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c-gate */ err: if (ret < 0) dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); @@ -234,8 +203,6 @@ static const struct dvb_tuner_ops tua9001_tuner_ops = { .frequency_step = 0, }, - .release = tua9001_release, - .init = tua9001_init, .sleep = tua9001_sleep, .set_params = tua9001_set_params, @@ -243,52 +210,6 @@ static const struct dvb_tuner_ops tua9001_tuner_ops = { .get_if_frequency = tua9001_get_if_frequency, }; -struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, struct tua9001_config *cfg) -{ - struct tua9001_priv *priv = NULL; - int ret; - - priv = kzalloc(sizeof(struct tua9001_priv), GFP_KERNEL); - if (priv == NULL) - return NULL; - - priv->i2c_addr = cfg->i2c_addr; - priv->i2c = i2c; - - if (fe->callback) { - ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER, - TUA9001_CMD_CEN, 1); - if (ret < 0) - goto err; - - ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER, - TUA9001_CMD_RXEN, 0); - if (ret < 0) - goto err; - - ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER, - TUA9001_CMD_RESETN, 1); - if (ret < 0) - goto err; - } - - dev_info(&priv->i2c->dev, - "%s: Infineon TUA 9001 successfully attached\n", - KBUILD_MODNAME); - - memcpy(&fe->ops.tuner_ops, &tua9001_tuner_ops, - sizeof(struct dvb_tuner_ops)); - - fe->tuner_priv = priv; - return fe; -err: - dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret); - kfree(priv); - return NULL; -} -EXPORT_SYMBOL(tua9001_attach); - static int tua9001_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -331,7 +252,6 @@ static int tua9001_probe(struct i2c_client *client, fe->tuner_priv = dev; memcpy(&fe->ops.tuner_ops, &tua9001_tuner_ops, sizeof(struct dvb_tuner_ops)); - fe->ops.tuner_ops.release = NULL; i2c_set_clientdata(client, dev); dev_info(&client->dev, "Infineon TUA 9001 successfully attached\n"); diff --git a/drivers/media/tuners/tua9001.h b/drivers/media/tuners/tua9001.h index 0b4fc8d26f52..5328ab23a9a9 100644 --- a/drivers/media/tuners/tua9001.h +++ b/drivers/media/tuners/tua9001.h @@ -21,7 +21,6 @@ #ifndef TUA9001_H #define TUA9001_H -#include #include "dvb_frontend.h" /* @@ -37,13 +36,6 @@ struct tua9001_platform_data { struct dvb_frontend *dvb_frontend; }; -struct tua9001_config { - /* - * I2C address - */ - u8 i2c_addr; -}; - /* * TUA9001 I/O PINs: * @@ -64,16 +56,4 @@ struct tua9001_config { #define TUA9001_CMD_RESETN 1 #define TUA9001_CMD_RXEN 2 -#if IS_REACHABLE(CONFIG_MEDIA_TUNER_TUA9001) -extern struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, struct tua9001_config *cfg); -#else -static inline struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, struct tua9001_config *cfg) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - #endif -- cgit v1.2.3-59-g8ed1b From 465433fa378a6e0248461f03df6bfd754832a87b Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 15 Apr 2015 20:26:06 -0300 Subject: [media] tua9001: various minor changes Fix logging. Style issues. Rename things. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/Kconfig | 2 +- drivers/media/tuners/tua9001.c | 153 ++++++++++++++++++------------------ drivers/media/tuners/tua9001.h | 6 +- drivers/media/tuners/tua9001_priv.h | 16 ++-- 4 files changed, 83 insertions(+), 94 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig index 26961da7ac03..0408745778e8 100644 --- a/drivers/media/tuners/Kconfig +++ b/drivers/media/tuners/Kconfig @@ -234,7 +234,7 @@ config MEDIA_TUNER_M88RS6000T Montage M88RS6000 internal tuner. config MEDIA_TUNER_TUA9001 - tristate "Infineon TUA 9001 silicon tuner" + tristate "Infineon TUA9001 silicon tuner" depends on MEDIA_SUPPORT && I2C default m if !MEDIA_SUBDRV_AUTOSELECT help diff --git a/drivers/media/tuners/tua9001.c b/drivers/media/tuners/tua9001.c index 87e85181e78a..fe778cd39c2e 100644 --- a/drivers/media/tuners/tua9001.c +++ b/drivers/media/tuners/tua9001.c @@ -1,5 +1,5 @@ /* - * Infineon TUA 9001 silicon tuner driver + * Infineon TUA9001 silicon tuner driver * * Copyright (C) 2009 Antti Palosaari * @@ -12,35 +12,30 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "tua9001.h" #include "tua9001_priv.h" /* write register */ -static int tua9001_wr_reg(struct tua9001_priv *priv, u8 reg, u16 val) +static int tua9001_wr_reg(struct tua9001_dev *dev, u8 reg, u16 val) { + struct i2c_client *client = dev->client; int ret; u8 buf[3] = { reg, (val >> 8) & 0xff, (val >> 0) & 0xff }; struct i2c_msg msg[1] = { { - .addr = priv->i2c_addr, + .addr = client->addr, .flags = 0, .len = sizeof(buf), .buf = buf, } }; - ret = i2c_transfer(priv->i2c, msg, 1); + ret = i2c_transfer(client->adapter, msg, 1); if (ret == 1) { ret = 0; } else { - dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x\n", - KBUILD_MODNAME, ret, reg); + dev_warn(&client->dev, "i2c wr failed=%d reg=%02x\n", ret, reg); ret = -EREMOTEIO; } @@ -49,77 +44,82 @@ static int tua9001_wr_reg(struct tua9001_priv *priv, u8 reg, u16 val) static int tua9001_init(struct dvb_frontend *fe) { - struct tua9001_priv *priv = fe->tuner_priv; - int ret = 0; - u8 i; - struct reg_val data[] = { - { 0x1e, 0x6512 }, - { 0x25, 0xb888 }, - { 0x39, 0x5460 }, - { 0x3b, 0x00c0 }, - { 0x3a, 0xf000 }, - { 0x08, 0x0000 }, - { 0x32, 0x0030 }, - { 0x41, 0x703a }, - { 0x40, 0x1c78 }, - { 0x2c, 0x1c00 }, - { 0x36, 0xc013 }, - { 0x37, 0x6f18 }, - { 0x27, 0x0008 }, - { 0x2a, 0x0001 }, - { 0x34, 0x0a40 }, + struct tua9001_dev *dev = fe->tuner_priv; + struct i2c_client *client = dev->client; + int ret, i; + static const struct tua9001_reg_val data[] = { + {0x1e, 0x6512}, + {0x25, 0xb888}, + {0x39, 0x5460}, + {0x3b, 0x00c0}, + {0x3a, 0xf000}, + {0x08, 0x0000}, + {0x32, 0x0030}, + {0x41, 0x703a}, + {0x40, 0x1c78}, + {0x2c, 0x1c00}, + {0x36, 0xc013}, + {0x37, 0x6f18}, + {0x27, 0x0008}, + {0x2a, 0x0001}, + {0x34, 0x0a40}, }; - dev_dbg(&priv->i2c->dev, "%s:\n", __func__); + dev_dbg(&client->dev, "\n"); if (fe->callback) { - ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER, - TUA9001_CMD_RESETN, 0); - if (ret < 0) + ret = fe->callback(client->adapter, + DVB_FRONTEND_COMPONENT_TUNER, + TUA9001_CMD_RESETN, 0); + if (ret) goto err; } for (i = 0; i < ARRAY_SIZE(data); i++) { - ret = tua9001_wr_reg(priv, data[i].reg, data[i].val); - if (ret < 0) + ret = tua9001_wr_reg(dev, data[i].reg, data[i].val); + if (ret) goto err; } + return 0; err: - if (ret < 0) - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); - + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int tua9001_sleep(struct dvb_frontend *fe) { - struct tua9001_priv *priv = fe->tuner_priv; - int ret = 0; - - dev_dbg(&priv->i2c->dev, "%s:\n", __func__); - - if (fe->callback) - ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER, - TUA9001_CMD_RESETN, 1); + struct tua9001_dev *dev = fe->tuner_priv; + struct i2c_client *client = dev->client; + int ret; - if (ret < 0) - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "\n"); + if (fe->callback) { + ret = fe->callback(client->adapter, + DVB_FRONTEND_COMPONENT_TUNER, + TUA9001_CMD_RESETN, 1); + if (ret) + goto err; + } + return 0; +err: + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int tua9001_set_params(struct dvb_frontend *fe) { - struct tua9001_priv *priv = fe->tuner_priv; + struct tua9001_dev *dev = fe->tuner_priv; + struct i2c_client *client = dev->client; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int ret = 0, i; + int ret, i; u16 val; u32 frequency; - struct reg_val data[2]; + struct tua9001_reg_val data[2]; - dev_dbg(&priv->i2c->dev, "%s: delivery_system=%d frequency=%d " \ - "bandwidth_hz=%d\n", __func__, - c->delivery_system, c->frequency, c->bandwidth_hz); + dev_dbg(&client->dev, + "delivery_system=%u frequency=%u bandwidth_hz=%u\n", + c->delivery_system, c->frequency, c->bandwidth_hz); switch (c->delivery_system) { case SYS_DVBT: @@ -158,49 +158,48 @@ static int tua9001_set_params(struct dvb_frontend *fe) data[1].val = frequency; if (fe->callback) { - ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER, - TUA9001_CMD_RXEN, 0); - if (ret < 0) + ret = fe->callback(client->adapter, + DVB_FRONTEND_COMPONENT_TUNER, + TUA9001_CMD_RXEN, 0); + if (ret) goto err; } for (i = 0; i < ARRAY_SIZE(data); i++) { - ret = tua9001_wr_reg(priv, data[i].reg, data[i].val); - if (ret < 0) + ret = tua9001_wr_reg(dev, data[i].reg, data[i].val); + if (ret) goto err; } if (fe->callback) { - ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER, - TUA9001_CMD_RXEN, 1); - if (ret < 0) + ret = fe->callback(client->adapter, + DVB_FRONTEND_COMPONENT_TUNER, + TUA9001_CMD_RXEN, 1); + if (ret) goto err; } + return 0; err: - if (ret < 0) - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); - + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int tua9001_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) { - struct tua9001_priv *priv = fe->tuner_priv; + struct tua9001_dev *dev = fe->tuner_priv; + struct i2c_client *client = dev->client; - dev_dbg(&priv->i2c->dev, "%s:\n", __func__); + dev_dbg(&client->dev, "\n"); *frequency = 0; /* Zero-IF */ - return 0; } static const struct dvb_tuner_ops tua9001_tuner_ops = { .info = { - .name = "Infineon TUA 9001", - + .name = "Infineon TUA9001", .frequency_min = 170000000, .frequency_max = 862000000, - .frequency_step = 0, }, .init = tua9001_init, @@ -213,7 +212,7 @@ static const struct dvb_tuner_ops tua9001_tuner_ops = { static int tua9001_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct tua9001_priv *dev; + struct tua9001_dev *dev; struct tua9001_platform_data *pdata = client->dev.platform_data; struct dvb_frontend *fe = pdata->dvb_frontend; int ret; @@ -225,8 +224,6 @@ static int tua9001_probe(struct i2c_client *client, } dev->client = client; - dev->i2c_addr = client->addr; - dev->i2c = client->adapter; dev->fe = pdata->dvb_frontend; if (fe->callback) { @@ -254,7 +251,7 @@ static int tua9001_probe(struct i2c_client *client, sizeof(struct dvb_tuner_ops)); i2c_set_clientdata(client, dev); - dev_info(&client->dev, "Infineon TUA 9001 successfully attached\n"); + dev_info(&client->dev, "Infineon TUA9001 successfully attached\n"); return 0; err_kfree: kfree(dev); @@ -265,7 +262,7 @@ err: static int tua9001_remove(struct i2c_client *client) { - struct tua9001_priv *dev = i2c_get_clientdata(client); + struct tua9001_dev *dev = i2c_get_clientdata(client); struct dvb_frontend *fe = dev->fe; int ret; @@ -305,6 +302,6 @@ static struct i2c_driver tua9001_driver = { module_i2c_driver(tua9001_driver); -MODULE_DESCRIPTION("Infineon TUA 9001 silicon tuner driver"); +MODULE_DESCRIPTION("Infineon TUA9001 silicon tuner driver"); MODULE_AUTHOR("Antti Palosaari "); MODULE_LICENSE("GPL"); diff --git a/drivers/media/tuners/tua9001.h b/drivers/media/tuners/tua9001.h index 5328ab23a9a9..7b0548181cdc 100644 --- a/drivers/media/tuners/tua9001.h +++ b/drivers/media/tuners/tua9001.h @@ -1,5 +1,5 @@ /* - * Infineon TUA 9001 silicon tuner driver + * Infineon TUA9001 silicon tuner driver * * Copyright (C) 2009 Antti Palosaari * @@ -12,10 +12,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef TUA9001_H diff --git a/drivers/media/tuners/tua9001_priv.h b/drivers/media/tuners/tua9001_priv.h index 3282a1a12e86..e24d84307035 100644 --- a/drivers/media/tuners/tua9001_priv.h +++ b/drivers/media/tuners/tua9001_priv.h @@ -1,5 +1,5 @@ /* - * Infineon TUA 9001 silicon tuner driver + * Infineon TUA9001 silicon tuner driver * * Copyright (C) 2009 Antti Palosaari * @@ -12,25 +12,21 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef TUA9001_PRIV_H #define TUA9001_PRIV_H -struct reg_val { +#include "tua9001.h" + +struct tua9001_reg_val { u8 reg; u16 val; }; -struct tua9001_priv { - struct i2c_client *client; - struct i2c_adapter *i2c; - u8 i2c_addr; +struct tua9001_dev { struct dvb_frontend *fe; + struct i2c_client *client; }; #endif -- cgit v1.2.3-59-g8ed1b From dd219a87e4ba963c8208a3ef0a38fbc14074ad70 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 15 Apr 2015 20:38:43 -0300 Subject: [media] tua9001: use regmap for I2C register access Use regmap for I2C register access. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/Kconfig | 1 + drivers/media/tuners/tua9001.c | 41 +++++++++++-------------------------- drivers/media/tuners/tua9001_priv.h | 2 ++ 3 files changed, 15 insertions(+), 29 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig index 0408745778e8..8294af909174 100644 --- a/drivers/media/tuners/Kconfig +++ b/drivers/media/tuners/Kconfig @@ -236,6 +236,7 @@ config MEDIA_TUNER_M88RS6000T config MEDIA_TUNER_TUA9001 tristate "Infineon TUA9001 silicon tuner" depends on MEDIA_SUPPORT && I2C + select REGMAP_I2C default m if !MEDIA_SUBDRV_AUTOSELECT help Infineon TUA 9001 silicon tuner driver. diff --git a/drivers/media/tuners/tua9001.c b/drivers/media/tuners/tua9001.c index fe778cd39c2e..09a10349dd57 100644 --- a/drivers/media/tuners/tua9001.c +++ b/drivers/media/tuners/tua9001.c @@ -16,32 +16,6 @@ #include "tua9001_priv.h" -/* write register */ -static int tua9001_wr_reg(struct tua9001_dev *dev, u8 reg, u16 val) -{ - struct i2c_client *client = dev->client; - int ret; - u8 buf[3] = { reg, (val >> 8) & 0xff, (val >> 0) & 0xff }; - struct i2c_msg msg[1] = { - { - .addr = client->addr, - .flags = 0, - .len = sizeof(buf), - .buf = buf, - } - }; - - ret = i2c_transfer(client->adapter, msg, 1); - if (ret == 1) { - ret = 0; - } else { - dev_warn(&client->dev, "i2c wr failed=%d reg=%02x\n", ret, reg); - ret = -EREMOTEIO; - } - - return ret; -} - static int tua9001_init(struct dvb_frontend *fe) { struct tua9001_dev *dev = fe->tuner_priv; @@ -76,7 +50,7 @@ static int tua9001_init(struct dvb_frontend *fe) } for (i = 0; i < ARRAY_SIZE(data); i++) { - ret = tua9001_wr_reg(dev, data[i].reg, data[i].val); + ret = regmap_write(dev->regmap, data[i].reg, data[i].val); if (ret) goto err; } @@ -166,7 +140,7 @@ static int tua9001_set_params(struct dvb_frontend *fe) } for (i = 0; i < ARRAY_SIZE(data); i++) { - ret = tua9001_wr_reg(dev, data[i].reg, data[i].val); + ret = regmap_write(dev->regmap, data[i].reg, data[i].val); if (ret) goto err; } @@ -216,6 +190,10 @@ static int tua9001_probe(struct i2c_client *client, struct tua9001_platform_data *pdata = client->dev.platform_data; struct dvb_frontend *fe = pdata->dvb_frontend; int ret; + static const struct regmap_config regmap_config = { + .reg_bits = 8, + .val_bits = 16, + }; dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { @@ -223,8 +201,13 @@ static int tua9001_probe(struct i2c_client *client, goto err; } - dev->client = client; dev->fe = pdata->dvb_frontend; + dev->client = client; + dev->regmap = devm_regmap_init_i2c(client, ®map_config); + if (IS_ERR(dev->regmap)) { + ret = PTR_ERR(dev->regmap); + goto err_kfree; + } if (fe->callback) { ret = fe->callback(client->adapter, diff --git a/drivers/media/tuners/tua9001_priv.h b/drivers/media/tuners/tua9001_priv.h index e24d84307035..327ead9ea2ba 100644 --- a/drivers/media/tuners/tua9001_priv.h +++ b/drivers/media/tuners/tua9001_priv.h @@ -18,6 +18,7 @@ #define TUA9001_PRIV_H #include "tua9001.h" +#include struct tua9001_reg_val { u8 reg; @@ -27,6 +28,7 @@ struct tua9001_reg_val { struct tua9001_dev { struct dvb_frontend *fe; struct i2c_client *client; + struct regmap *regmap; }; #endif -- cgit v1.2.3-59-g8ed1b From 47f95dbdb3adefb927851c8737de66894f58b14d Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 16 Apr 2015 07:36:51 -0300 Subject: [media] tua9001: use div_u64() for frequency calculation Use div_u64() to simplify and remove home made divides. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/tua9001.c | 9 +-------- drivers/media/tuners/tua9001_priv.h | 1 + 2 files changed, 2 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/tua9001.c b/drivers/media/tuners/tua9001.c index 09a10349dd57..d4f6ca0c4d92 100644 --- a/drivers/media/tuners/tua9001.c +++ b/drivers/media/tuners/tua9001.c @@ -88,7 +88,6 @@ static int tua9001_set_params(struct dvb_frontend *fe) struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, i; u16 val; - u32 frequency; struct tua9001_reg_val data[2]; dev_dbg(&client->dev, @@ -122,14 +121,8 @@ static int tua9001_set_params(struct dvb_frontend *fe) data[0].reg = 0x04; data[0].val = val; - - frequency = (c->frequency - 150000000); - frequency /= 100; - frequency *= 48; - frequency /= 10000; - data[1].reg = 0x1f; - data[1].val = frequency; + data[1].val = div_u64((u64) (c->frequency - 150000000) * 48, 1000000); if (fe->callback) { ret = fe->callback(client->adapter, diff --git a/drivers/media/tuners/tua9001_priv.h b/drivers/media/tuners/tua9001_priv.h index 327ead9ea2ba..bc406c5ec69d 100644 --- a/drivers/media/tuners/tua9001_priv.h +++ b/drivers/media/tuners/tua9001_priv.h @@ -18,6 +18,7 @@ #define TUA9001_PRIV_H #include "tua9001.h" +#include #include struct tua9001_reg_val { -- cgit v1.2.3-59-g8ed1b From f88aae9d07ab1612c37cf52fee3a98e1e1eeea69 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 23 Apr 2015 22:52:07 -0300 Subject: [media] rtl2832: add inittab for FC2580 tuner Add reg/val inittab for FC2580 tuner. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/rtl2832.c | 4 ++++ drivers/media/dvb-frontends/rtl2832.h | 1 + drivers/media/dvb-frontends/rtl2832_priv.h | 24 ++++++++++++++++++++++++ 3 files changed, 29 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c index 55a8b1f26bee..a57c478e2306 100644 --- a/drivers/media/dvb-frontends/rtl2832.c +++ b/drivers/media/dvb-frontends/rtl2832.c @@ -358,6 +358,10 @@ static int rtl2832_init(struct dvb_frontend *fe) dev_dbg(&client->dev, "load settings for tuner=%02x\n", dev->pdata->tuner); switch (dev->pdata->tuner) { + case RTL2832_TUNER_FC2580: + len = ARRAY_SIZE(rtl2832_tuner_init_fc2580); + init = rtl2832_tuner_init_fc2580; + break; case RTL2832_TUNER_FC0012: case RTL2832_TUNER_FC0013: len = ARRAY_SIZE(rtl2832_tuner_init_fc0012); diff --git a/drivers/media/dvb-frontends/rtl2832.h b/drivers/media/dvb-frontends/rtl2832.h index c6cdcc45d1ce..c29a4c2bf71a 100644 --- a/drivers/media/dvb-frontends/rtl2832.h +++ b/drivers/media/dvb-frontends/rtl2832.h @@ -41,6 +41,7 @@ struct rtl2832_platform_data { /* * XXX: This list must be kept sync with dvb_usb_rtl28xxu USB IF driver. */ +#define RTL2832_TUNER_FC2580 0x21 #define RTL2832_TUNER_TUA9001 0x24 #define RTL2832_TUNER_FC0012 0x26 #define RTL2832_TUNER_E4000 0x27 diff --git a/drivers/media/dvb-frontends/rtl2832_priv.h b/drivers/media/dvb-frontends/rtl2832_priv.h index a973b8aba07c..6f3a49c63ab0 100644 --- a/drivers/media/dvb-frontends/rtl2832_priv.h +++ b/drivers/media/dvb-frontends/rtl2832_priv.h @@ -252,6 +252,30 @@ enum DVBT_REG_BIT_NAME { DVBT_REG_BIT_NAME_ITEM_TERMINATOR, }; +static const struct rtl2832_reg_value rtl2832_tuner_init_fc2580[] = { + {DVBT_DAGC_TRG_VAL, 0x39}, + {DVBT_AGC_TARG_VAL_0, 0x0}, + {DVBT_AGC_TARG_VAL_8_1, 0x5a}, + {DVBT_AAGC_LOOP_GAIN, 0x16}, + {DVBT_LOOP_GAIN2_3_0, 0x6}, + {DVBT_LOOP_GAIN2_4, 0x1}, + {DVBT_LOOP_GAIN3, 0x16}, + {DVBT_VTOP1, 0x35}, + {DVBT_VTOP2, 0x21}, + {DVBT_VTOP3, 0x21}, + {DVBT_KRF1, 0x0}, + {DVBT_KRF2, 0x40}, + {DVBT_KRF3, 0x10}, + {DVBT_KRF4, 0x10}, + {DVBT_IF_AGC_MIN, 0x80}, + {DVBT_IF_AGC_MAX, 0x7f}, + {DVBT_RF_AGC_MIN, 0x9c}, + {DVBT_RF_AGC_MAX, 0x7f}, + {DVBT_POLAR_RF_AGC, 0x0}, + {DVBT_POLAR_IF_AGC, 0x0}, + {DVBT_AD7_SETTING, 0xe9f4}, +}; + static const struct rtl2832_reg_value rtl2832_tuner_init_tua9001[] = { {DVBT_DAGC_TRG_VAL, 0x39}, {DVBT_AGC_TARG_VAL_0, 0x0}, -- cgit v1.2.3-59-g8ed1b From 7e33f8a282d4c98710db7423d637b799b52eb477 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 23 Apr 2015 22:54:03 -0300 Subject: [media] rtl28xxu: set correct FC2580 tuner for RTL2832 demod rtl2832 demod driver has support for FC2580 tuner config, no need to abuse FC0012 settings anymore. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 2bb71056ec3b..2d2d50625048 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -689,6 +689,11 @@ err: return ret; } +static const struct rtl2832_platform_data rtl2832_fc2580_platform_data = { + .clk = 28800000, + .tuner = TUNER_RTL2832_FC2580, +}; + static const struct rtl2832_platform_data rtl2832_fc0012_platform_data = { .clk = 28800000, .tuner = TUNER_RTL2832_FC0012 @@ -855,8 +860,7 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap) *pdata = rtl2832_fc0013_platform_data; break; case TUNER_RTL2832_FC2580: - /* FIXME: do not abuse fc0012 settings */ - *pdata = rtl2832_fc0012_platform_data; + *pdata = rtl2832_fc2580_platform_data; break; case TUNER_RTL2832_TUA9001: *pdata = rtl2832_tua9001_platform_data; -- cgit v1.2.3-59-g8ed1b From 8b302d43e84dc863729010a1ea9a5a2bc83d25de Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 3 May 2015 15:16:52 -0300 Subject: [media] fc2580: calculate filter control word dynamically Calculate low-pass filter control word dynamically from given radio channel bandwidth. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/fc2580.c | 8 ++++---- drivers/media/tuners/fc2580_priv.h | 9 ++++----- 2 files changed, 8 insertions(+), 9 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/fc2580.c b/drivers/media/tuners/fc2580.c index 08838b4b4821..30cee76b5f37 100644 --- a/drivers/media/tuners/fc2580.c +++ b/drivers/media/tuners/fc2580.c @@ -46,7 +46,7 @@ static int fc2580_set_params(struct dvb_frontend *fe) int ret, i; unsigned int uitmp, div_ref, div_ref_val, div_n, k, k_cw, div_out; u64 f_vco; - u8 u8tmp, synth_config; + u8 synth_config; unsigned long timeout; dev_dbg(&client->dev, @@ -249,9 +249,9 @@ static int fc2580_set_params(struct dvb_frontend *fe) if (ret) goto err; - u8tmp = div_u64((u64) dev->clk * fc2580_if_filter_lut[i].mul, - 1000000000); - ret = regmap_write(dev->regmap, 0x37, u8tmp); + uitmp = (unsigned int) 8058000 - (c->bandwidth_hz * 122 / 100 / 2); + uitmp = div64_u64((u64) dev->clk * uitmp, 1000000000000ULL); + ret = regmap_write(dev->regmap, 0x37, uitmp); if (ret) goto err; diff --git a/drivers/media/tuners/fc2580_priv.h b/drivers/media/tuners/fc2580_priv.h index 60f8f6caca11..bd88b0141141 100644 --- a/drivers/media/tuners/fc2580_priv.h +++ b/drivers/media/tuners/fc2580_priv.h @@ -64,16 +64,15 @@ static const struct fc2580_pll fc2580_pll_lut[] = { struct fc2580_if_filter { u32 freq; - u16 mul; u8 r36_val; u8 r39_val; }; static const struct fc2580_if_filter fc2580_if_filter_lut[] = { - { 6000000, 4400, 0x18, 0x00}, - { 7000000, 3910, 0x18, 0x80}, - { 8000000, 3300, 0x18, 0x80}, - {0xffffffff, 3300, 0x18, 0x80}, + { 6000000, 0x18, 0x00}, + { 7000000, 0x18, 0x80}, + { 8000000, 0x18, 0x80}, + {0xffffffff, 0x18, 0x80}, }; struct fc2580_freq_regs { -- cgit v1.2.3-59-g8ed1b From 252fad1cee34d6613a44ff218d7a80fd5f4b0987 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 3 May 2015 21:42:02 -0300 Subject: [media] fc2580: implement V4L2 subdevice for SDR control Implement V4L2 subdevice for bandwidth and frequency controls of SDR usage. That driver now implements both DVB frontend and V4L2 subdevice. Driver itself is I2C driver. Lets see how it works. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/fc2580.c | 262 +++++++++++++++++++++++++++++++++---- drivers/media/tuners/fc2580.h | 5 + drivers/media/tuners/fc2580_priv.h | 11 ++ 3 files changed, 249 insertions(+), 29 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/fc2580.c b/drivers/media/tuners/fc2580.c index 30cee76b5f37..db21902b6e63 100644 --- a/drivers/media/tuners/fc2580.c +++ b/drivers/media/tuners/fc2580.c @@ -38,20 +38,19 @@ static int fc2580_wr_reg_ff(struct fc2580_dev *dev, u8 reg, u8 val) return regmap_write(dev->regmap, reg, val); } -static int fc2580_set_params(struct dvb_frontend *fe) +static int fc2580_set_params(struct fc2580_dev *dev) { - struct fc2580_dev *dev = fe->tuner_priv; struct i2c_client *client = dev->client; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, i; unsigned int uitmp, div_ref, div_ref_val, div_n, k, k_cw, div_out; u64 f_vco; u8 synth_config; unsigned long timeout; - dev_dbg(&client->dev, - "delivery_system=%u frequency=%u bandwidth_hz=%u\n", - c->delivery_system, c->frequency, c->bandwidth_hz); + if (!dev->active) { + dev_dbg(&client->dev, "tuner is sleeping\n"); + return 0; + } /* * Fractional-N synthesizer @@ -69,7 +68,7 @@ static int fc2580_set_params(struct dvb_frontend *fe) * +-------+ */ for (i = 0; i < ARRAY_SIZE(fc2580_pll_lut); i++) { - if (c->frequency <= fc2580_pll_lut[i].freq) + if (dev->f_frequency <= fc2580_pll_lut[i].freq) break; } if (i == ARRAY_SIZE(fc2580_pll_lut)) { @@ -80,7 +79,7 @@ static int fc2580_set_params(struct dvb_frontend *fe) #define DIV_PRE_N 2 #define F_REF dev->clk div_out = fc2580_pll_lut[i].div_out; - f_vco = (u64) c->frequency * div_out; + f_vco = (u64) dev->f_frequency * div_out; synth_config = fc2580_pll_lut[i].band; if (f_vco < 2600000000ULL) synth_config |= 0x06; @@ -106,8 +105,9 @@ static int fc2580_set_params(struct dvb_frontend *fe) k_cw = div_u64((u64) k * 0x100000, uitmp); dev_dbg(&client->dev, - "frequency=%u f_vco=%llu F_REF=%u div_ref=%u div_n=%u k=%u div_out=%u k_cw=%0x\n", - c->frequency, f_vco, F_REF, div_ref, div_n, k, div_out, k_cw); + "frequency=%u bandwidth=%u f_vco=%llu F_REF=%u div_ref=%u div_n=%u k=%u div_out=%u k_cw=%0x\n", + dev->f_frequency, dev->f_bandwidth, f_vco, F_REF, div_ref, + div_n, k, div_out, k_cw); ret = regmap_write(dev->regmap, 0x02, synth_config); if (ret) @@ -131,7 +131,7 @@ static int fc2580_set_params(struct dvb_frontend *fe) /* registers */ for (i = 0; i < ARRAY_SIZE(fc2580_freq_regs_lut); i++) { - if (c->frequency <= fc2580_freq_regs_lut[i].freq) + if (dev->f_frequency <= fc2580_freq_regs_lut[i].freq) break; } if (i == ARRAY_SIZE(fc2580_freq_regs_lut)) { @@ -237,7 +237,7 @@ static int fc2580_set_params(struct dvb_frontend *fe) /* IF filters */ for (i = 0; i < ARRAY_SIZE(fc2580_if_filter_lut); i++) { - if (c->bandwidth_hz <= fc2580_if_filter_lut[i].freq) + if (dev->f_bandwidth <= fc2580_if_filter_lut[i].freq) break; } if (i == ARRAY_SIZE(fc2580_if_filter_lut)) { @@ -249,7 +249,7 @@ static int fc2580_set_params(struct dvb_frontend *fe) if (ret) goto err; - uitmp = (unsigned int) 8058000 - (c->bandwidth_hz * 122 / 100 / 2); + uitmp = (unsigned int) 8058000 - (dev->f_bandwidth * 122 / 100 / 2); uitmp = div64_u64((u64) dev->clk * uitmp, 1000000000000ULL); ret = regmap_write(dev->regmap, 0x37, uitmp); if (ret) @@ -285,9 +285,8 @@ err: return ret; } -static int fc2580_init(struct dvb_frontend *fe) +static int fc2580_init(struct fc2580_dev *dev) { - struct fc2580_dev *dev = fe->tuner_priv; struct i2c_client *client = dev->client; int ret, i; @@ -300,56 +299,236 @@ static int fc2580_init(struct dvb_frontend *fe) goto err; } + dev->active = true; return 0; err: dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } -static int fc2580_sleep(struct dvb_frontend *fe) +static int fc2580_sleep(struct fc2580_dev *dev) { - struct fc2580_dev *dev = fe->tuner_priv; struct i2c_client *client = dev->client; int ret; dev_dbg(&client->dev, "\n"); + dev->active = false; + ret = regmap_write(dev->regmap, 0x02, 0x0a); if (ret) goto err; - return 0; err: dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } -static int fc2580_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) +/* + * DVB API + */ +static int fc2580_dvb_set_params(struct dvb_frontend *fe) { struct fc2580_dev *dev = fe->tuner_priv; - struct i2c_client *client = dev->client; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; - dev_dbg(&client->dev, "\n"); + dev->f_frequency = c->frequency; + dev->f_bandwidth = c->bandwidth_hz; + return fc2580_set_params(dev); +} - *frequency = 0; /* Zero-IF */ +static int fc2580_dvb_init(struct dvb_frontend *fe) +{ + return fc2580_init(fe->tuner_priv); +} +static int fc2580_dvb_sleep(struct dvb_frontend *fe) +{ + return fc2580_sleep(fe->tuner_priv); +} + +static int fc2580_dvb_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + *frequency = 0; /* Zero-IF */ return 0; } -static const struct dvb_tuner_ops fc2580_tuner_ops = { +static const struct dvb_tuner_ops fc2580_dvb_tuner_ops = { .info = { .name = "FCI FC2580", .frequency_min = 174000000, .frequency_max = 862000000, }, - .init = fc2580_init, - .sleep = fc2580_sleep, - .set_params = fc2580_set_params, + .init = fc2580_dvb_init, + .sleep = fc2580_dvb_sleep, + .set_params = fc2580_dvb_set_params, - .get_if_frequency = fc2580_get_if_frequency, + .get_if_frequency = fc2580_dvb_get_if_frequency, }; +/* + * V4L2 API + */ +#if IS_ENABLED(CONFIG_VIDEO_V4L2) +static const struct v4l2_frequency_band bands[] = { + { + .type = V4L2_TUNER_RF, + .index = 0, + .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS, + .rangelow = 130000000, + .rangehigh = 2000000000, + }, +}; + +static inline struct fc2580_dev *fc2580_subdev_to_dev(struct v4l2_subdev *sd) +{ + return container_of(sd, struct fc2580_dev, subdev); +} + +static int fc2580_s_power(struct v4l2_subdev *sd, int on) +{ + struct fc2580_dev *dev = fc2580_subdev_to_dev(sd); + struct i2c_client *client = dev->client; + int ret; + + dev_dbg(&client->dev, "on=%d\n", on); + + if (on) + ret = fc2580_init(dev); + else + ret = fc2580_sleep(dev); + if (ret) + return ret; + + return fc2580_set_params(dev); +} + +static const struct v4l2_subdev_core_ops fc2580_subdev_core_ops = { + .s_power = fc2580_s_power, +}; + +static int fc2580_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v) +{ + struct fc2580_dev *dev = fc2580_subdev_to_dev(sd); + struct i2c_client *client = dev->client; + + dev_dbg(&client->dev, "index=%d\n", v->index); + + strlcpy(v->name, "FCI FC2580", sizeof(v->name)); + v->type = V4L2_TUNER_RF; + v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS; + v->rangelow = bands[0].rangelow; + v->rangehigh = bands[0].rangehigh; + return 0; +} + +static int fc2580_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *v) +{ + struct fc2580_dev *dev = fc2580_subdev_to_dev(sd); + struct i2c_client *client = dev->client; + + dev_dbg(&client->dev, "index=%d\n", v->index); + return 0; +} + +static int fc2580_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) +{ + struct fc2580_dev *dev = fc2580_subdev_to_dev(sd); + struct i2c_client *client = dev->client; + + dev_dbg(&client->dev, "tuner=%d\n", f->tuner); + f->frequency = dev->f_frequency; + return 0; +} + +static int fc2580_s_frequency(struct v4l2_subdev *sd, + const struct v4l2_frequency *f) +{ + struct fc2580_dev *dev = fc2580_subdev_to_dev(sd); + struct i2c_client *client = dev->client; + + dev_dbg(&client->dev, "tuner=%d type=%d frequency=%u\n", + f->tuner, f->type, f->frequency); + + dev->f_frequency = clamp_t(unsigned int, f->frequency, + bands[0].rangelow, bands[0].rangehigh); + return fc2580_set_params(dev); +} + +static int fc2580_enum_freq_bands(struct v4l2_subdev *sd, + struct v4l2_frequency_band *band) +{ + struct fc2580_dev *dev = fc2580_subdev_to_dev(sd); + struct i2c_client *client = dev->client; + + dev_dbg(&client->dev, "tuner=%d type=%d index=%d\n", + band->tuner, band->type, band->index); + + if (band->index >= ARRAY_SIZE(bands)) + return -EINVAL; + + band->capability = bands[band->index].capability; + band->rangelow = bands[band->index].rangelow; + band->rangehigh = bands[band->index].rangehigh; + return 0; +} + +static const struct v4l2_subdev_tuner_ops fc2580_subdev_tuner_ops = { + .g_tuner = fc2580_g_tuner, + .s_tuner = fc2580_s_tuner, + .g_frequency = fc2580_g_frequency, + .s_frequency = fc2580_s_frequency, + .enum_freq_bands = fc2580_enum_freq_bands, +}; + +static const struct v4l2_subdev_ops fc2580_subdev_ops = { + .core = &fc2580_subdev_core_ops, + .tuner = &fc2580_subdev_tuner_ops, +}; + +static int fc2580_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct fc2580_dev *dev = container_of(ctrl->handler, struct fc2580_dev, hdl); + struct i2c_client *client = dev->client; + int ret; + + dev_dbg(&client->dev, "ctrl: id=%d name=%s cur.val=%d val=%d\n", + ctrl->id, ctrl->name, ctrl->cur.val, ctrl->val); + + switch (ctrl->id) { + case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO: + case V4L2_CID_RF_TUNER_BANDWIDTH: + /* + * TODO: Auto logic does not work 100% correctly as tuner driver + * do not have information to calculate maximum suitable + * bandwidth. Calculating it is responsible of master driver. + */ + dev->f_bandwidth = dev->bandwidth->val; + ret = fc2580_set_params(dev); + break; + default: + dev_dbg(&client->dev, "unknown ctrl"); + ret = -EINVAL; + } + return ret; +} + +static const struct v4l2_ctrl_ops fc2580_ctrl_ops = { + .s_ctrl = fc2580_s_ctrl, +}; +#endif + +static struct v4l2_subdev *fc2580_get_v4l2_subdev(struct i2c_client *client) +{ + struct fc2580_dev *dev = i2c_get_clientdata(client); + + if (dev->subdev.ops) + return &dev->subdev; + else + return NULL; +} + static int fc2580_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -395,9 +574,31 @@ static int fc2580_probe(struct i2c_client *client, goto err_kfree; } +#if IS_ENABLED(CONFIG_VIDEO_V4L2) + /* Register controls */ + v4l2_ctrl_handler_init(&dev->hdl, 2); + dev->bandwidth_auto = v4l2_ctrl_new_std(&dev->hdl, &fc2580_ctrl_ops, + V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, + 0, 1, 1, 1); + dev->bandwidth = v4l2_ctrl_new_std(&dev->hdl, &fc2580_ctrl_ops, + V4L2_CID_RF_TUNER_BANDWIDTH, + 3000, 10000000, 1, 3000); + v4l2_ctrl_auto_cluster(2, &dev->bandwidth_auto, 0, false); + if (dev->hdl.error) { + ret = dev->hdl.error; + dev_err(&client->dev, "Could not initialize controls\n"); + v4l2_ctrl_handler_free(&dev->hdl); + goto err_kfree; + } + dev->subdev.ctrl_handler = &dev->hdl; + dev->f_frequency = bands[0].rangelow; + dev->f_bandwidth = dev->bandwidth->val; + v4l2_i2c_subdev_init(&dev->subdev, client, &fc2580_subdev_ops); +#endif fe->tuner_priv = dev; - memcpy(&fe->ops.tuner_ops, &fc2580_tuner_ops, - sizeof(struct dvb_tuner_ops)); + memcpy(&fe->ops.tuner_ops, &fc2580_dvb_tuner_ops, + sizeof(fe->ops.tuner_ops)); + pdata->get_v4l2_subdev = fc2580_get_v4l2_subdev; i2c_set_clientdata(client, dev); dev_info(&client->dev, "FCI FC2580 successfully identified\n"); @@ -415,6 +616,9 @@ static int fc2580_remove(struct i2c_client *client) dev_dbg(&client->dev, "\n"); +#if IS_ENABLED(CONFIG_VIDEO_V4L2) + v4l2_ctrl_handler_free(&dev->hdl); +#endif kfree(dev); return 0; } diff --git a/drivers/media/tuners/fc2580.h b/drivers/media/tuners/fc2580.h index 61ee0e826cb9..862ea46995d7 100644 --- a/drivers/media/tuners/fc2580.h +++ b/drivers/media/tuners/fc2580.h @@ -22,6 +22,8 @@ #define FC2580_H #include "dvb_frontend.h" +#include +#include /* * I2C address @@ -32,10 +34,13 @@ * struct fc2580_platform_data - Platform data for the fc2580 driver * @clk: Clock frequency (0 = internal clock). * @dvb_frontend: DVB frontend. + * @get_v4l2_subdev: Get V4L2 subdev. */ struct fc2580_platform_data { u32 clk; struct dvb_frontend *dvb_frontend; + + struct v4l2_subdev* (*get_v4l2_subdev)(struct i2c_client *); }; #endif diff --git a/drivers/media/tuners/fc2580_priv.h b/drivers/media/tuners/fc2580_priv.h index bd88b0141141..031a43d7e7af 100644 --- a/drivers/media/tuners/fc2580_priv.h +++ b/drivers/media/tuners/fc2580_priv.h @@ -22,6 +22,8 @@ #define FC2580_PRIV_H #include "fc2580.h" +#include +#include #include #include @@ -131,6 +133,15 @@ struct fc2580_dev { u32 clk; struct i2c_client *client; struct regmap *regmap; + struct v4l2_subdev subdev; + bool active; + unsigned int f_frequency; + unsigned int f_bandwidth; + + /* Controls */ + struct v4l2_ctrl_handler hdl; + struct v4l2_ctrl *bandwidth_auto; + struct v4l2_ctrl *bandwidth; }; #endif -- cgit v1.2.3-59-g8ed1b From fc3a0497b9d84018f13f7af5868c0089d52f6006 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 3 May 2015 21:45:43 -0300 Subject: [media] rtl2832_sdr: add support for fc2580 tuner Add initial support for fc2580 tuner based devices. Tuner is controlled via V4L2 subdevice API. Passes v4l2-compliance tests. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/rtl2832_sdr.c | 110 ++++++++++++++++++++++++------ drivers/media/dvb-frontends/rtl2832_sdr.h | 1 + 2 files changed, 92 insertions(+), 19 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/rtl2832_sdr.c b/drivers/media/dvb-frontends/rtl2832_sdr.c index 3ff8806ca584..c501bcd680b5 100644 --- a/drivers/media/dvb-frontends/rtl2832_sdr.c +++ b/drivers/media/dvb-frontends/rtl2832_sdr.c @@ -39,6 +39,10 @@ static bool rtl2832_sdr_emulated_fmt; module_param_named(emulated_formats, rtl2832_sdr_emulated_fmt, bool, 0644); MODULE_PARM_DESC(emulated_formats, "enable emulated formats (disappears in future)"); +/* Original macro does not contain enough null pointer checks for our need */ +#define V4L2_SUBDEV_HAS_OP(sd, o, f) \ + ((sd) && (sd)->ops && (sd)->ops->o && (sd)->ops->o->f) + #define MAX_BULK_BUFS (10) #define BULK_BUFFER_SIZE (128 * 512) @@ -116,6 +120,7 @@ struct rtl2832_sdr_dev { struct video_device vdev; struct v4l2_device v4l2_dev; + struct v4l2_subdev *v4l2_subdev; /* videobuf2 queue and queued buffers list */ struct vb2_queue vb_queue; @@ -742,6 +747,29 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_dev *dev) ret = rtl2832_sdr_wr_regs(dev, 0x00e, "\xfc", 1); ret = rtl2832_sdr_wr_regs(dev, 0x011, "\xf4", 1); break; + case RTL2832_SDR_TUNER_FC2580: + ret = rtl2832_sdr_wr_regs(dev, 0x112, "\x39", 1); + ret = rtl2832_sdr_wr_regs(dev, 0x102, "\x40", 1); + ret = rtl2832_sdr_wr_regs(dev, 0x103, "\x5a", 1); + ret = rtl2832_sdr_wr_regs(dev, 0x1c7, "\x2c", 1); + ret = rtl2832_sdr_wr_regs(dev, 0x104, "\xcc", 1); + ret = rtl2832_sdr_wr_regs(dev, 0x105, "\xbe", 1); + ret = rtl2832_sdr_wr_regs(dev, 0x1c8, "\x16", 1); + ret = rtl2832_sdr_wr_regs(dev, 0x106, "\x35", 1); + ret = rtl2832_sdr_wr_regs(dev, 0x1c9, "\x21", 1); + ret = rtl2832_sdr_wr_regs(dev, 0x1ca, "\x21", 1); + ret = rtl2832_sdr_wr_regs(dev, 0x1cb, "\x00", 1); + ret = rtl2832_sdr_wr_regs(dev, 0x107, "\x40", 1); + ret = rtl2832_sdr_wr_regs(dev, 0x1cd, "\x10", 1); + ret = rtl2832_sdr_wr_regs(dev, 0x1ce, "\x10", 1); + ret = rtl2832_sdr_wr_regs(dev, 0x108, "\x80", 1); + ret = rtl2832_sdr_wr_regs(dev, 0x109, "\x7f", 1); + ret = rtl2832_sdr_wr_regs(dev, 0x10a, "\x9c", 1); + ret = rtl2832_sdr_wr_regs(dev, 0x10b, "\x7f", 1); + ret = rtl2832_sdr_wr_regs(dev, 0x00e, "\xfc", 1); + ret = rtl2832_sdr_wr_regs(dev, 0x00e, "\xfc", 1); + ret = rtl2832_sdr_wr_regs(dev, 0x011, "\xe9\xf4", 2); + break; default: dev_notice(&pdev->dev, "Unsupported tuner\n"); } @@ -832,8 +860,10 @@ static int rtl2832_sdr_set_tuner_freq(struct rtl2832_sdr_dev *dev) if (!test_bit(POWER_ON, &dev->flags)) return 0; - if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe); + if (!V4L2_SUBDEV_HAS_OP(dev->v4l2_subdev, tuner, s_frequency)) { + if (fe->ops.tuner_ops.set_params) + fe->ops.tuner_ops.set_params(fe); + } return 0; }; @@ -891,7 +921,11 @@ static int rtl2832_sdr_start_streaming(struct vb2_queue *vq, unsigned int count) set_bit(POWER_ON, &dev->flags); - ret = rtl2832_sdr_set_tuner(dev); + /* wake-up tuner */ + if (V4L2_SUBDEV_HAS_OP(dev->v4l2_subdev, core, s_power)) + ret = v4l2_subdev_call(dev->v4l2_subdev, core, s_power, 1); + else + ret = rtl2832_sdr_set_tuner(dev); if (ret) goto err; @@ -939,7 +973,12 @@ static void rtl2832_sdr_stop_streaming(struct vb2_queue *vq) rtl2832_sdr_free_stream_bufs(dev); rtl2832_sdr_cleanup_queued_bufs(dev); rtl2832_sdr_unset_adc(dev); - rtl2832_sdr_unset_tuner(dev); + + /* sleep tuner */ + if (V4L2_SUBDEV_HAS_OP(dev->v4l2_subdev, core, s_power)) + v4l2_subdev_call(dev->v4l2_subdev, core, s_power, 0); + else + rtl2832_sdr_unset_tuner(dev); clear_bit(POWER_ON, &dev->flags); @@ -968,6 +1007,7 @@ static int rtl2832_sdr_g_tuner(struct file *file, void *priv, { struct rtl2832_sdr_dev *dev = video_drvdata(file); struct platform_device *pdev = dev->pdev; + int ret; dev_dbg(&pdev->dev, "index=%d type=%d\n", v->index, v->type); @@ -977,17 +1017,21 @@ static int rtl2832_sdr_g_tuner(struct file *file, void *priv, v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS; v->rangelow = 300000; v->rangehigh = 3200000; + ret = 0; + } else if (v->index == 1 && + V4L2_SUBDEV_HAS_OP(dev->v4l2_subdev, tuner, g_tuner)) { + ret = v4l2_subdev_call(dev->v4l2_subdev, tuner, g_tuner, v); } else if (v->index == 1) { strlcpy(v->name, "RF: ", sizeof(v->name)); v->type = V4L2_TUNER_RF; v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS; v->rangelow = 50000000; v->rangehigh = 2000000000; + ret = 0; } else { - return -EINVAL; + ret = -EINVAL; } - - return 0; + return ret; } static int rtl2832_sdr_s_tuner(struct file *file, void *priv, @@ -995,12 +1039,21 @@ static int rtl2832_sdr_s_tuner(struct file *file, void *priv, { struct rtl2832_sdr_dev *dev = video_drvdata(file); struct platform_device *pdev = dev->pdev; + int ret; dev_dbg(&pdev->dev, "\n"); - if (v->index > 1) - return -EINVAL; - return 0; + if (v->index == 0) { + ret = 0; + } else if (v->index == 1 && + V4L2_SUBDEV_HAS_OP(dev->v4l2_subdev, tuner, s_tuner)) { + ret = v4l2_subdev_call(dev->v4l2_subdev, tuner, s_tuner, v); + } else if (v->index == 1) { + ret = 0; + } else { + ret = -EINVAL; + } + return ret; } static int rtl2832_sdr_enum_freq_bands(struct file *file, void *priv, @@ -1008,6 +1061,7 @@ static int rtl2832_sdr_enum_freq_bands(struct file *file, void *priv, { struct rtl2832_sdr_dev *dev = video_drvdata(file); struct platform_device *pdev = dev->pdev; + int ret; dev_dbg(&pdev->dev, "tuner=%d type=%d index=%d\n", band->tuner, band->type, band->index); @@ -1017,16 +1071,20 @@ static int rtl2832_sdr_enum_freq_bands(struct file *file, void *priv, return -EINVAL; *band = bands_adc[band->index]; + ret = 0; + } else if (band->tuner == 1 && + V4L2_SUBDEV_HAS_OP(dev->v4l2_subdev, tuner, enum_freq_bands)) { + ret = v4l2_subdev_call(dev->v4l2_subdev, tuner, enum_freq_bands, band); } else if (band->tuner == 1) { if (band->index >= ARRAY_SIZE(bands_fm)) return -EINVAL; *band = bands_fm[band->index]; + ret = 0; } else { - return -EINVAL; + ret = -EINVAL; } - - return 0; + return ret; } static int rtl2832_sdr_g_frequency(struct file *file, void *priv, @@ -1034,20 +1092,25 @@ static int rtl2832_sdr_g_frequency(struct file *file, void *priv, { struct rtl2832_sdr_dev *dev = video_drvdata(file); struct platform_device *pdev = dev->pdev; - int ret = 0; + int ret; dev_dbg(&pdev->dev, "tuner=%d type=%d\n", f->tuner, f->type); if (f->tuner == 0) { f->frequency = dev->f_adc; f->type = V4L2_TUNER_ADC; + ret = 0; + } else if (f->tuner == 1 && + V4L2_SUBDEV_HAS_OP(dev->v4l2_subdev, tuner, g_frequency)) { + f->type = V4L2_TUNER_RF; + ret = v4l2_subdev_call(dev->v4l2_subdev, tuner, g_frequency, f); } else if (f->tuner == 1) { f->frequency = dev->f_tuner; f->type = V4L2_TUNER_RF; + ret = 0; } else { - return -EINVAL; + ret = -EINVAL; } - return ret; } @@ -1074,11 +1137,14 @@ static int rtl2832_sdr_s_frequency(struct file *file, void *priv, band = 2; dev->f_adc = clamp_t(unsigned int, f->frequency, - bands_adc[band].rangelow, - bands_adc[band].rangehigh); + bands_adc[band].rangelow, + bands_adc[band].rangehigh); dev_dbg(&pdev->dev, "ADC frequency=%u Hz\n", dev->f_adc); ret = rtl2832_sdr_set_adc(dev); + } else if (f->tuner == 1 && + V4L2_SUBDEV_HAS_OP(dev->v4l2_subdev, tuner, s_frequency)) { + ret = v4l2_subdev_call(dev->v4l2_subdev, tuner, s_frequency, f); } else if (f->tuner == 1) { dev->f_tuner = clamp_t(unsigned int, f->frequency, bands_fm[0].rangelow, @@ -1089,7 +1155,6 @@ static int rtl2832_sdr_s_frequency(struct file *file, void *priv, } else { ret = -EINVAL; } - return ret; } @@ -1329,6 +1394,7 @@ static int rtl2832_sdr_probe(struct platform_device *pdev) /* setup the state */ subdev = pdata->v4l2_subdev; + dev->v4l2_subdev = pdata->v4l2_subdev; dev->pdev = pdev; dev->udev = pdata->dvb_usb_device->udev; dev->f_adc = bands_adc[0].rangelow; @@ -1388,6 +1454,12 @@ static int rtl2832_sdr_probe(struct platform_device *pdev) 6000000); v4l2_ctrl_auto_cluster(2, &dev->bandwidth_auto, 0, false); break; + case RTL2832_SDR_TUNER_FC2580: + v4l2_ctrl_handler_init(&dev->hdl, 2); + if (subdev) + v4l2_ctrl_add_handler(&dev->hdl, subdev->ctrl_handler, + NULL); + break; default: v4l2_ctrl_handler_init(&dev->hdl, 0); dev_err(&pdev->dev, "Unsupported tuner\n"); diff --git a/drivers/media/dvb-frontends/rtl2832_sdr.h b/drivers/media/dvb-frontends/rtl2832_sdr.h index d2594768bff2..342ea84860df 100644 --- a/drivers/media/dvb-frontends/rtl2832_sdr.h +++ b/drivers/media/dvb-frontends/rtl2832_sdr.h @@ -47,6 +47,7 @@ struct rtl2832_sdr_platform_data { /* * XXX: This list must be kept sync with dvb_usb_rtl28xxu USB IF driver. */ +#define RTL2832_SDR_TUNER_FC2580 0x21 #define RTL2832_SDR_TUNER_TUA9001 0x24 #define RTL2832_SDR_TUNER_FC0012 0x26 #define RTL2832_SDR_TUNER_E4000 0x27 -- cgit v1.2.3-59-g8ed1b From 9ea964f369f109580c3ae5bbe3405c79fc855203 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 3 May 2015 21:48:47 -0300 Subject: [media] rtl28xxu: load SDR module for fc2580 based devices Load rtl2832_sdr driver for devices having fc2580 tuner. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 2d2d50625048..c3cac4c12fb3 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -1201,6 +1201,7 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) break; } dev->i2c_client_tuner = client; + subdev = fc2580_pdata.get_v4l2_subdev(client); } break; case TUNER_RTL2832_TUA9001: { @@ -1299,6 +1300,7 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) /* register SDR */ switch (dev->tuner) { + case TUNER_RTL2832_FC2580: case TUNER_RTL2832_FC0012: case TUNER_RTL2832_FC0013: case TUNER_RTL2832_E4000: -- cgit v1.2.3-59-g8ed1b From 18b3b3b8edb136d90e5d16d986ce9ae7eaeb0776 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Mon, 4 May 2015 05:07:29 -0300 Subject: [media] media/vivid: Add support for Y16 format Support for V4L2_PIX_FMT_Y16, a 16 bit greyscale format. Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-tpg.c | 9 ++++++++- drivers/media/platform/vivid/vivid-vid-common.c | 8 ++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/vivid/vivid-tpg.c b/drivers/media/platform/vivid/vivid-tpg.c index 4df755aa7e48..9e50303a19c5 100644 --- a/drivers/media/platform/vivid/vivid-tpg.c +++ b/drivers/media/platform/vivid/vivid-tpg.c @@ -220,6 +220,7 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) case V4L2_PIX_FMT_ARGB32: case V4L2_PIX_FMT_ABGR32: case V4L2_PIX_FMT_GREY: + case V4L2_PIX_FMT_Y16: tpg->is_yuv = false; break; case V4L2_PIX_FMT_YUV444: @@ -313,6 +314,7 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) case V4L2_PIX_FMT_YUV444: case V4L2_PIX_FMT_YUV555: case V4L2_PIX_FMT_YUV565: + case V4L2_PIX_FMT_Y16: tpg->twopixelsize[0] = 2 * 2; break; case V4L2_PIX_FMT_RGB24: @@ -712,7 +714,8 @@ static void precalculate_color(struct tpg_data *tpg, int k) g <<= 4; b <<= 4; } - if (tpg->qual == TPG_QUAL_GRAY || tpg->fourcc == V4L2_PIX_FMT_GREY) { + if (tpg->qual == TPG_QUAL_GRAY || tpg->fourcc == V4L2_PIX_FMT_GREY || + tpg->fourcc == V4L2_PIX_FMT_Y16) { /* Rec. 709 Luma function */ /* (0.2126, 0.7152, 0.0722) * (255 * 256) */ r = g = b = (13879 * r + 46688 * g + 4713 * b) >> 16; @@ -895,6 +898,10 @@ static void gen_twopix(struct tpg_data *tpg, case V4L2_PIX_FMT_GREY: buf[0][offset] = r_y; break; + case V4L2_PIX_FMT_Y16: + buf[0][offset] = 0; + buf[0][offset+1] = r_y; + break; case V4L2_PIX_FMT_YUV422P: case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YUV420M: diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c index 6ba874420485..96ccd3c38dd2 100644 --- a/drivers/media/platform/vivid/vivid-vid-common.c +++ b/drivers/media/platform/vivid/vivid-vid-common.c @@ -188,6 +188,14 @@ struct vivid_fmt vivid_formats[] = { .planes = 1, .buffers = 1, }, + { + .fourcc = V4L2_PIX_FMT_Y16, + .vdownsampling = { 1 }, + .bit_depth = { 16 }, + .is_yuv = true, + .planes = 1, + .buffers = 1, + }, { .fourcc = V4L2_PIX_FMT_RGB332, /* rrrgggbb */ .vdownsampling = { 1 }, -- cgit v1.2.3-59-g8ed1b From ed1bc664daf58af7da47581fe43d42b95a1de65a Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Mon, 4 May 2015 05:07:32 -0300 Subject: [media] media/vivid: Code cleanout Remove code duplication by merging two cases in a switch. Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-tpg.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/vivid/vivid-tpg.c b/drivers/media/platform/vivid/vivid-tpg.c index 9e50303a19c5..af4bc9780099 100644 --- a/drivers/media/platform/vivid/vivid-tpg.c +++ b/drivers/media/platform/vivid/vivid-tpg.c @@ -293,6 +293,7 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) } switch (fourcc) { + case V4L2_PIX_FMT_GREY: case V4L2_PIX_FMT_RGB332: tpg->twopixelsize[0] = 2; break; @@ -331,9 +332,6 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) case V4L2_PIX_FMT_YUV32: tpg->twopixelsize[0] = 2 * 4; break; - case V4L2_PIX_FMT_GREY: - tpg->twopixelsize[0] = 2; - break; case V4L2_PIX_FMT_NV12: case V4L2_PIX_FMT_NV21: case V4L2_PIX_FMT_NV12M: -- cgit v1.2.3-59-g8ed1b From c9bc9f50753d20d24836831d40e1efe74c21b0ef Mon Sep 17 00:00:00 2001 From: Prashant Laddha Date: Tue, 5 May 2015 10:16:27 -0300 Subject: [media] v4l2-dv-timings: fix overflow in gtf timings calculation The intermediate calculation in the expression for hblank can exceed 32 bit signed range. This overflow can lead to negative values for hblank. Typecasting intermediate variable to higher precision. Cc: Martin Bugge Signed-off-by: Prashant Laddha [hans.verkuil@cisco.com: made the denominator u32, since that's what div_u64 expects] Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-dv-timings.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c index 37f0d6f89878..5792192bce6c 100644 --- a/drivers/media/v4l2-core/v4l2-dv-timings.c +++ b/drivers/media/v4l2-core/v4l2-dv-timings.c @@ -25,6 +25,7 @@ #include #include #include +#include MODULE_AUTHOR("Hans Verkuil"); MODULE_DESCRIPTION("V4L2 DV Timings Helper Functions"); @@ -554,16 +555,23 @@ bool v4l2_detect_gtf(unsigned frame_height, image_width = (image_width + GTF_CELL_GRAN/2) & ~(GTF_CELL_GRAN - 1); /* Horizontal */ - if (default_gtf) - h_blank = ((image_width * GTF_D_C_PRIME * hfreq) - - (image_width * GTF_D_M_PRIME * 1000) + - (hfreq * (100 - GTF_D_C_PRIME) + GTF_D_M_PRIME * 1000) / 2) / - (hfreq * (100 - GTF_D_C_PRIME) + GTF_D_M_PRIME * 1000); - else - h_blank = ((image_width * GTF_S_C_PRIME * hfreq) - - (image_width * GTF_S_M_PRIME * 1000) + - (hfreq * (100 - GTF_S_C_PRIME) + GTF_S_M_PRIME * 1000) / 2) / - (hfreq * (100 - GTF_S_C_PRIME) + GTF_S_M_PRIME * 1000); + if (default_gtf) { + u64 num; + u32 den; + + num = ((image_width * GTF_D_C_PRIME * (u64)hfreq) - + ((u64)image_width * GTF_D_M_PRIME * 1000)); + den = hfreq * (100 - GTF_D_C_PRIME) + GTF_D_M_PRIME * 1000; + h_blank = div_u64((num + (den >> 1)), den); + } else { + u64 num; + u32 den; + + num = ((image_width * GTF_S_C_PRIME * (u64)hfreq) - + ((u64)image_width * GTF_S_M_PRIME * 1000)); + den = hfreq * (100 - GTF_S_C_PRIME) + GTF_S_M_PRIME * 1000; + h_blank = div_u64((num + (den >> 1)), den); + } h_blank = ((h_blank + GTF_CELL_GRAN) / (2 * GTF_CELL_GRAN)) * (2 * GTF_CELL_GRAN); -- cgit v1.2.3-59-g8ed1b From b59b100c91ff4e742ebbc759dfca7057708da091 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 7 May 2015 03:22:14 -0300 Subject: [media] sta2x11: use monotonic timestamp V4L2 drivers should use MONOTONIC timestamps instead of gettimeofday, which is affected by daylight savings time. Signed-off-by: Hans Verkuil Acked-by: Federico Vaga Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/sta2x11/sta2x11_vip.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/sta2x11/sta2x11_vip.c b/drivers/media/pci/sta2x11/sta2x11_vip.c index d384a6b0b09f..59b3a36a3639 100644 --- a/drivers/media/pci/sta2x11/sta2x11_vip.c +++ b/drivers/media/pci/sta2x11/sta2x11_vip.c @@ -813,7 +813,7 @@ static irqreturn_t vip_irq(int irq, struct sta2x11_vip *vip) /* Disable acquisition */ reg_write(vip, DVP_CTL, reg_read(vip, DVP_CTL) & ~DVP_CTL_ENA); /* Remove the active buffer from the list */ - do_gettimeofday(&vip->active->vb.v4l2_buf.timestamp); + v4l2_get_timestamp(&vip->active->vb.v4l2_buf.timestamp); vip->active->vb.v4l2_buf.sequence = vip->sequence++; vb2_buffer_done(&vip->active->vb, VB2_BUF_STATE_DONE); } @@ -864,6 +864,7 @@ static int sta2x11_vip_init_buffer(struct sta2x11_vip *vip) vip->vb_vidq.buf_struct_size = sizeof(struct vip_buffer); vip->vb_vidq.ops = &vip_video_qops; vip->vb_vidq.mem_ops = &vb2_dma_contig_memops; + vip->vb_vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; err = vb2_queue_init(&vip->vb_vidq); if (err) return err; -- cgit v1.2.3-59-g8ed1b From b9143e5ac5089561e857e223f7750b85a1951547 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 7 May 2015 03:26:21 -0300 Subject: [media] rcar-vin: use monotonic timestamps Even though the rcar-vin driver tells userspace that it will give a monotonic timestamp, it is actually using gettimeofday. Replace this with a proper monotonic timestamp. Signed-off-by: Hans Verkuil Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/soc_camera/rcar_vin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c index 4dc3288ddd06..db7700b0af7c 100644 --- a/drivers/media/platform/soc_camera/rcar_vin.c +++ b/drivers/media/platform/soc_camera/rcar_vin.c @@ -899,7 +899,7 @@ static irqreturn_t rcar_vin_irq(int irq, void *data) priv->queue_buf[slot]->v4l2_buf.field = priv->field; priv->queue_buf[slot]->v4l2_buf.sequence = priv->sequence++; - do_gettimeofday(&priv->queue_buf[slot]->v4l2_buf.timestamp); + v4l2_get_timestamp(&priv->queue_buf[slot]->v4l2_buf.timestamp); vb2_buffer_done(priv->queue_buf[slot], VB2_BUF_STATE_DONE); priv->queue_buf[slot] = NULL; -- cgit v1.2.3-59-g8ed1b From 5afc9a25be8d4e627cf07aa8a7500eafe3664b94 Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Tue, 14 Apr 2015 09:04:50 -0300 Subject: [media] Add support for TechniSat Skystar S2 This patch adds support for the Technisat Skystar S2 - this has been tried before but the cx24120 driver was a bit out of shape and it didn't got any further: https://patchwork.linuxtv.org/patch/10575/ It is an old card, but currently being sold off for next to nothing, so it's proving quite popular of late. Noticing it's quite similar to the cx24116 and cx24117 I've rewritten the driver in a similar way. There were a few registers and commands from those drivers missing from this one I've tested out and found they do something so they've been added in to speed up tuning and to make get_frontend return something useful. Signed-off-by: Jemma Denson Signed-off-by: Patrick.Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/b2c2/Kconfig | 1 + drivers/media/common/b2c2/flexcop-fe-tuner.c | 51 +- drivers/media/common/b2c2/flexcop-misc.c | 1 + drivers/media/common/b2c2/flexcop-reg.h | 1 + drivers/media/dvb-frontends/Kconfig | 7 + drivers/media/dvb-frontends/Makefile | 1 + drivers/media/dvb-frontends/cx24120.c | 1577 ++++++++++++++++++++++++++ drivers/media/dvb-frontends/cx24120.h | 56 + 8 files changed, 1688 insertions(+), 7 deletions(-) create mode 100644 drivers/media/dvb-frontends/cx24120.c create mode 100644 drivers/media/dvb-frontends/cx24120.h (limited to 'drivers/media') diff --git a/drivers/media/common/b2c2/Kconfig b/drivers/media/common/b2c2/Kconfig index a8c6cdfaa2f5..e5936380b1e5 100644 --- a/drivers/media/common/b2c2/Kconfig +++ b/drivers/media/common/b2c2/Kconfig @@ -14,6 +14,7 @@ config DVB_B2C2_FLEXCOP select DVB_S5H1420 if MEDIA_SUBDRV_AUTOSELECT select DVB_TUNER_ITD1000 if MEDIA_SUBDRV_AUTOSELECT select DVB_ISL6421 if MEDIA_SUBDRV_AUTOSELECT + select DVB_CX24120 if MEDIA_SUBDRV_AUTOSELECT select DVB_CX24123 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT select DVB_TUNER_CX24113 if MEDIA_SUBDRV_AUTOSELECT diff --git a/drivers/media/common/b2c2/flexcop-fe-tuner.c b/drivers/media/common/b2c2/flexcop-fe-tuner.c index 7e14e90d2922..66f6910a1810 100644 --- a/drivers/media/common/b2c2/flexcop-fe-tuner.c +++ b/drivers/media/common/b2c2/flexcop-fe-tuner.c @@ -12,6 +12,7 @@ #include "cx24113.h" #include "cx24123.h" #include "isl6421.h" +#include "cx24120.h" #include "mt352.h" #include "bcm3510.h" #include "nxt200x.h" @@ -26,6 +27,16 @@ #define FE_SUPPORTED(fe) (defined(CONFIG_DVB_##fe) || \ (defined(CONFIG_DVB_##fe##_MODULE) && defined(MODULE))) +#if FE_SUPPORTED(BCM3510) || FE_SUPPORTED(CX24120) +static int flexcop_fe_request_firmware(struct dvb_frontend *fe, + const struct firmware **fw, char *name) +{ + struct flexcop_device *fc = fe->dvb->priv; + + return request_firmware(fw, name, fc->dev); +} +#endif + /* lnb control */ #if FE_SUPPORTED(MT312) || FE_SUPPORTED(STV0299) static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) @@ -445,13 +456,6 @@ static int airstar_dvbt_attach(struct flexcop_device *fc, /* AirStar ATSC 1st generation */ #if FE_SUPPORTED(BCM3510) -static int flexcop_fe_request_firmware(struct dvb_frontend *fe, - const struct firmware **fw, char* name) -{ - struct flexcop_device *fc = fe->dvb->priv; - return request_firmware(fw, name, fc->dev); -} - static struct bcm3510_config air2pc_atsc_first_gen_config = { .demod_address = 0x0f, .request_firmware = flexcop_fe_request_firmware, @@ -619,6 +623,38 @@ fail: #define cablestar2_attach NULL #endif +/* SkyStar S2 PCI DVB-S/S2 card based on Conexant cx24120/cx24118 */ +#if FE_SUPPORTED(CX24120) && FE_SUPPORTED(ISL6421) +static const struct cx24120_config skystar2_rev3_3_cx24120_config = { + .i2c_addr = 0x55, + .xtal_khz = 10111, + .initial_mpeg_config = { 0xa1, 0x76, 0x07 }, + .request_firmware = flexcop_fe_request_firmware, +}; + +static int skystarS2_rev33_attach(struct flexcop_device *fc, + struct i2c_adapter *i2c) +{ + fc->fe = dvb_attach(cx24120_attach, + &skystar2_rev3_3_cx24120_config, i2c); + if (fc->fe == NULL) + return 0; + + fc->dev_type = FC_SKYS2_REV33; + fc->fc_i2c_adap[2].no_base_addr = 1; + if ((dvb_attach(isl6421_attach, fc->fe, + &fc->fc_i2c_adap[2].i2c_adap, 0x08, 0, 0, false) == NULL)) { + err("ISL6421 could NOT be attached!"); + return 0; + } + info("ISL6421 successfully attached."); + + return 1; +} +#else +#define skystarS2_rev33_attach NULL +#endif + static struct { flexcop_device_type_t type; int (*attach)(struct flexcop_device *, struct i2c_adapter *); @@ -632,6 +668,7 @@ static struct { { FC_AIR_ATSC1, airstar_atsc1_attach }, { FC_CABLE, cablestar2_attach }, { FC_SKY_REV23, skystar2_rev23_attach }, + { FC_SKYS2_REV33, skystarS2_rev33_attach }, }; /* try to figure out the frontend */ diff --git a/drivers/media/common/b2c2/flexcop-misc.c b/drivers/media/common/b2c2/flexcop-misc.c index f06f3a9070f5..b8eff235367d 100644 --- a/drivers/media/common/b2c2/flexcop-misc.c +++ b/drivers/media/common/b2c2/flexcop-misc.c @@ -56,6 +56,7 @@ static const char *flexcop_device_names[] = { [FC_SKY_REV26] = "Sky2PC/SkyStar 2 DVB-S rev 2.6", [FC_SKY_REV27] = "Sky2PC/SkyStar 2 DVB-S rev 2.7a/u", [FC_SKY_REV28] = "Sky2PC/SkyStar 2 DVB-S rev 2.8", + [FC_SKYS2_REV33] = "Sky2PC/SkyStar S2 DVB-S/S2 rev 3.3", }; static const char *flexcop_bus_names[] = { diff --git a/drivers/media/common/b2c2/flexcop-reg.h b/drivers/media/common/b2c2/flexcop-reg.h index dc4528dcbb98..835c54d60e74 100644 --- a/drivers/media/common/b2c2/flexcop-reg.h +++ b/drivers/media/common/b2c2/flexcop-reg.h @@ -24,6 +24,7 @@ typedef enum { FC_SKY_REV26, FC_SKY_REV27, FC_SKY_REV28, + FC_SKYS2_REV33, } flexcop_device_type_t; typedef enum { diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index 97c151d5b2e1..7ff3ec4d8ab6 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -223,6 +223,13 @@ config DVB_CX24117 help A Dual DVB-S/S2 tuner module. Say Y when you want to support this frontend. +config DVB_CX24120 + tristate "Conexant CX24120 based" + depends on DVB_CORE && I2C + default m if !MEDIA_SUBDRV_AUTOSELECT + help + A DVB-S/DVB-S2 tuner module. Say Y when you want to support this frontend. + config DVB_SI21XX tristate "Silicon Labs SI21XX based" depends on DVB_CORE && I2C diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile index 23d399bec804..ebab1b83e1fc 100644 --- a/drivers/media/dvb-frontends/Makefile +++ b/drivers/media/dvb-frontends/Makefile @@ -83,6 +83,7 @@ obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o obj-$(CONFIG_DVB_AF9013) += af9013.o obj-$(CONFIG_DVB_CX24116) += cx24116.o obj-$(CONFIG_DVB_CX24117) += cx24117.o +obj-$(CONFIG_DVB_CX24120) += cx24120.o obj-$(CONFIG_DVB_SI21XX) += si21xx.o obj-$(CONFIG_DVB_SI2168) += si2168.o obj-$(CONFIG_DVB_STV0288) += stv0288.o diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c new file mode 100644 index 000000000000..344d8b8e37e5 --- /dev/null +++ b/drivers/media/dvb-frontends/cx24120.c @@ -0,0 +1,1577 @@ +/* + Conexant cx24120/cx24118 - DVBS/S2 Satellite demod/tuner driver + + Copyright (C) 2008 Patrick Boettcher + Copyright (C) 2009 Sergey Tyurin + Updated 2012 by Jannis Achstetter + Copyright (C) 2015 Jemma Denson + April 2015 + Refactored & simplified driver + Updated to work with delivery system supplied by DVBv5 + Add frequency, fec & pilot to get_frontend + + Cards supported: Technisat Skystar S2 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +*/ + +#include +#include +#include +#include +#include +#include +#include "dvb_frontend.h" +#include "cx24120.h" + +#define CX24120_SEARCH_RANGE_KHZ 5000 +#define CX24120_FIRMWARE "dvb-fe-cx24120-1.20.58.2.fw" + +/* cx24120 i2c registers */ +#define CX24120_REG_CMD_START (0x00) /* write cmd_id */ +#define CX24120_REG_CMD_ARGS (0x01) /* write command arguments */ +#define CX24120_REG_CMD_END (0x1f) /* write 0x01 for end */ + +#define CX24120_REG_MAILBOX (0x33) +#define CX24120_REG_FREQ3 (0x34) /* frequency */ +#define CX24120_REG_FREQ2 (0x35) +#define CX24120_REG_FREQ1 (0x36) + +#define CX24120_REG_FECMODE (0x39) /* FEC status */ +#define CX24120_REG_STATUS (0x3a) /* Tuner status */ +#define CX24120_REG_SIGSTR_H (0x3a) /* Signal strength high */ +#define CX24120_REG_SIGSTR_L (0x3b) /* Signal strength low byte */ +#define CX24120_REG_QUALITY_H (0x40) /* SNR high byte */ +#define CX24120_REG_QUALITY_L (0x41) /* SNR low byte */ + +#define CX24120_REG_BER_HH (0x47) /* BER high byte of high word */ +#define CX24120_REG_BER_HL (0x48) /* BER low byte of high word */ +#define CX24120_REG_BER_LH (0x49) /* BER high byte of low word */ +#define CX24120_REG_BER_LL (0x4a) /* BER low byte of low word */ + +#define CX24120_REG_UCB_H (0x50) /* UCB high byte */ +#define CX24120_REG_UCB_L (0x51) /* UCB low byte */ + +#define CX24120_REG_CLKDIV (0xe6) +#define CX24120_REG_RATEDIV (0xf0) + +#define CX24120_REG_REVISION (0xff) /* Chip revision (ro) */ + + +/* Command messages */ +enum command_message_id { + CMD_VCO_SET = 0x10, /* cmd.len = 12; */ + CMD_TUNEREQUEST = 0x11, /* cmd.len = 15; */ + + CMD_MPEG_ONOFF = 0x13, /* cmd.len = 4; */ + CMD_MPEG_INIT = 0x14, /* cmd.len = 7; */ + CMD_BANDWIDTH = 0x15, /* cmd.len = 12; */ + CMD_CLOCK_READ = 0x16, /* read clock */ + CMD_CLOCK_SET = 0x17, /* cmd.len = 10; */ + + CMD_DISEQC_MSG1 = 0x20, /* cmd.len = 11; */ + CMD_DISEQC_MSG2 = 0x21, /* cmd.len = d->msg_len + 6; */ + CMD_SETVOLTAGE = 0x22, /* cmd.len = 2; */ + CMD_SETTONE = 0x23, /* cmd.len = 4; */ + CMD_DISEQC_BURST = 0x24, /* cmd.len not used !!! */ + + CMD_READ_SNR = 0x1a, /* Read signal strength */ + CMD_START_TUNER = 0x1b, /* ??? */ + + CMD_FWVERSION = 0x35, + + CMD_TUNER_INIT = 0x3c, /* cmd.len = 0x03; */ +}; + +#define CX24120_MAX_CMD_LEN 30 + +/* pilot mask */ +#define CX24120_PILOT_OFF (0x00) +#define CX24120_PILOT_ON (0x40) +#define CX24120_PILOT_AUTO (0x80) + +/* signal status */ +#define CX24120_HAS_SIGNAL (0x01) +#define CX24120_HAS_CARRIER (0x02) +#define CX24120_HAS_VITERBI (0x04) +#define CX24120_HAS_LOCK (0x08) +#define CX24120_HAS_UNK1 (0x10) +#define CX24120_HAS_UNK2 (0x20) +#define CX24120_STATUS_MASK (0x0f) +#define CX24120_SIGNAL_MASK (0xc0) + +#define info(args...) do { printk(KERN_INFO "cx24120: "); \ + printk(args); } while (0) +#define err(args...) do { printk(KERN_ERR "cx24120: ### ERROR: "); \ + printk(args); } while (0) + + +/* The Demod/Tuner can't easily provide these, we cache them */ +struct cx24120_tuning { + u32 frequency; + u32 symbol_rate; + fe_spectral_inversion_t inversion; + fe_code_rate_t fec; + + fe_delivery_system_t delsys; + fe_modulation_t modulation; + fe_pilot_t pilot; + + /* Demod values */ + u8 fec_val; + u8 fec_mask; + u8 clkdiv; + u8 ratediv; + u8 inversion_val; + u8 pilot_val; +}; + + +/* Private state */ +struct cx24120_state { + struct i2c_adapter *i2c; + const struct cx24120_config *config; + struct dvb_frontend frontend; + + u8 cold_init; + u8 mpeg_enabled; + + /* current and next tuning parameters */ + struct cx24120_tuning dcur; + struct cx24120_tuning dnxt; +}; + + +/* Command message to firmware */ +struct cx24120_cmd { + u8 id; + u8 len; + u8 arg[CX24120_MAX_CMD_LEN]; +}; + + +/* Read single register */ +static int cx24120_readreg(struct cx24120_state *state, u8 reg) +{ + int ret; + u8 buf = 0; + struct i2c_msg msg[] = { + { .addr = state->config->i2c_addr, + .flags = 0, + .len = 1, + .buf = ® }, + + { .addr = state->config->i2c_addr, + .flags = I2C_M_RD, + .len = 1, + .buf = &buf } + }; + ret = i2c_transfer(state->i2c, msg, 2); + if (ret != 2) { + err("Read error: reg=0x%02x, ret=0x%02x)\n", reg, ret); + return ret; + } + + dev_dbg(&state->i2c->dev, "%s: reg=0x%02x; data=0x%02x\n", + __func__, reg, buf); + + return buf; +} + + +/* Write single register */ +static int cx24120_writereg(struct cx24120_state *state, u8 reg, u8 data) +{ + u8 buf[] = { reg, data }; + struct i2c_msg msg = { + .addr = state->config->i2c_addr, + .flags = 0, + .buf = buf, + .len = 2 }; + int ret; + + ret = i2c_transfer(state->i2c, &msg, 1); + if (ret != 1) { + err("Write error: i2c_write error(err == %i, 0x%02x: 0x%02x)\n", + ret, reg, data); + return ret; + } + + dev_dbg(&state->i2c->dev, "%s: reg=0x%02x; data=0x%02x\n", + __func__, reg, data); + + return 0; +} + + +/* Write multiple registers */ +static int cx24120_writeregN(struct cx24120_state *state, + u8 reg, const u8 *values, u16 len, u8 incr) +{ + int ret; + u8 buf[5]; /* maximum 4 data bytes at once - flexcop limitation + (very limited i2c-interface this one) */ + + struct i2c_msg msg = { + .addr = state->config->i2c_addr, + .flags = 0, + .buf = buf, + .len = len }; + + while (len) { + buf[0] = reg; + msg.len = len > 4 ? 4 : len; + memcpy(&buf[1], values, msg.len); + + len -= msg.len; /* data length revers counter */ + values += msg.len; /* incr data pointer */ + + if (incr) + reg += msg.len; + msg.len++; /* don't forget the addr byte */ + + ret = i2c_transfer(state->i2c, &msg, 1); + if (ret != 1) { + err("i2c_write error(err == %i, 0x%02x)\n", ret, reg); + return ret; + } + + dev_dbg(&state->i2c->dev, + "%s: reg=0x%02x; data=0x%02x,0x%02x,0x%02x,0x%02x\n", + __func__, reg, + buf[1], buf[2], buf[3], buf[4]); + + } + + return 0; +} + + +static struct dvb_frontend_ops cx24120_ops; + +struct dvb_frontend *cx24120_attach(const struct cx24120_config *config, + struct i2c_adapter *i2c) +{ + struct cx24120_state *state = NULL; + int demod_rev; + + info("Conexant cx24120/cx24118 - DVBS/S2 Satellite demod/tuner\n"); + state = kzalloc(sizeof(struct cx24120_state), + GFP_KERNEL); + if (state == NULL) { + err("Unable to allocate memory for cx24120_state\n"); + goto error; + } + + /* setup the state */ + state->config = config; + state->i2c = i2c; + + /* check if the demod is present and has proper type */ + demod_rev = cx24120_readreg(state, CX24120_REG_REVISION); + switch (demod_rev) { + case 0x07: + info("Demod cx24120 rev. 0x07 detected.\n"); + break; + case 0x05: + info("Demod cx24120 rev. 0x05 detected.\n"); + break; + default: + err("Unsupported demod revision: 0x%x detected.\n", + demod_rev); + goto error; + } + + /* create dvb_frontend */ + state->cold_init = 0; + memcpy(&state->frontend.ops, &cx24120_ops, + sizeof(struct dvb_frontend_ops)); + state->frontend.demodulator_priv = state; + + info("Conexant cx24120/cx24118 attached.\n"); + return &state->frontend; + +error: + kfree(state); + return NULL; +} +EXPORT_SYMBOL(cx24120_attach); + +static int cx24120_test_rom(struct cx24120_state *state) +{ + int err, ret; + + err = cx24120_readreg(state, 0xfd); + if (err & 4) { + ret = cx24120_readreg(state, 0xdf) & 0xfe; + err = cx24120_writereg(state, 0xdf, ret); + } + return err; +} + + +static int cx24120_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + struct cx24120_state *state = fe->demodulator_priv; + + *snr = (cx24120_readreg(state, CX24120_REG_QUALITY_H)<<8) | + (cx24120_readreg(state, CX24120_REG_QUALITY_L)); + dev_dbg(&state->i2c->dev, "%s: read SNR index = %d\n", + __func__, *snr); + + return 0; +} + + +static int cx24120_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + struct cx24120_state *state = fe->demodulator_priv; + + *ber = (cx24120_readreg(state, CX24120_REG_BER_HH) << 24) | + (cx24120_readreg(state, CX24120_REG_BER_HL) << 16) | + (cx24120_readreg(state, CX24120_REG_BER_LH) << 8) | + cx24120_readreg(state, CX24120_REG_BER_LL); + dev_dbg(&state->i2c->dev, "%s: read BER index = %d\n", + __func__, *ber); + + return 0; +} + +static int cx24120_msg_mpeg_output_global_config(struct cx24120_state *state, + u8 flag); + +/* Check if we're running a command that needs to disable mpeg out */ +static void cx24120_check_cmd(struct cx24120_state *state, u8 id) +{ + switch (id) { + case CMD_TUNEREQUEST: + case CMD_CLOCK_READ: + case CMD_DISEQC_MSG1: + case CMD_DISEQC_MSG2: + case CMD_SETVOLTAGE: + case CMD_SETTONE: + cx24120_msg_mpeg_output_global_config(state, 0); + /* Old driver would do a msleep(100) here */ + default: + return; + } +} + + +/* Send a message to the firmware */ +static int cx24120_message_send(struct cx24120_state *state, + struct cx24120_cmd *cmd) +{ + int ret, ficus; + + if (state->mpeg_enabled) { + /* Disable mpeg out on certain commands */ + cx24120_check_cmd(state, cmd->id); + } + + ret = cx24120_writereg(state, CX24120_REG_CMD_START, cmd->id); + ret = cx24120_writeregN(state, CX24120_REG_CMD_ARGS, &cmd->arg[0], + cmd->len, 1); + ret = cx24120_writereg(state, CX24120_REG_CMD_END, 0x01); + + ficus = 1000; + while (cx24120_readreg(state, CX24120_REG_CMD_END)) { + msleep(20); + ficus -= 20; + if (ficus == 0) { + err("Error sending message to firmware\n"); + return -EREMOTEIO; + } + } + dev_dbg(&state->i2c->dev, "%s: Successfully send message 0x%02x\n", + __func__, cmd->id); + + return 0; +} + +/* Send a message and fill arg[] with the results */ +static int cx24120_message_sendrcv(struct cx24120_state *state, + struct cx24120_cmd *cmd, u8 numreg) +{ + int ret, i; + + if (numreg > CX24120_MAX_CMD_LEN) { + err("Too many registers to read. cmd->reg = %d", numreg); + return -EREMOTEIO; + } + + ret = cx24120_message_send(state, cmd); + if (ret != 0) + return ret; + + if (!numreg) + return 0; + + /* Read numreg registers starting from register cmd->len */ + for (i = 0; i < numreg; i++) + cmd->arg[i] = cx24120_readreg(state, (cmd->len+i+1)); + + return 0; +} + + + +static int cx24120_read_signal_strength(struct dvb_frontend *fe, + u16 *signal_strength) +{ + struct cx24120_state *state = fe->demodulator_priv; + struct cx24120_cmd cmd; + int ret, sigstr_h, sigstr_l; + + cmd.id = CMD_READ_SNR; + cmd.len = 1; + cmd.arg[0] = 0x00; + + ret = cx24120_message_send(state, &cmd); + if (ret != 0) { + err("error reading signal strength\n"); + return -EREMOTEIO; + } + + /* raw */ + sigstr_h = (cx24120_readreg(state, CX24120_REG_SIGSTR_H) >> 6) << 8; + sigstr_l = cx24120_readreg(state, CX24120_REG_SIGSTR_L); + dev_dbg(&state->i2c->dev, "%s: Signal strength from firmware= 0x%x\n", + __func__, (sigstr_h | sigstr_l)); + + /* cooked */ + *signal_strength = ((sigstr_h | sigstr_l) << 5) & 0x0000ffff; + dev_dbg(&state->i2c->dev, "%s: Signal strength= 0x%x\n", + __func__, *signal_strength); + + return 0; +} + + +static int cx24120_msg_mpeg_output_global_config(struct cx24120_state *state, + u8 enable) +{ + struct cx24120_cmd cmd; + int ret; + + cmd.id = CMD_MPEG_ONOFF; + cmd.len = 4; + cmd.arg[0] = 0x01; + cmd.arg[1] = 0x00; + cmd.arg[2] = enable ? 0 : (u8)(-1); + cmd.arg[3] = 0x01; + + ret = cx24120_message_send(state, &cmd); + if (ret != 0) { + dev_dbg(&state->i2c->dev, + "%s: Failed to set MPEG output to %s\n", + __func__, + (enable)?"enabled":"disabled"); + return ret; + } + + state->mpeg_enabled = enable; + dev_dbg(&state->i2c->dev, "%s: MPEG output %s\n", + __func__, + (enable)?"enabled":"disabled"); + + return 0; +} + + +static int cx24120_msg_mpeg_output_config(struct cx24120_state *state, u8 seq) +{ + struct cx24120_cmd cmd; + struct cx24120_initial_mpeg_config i = + state->config->initial_mpeg_config; + + cmd.id = CMD_MPEG_INIT; + cmd.len = 7; + cmd.arg[0] = seq; /* sequental number - can be 0,1,2 */ + cmd.arg[1] = ((i.x1 & 0x01) << 1) | ((i.x1 >> 1) & 0x01); + cmd.arg[2] = 0x05; + cmd.arg[3] = 0x02; + cmd.arg[4] = ((i.x2 >> 1) & 0x01); + cmd.arg[5] = (i.x2 & 0xf0) | (i.x3 & 0x0f); + cmd.arg[6] = 0x10; + + return cx24120_message_send(state, &cmd); +} + + +static int cx24120_diseqc_send_burst(struct dvb_frontend *fe, + fe_sec_mini_cmd_t burst) +{ + struct cx24120_state *state = fe->demodulator_priv; + struct cx24120_cmd cmd; + + /* Yes, cmd.len is set to zero. The old driver + * didn't specify any len, but also had a + * memset 0 before every use of the cmd struct + * which would have set it to zero. + * This quite probably needs looking into. + */ + cmd.id = CMD_DISEQC_BURST; + cmd.len = 0; + cmd.arg[0] = 0x00; + if (burst) + cmd.arg[1] = 0x01; + dev_dbg(&state->i2c->dev, "%s: burst sent.\n", __func__); + + return cx24120_message_send(state, &cmd); +} + + +static int cx24120_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) +{ + struct cx24120_state *state = fe->demodulator_priv; + struct cx24120_cmd cmd; + + dev_dbg(&state->i2c->dev, "%s(%d)\n", + __func__, tone); + + if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) { + err("Invalid tone=%d\n", tone); + return -EINVAL; + } + + cmd.id = CMD_SETTONE; + cmd.len = 4; + cmd.arg[0] = 0x00; + cmd.arg[1] = 0x00; + cmd.arg[2] = 0x00; + cmd.arg[3] = (tone == SEC_TONE_ON)?0x01:0x00; + + return cx24120_message_send(state, &cmd); +} + + +static int cx24120_set_voltage(struct dvb_frontend *fe, + fe_sec_voltage_t voltage) +{ + struct cx24120_state *state = fe->demodulator_priv; + struct cx24120_cmd cmd; + + dev_dbg(&state->i2c->dev, "%s(%d)\n", + __func__, voltage); + + cmd.id = CMD_SETVOLTAGE; + cmd.len = 2; + cmd.arg[0] = 0x00; + cmd.arg[1] = (voltage == SEC_VOLTAGE_18)?0x01:0x00; + + return cx24120_message_send(state, &cmd); +} + + +static int cx24120_send_diseqc_msg(struct dvb_frontend *fe, + struct dvb_diseqc_master_cmd *d) +{ + struct cx24120_state *state = fe->demodulator_priv; + struct cx24120_cmd cmd; + int back_count; + + dev_dbg(&state->i2c->dev, "%s()\n", __func__); + + cmd.id = CMD_DISEQC_MSG1; + cmd.len = 11; + cmd.arg[0] = 0x00; + cmd.arg[1] = 0x00; + cmd.arg[2] = 0x03; + cmd.arg[3] = 0x16; + cmd.arg[4] = 0x28; + cmd.arg[5] = 0x01; + cmd.arg[6] = 0x01; + cmd.arg[7] = 0x14; + cmd.arg[8] = 0x19; + cmd.arg[9] = 0x14; + cmd.arg[10] = 0x1e; + + if (cx24120_message_send(state, &cmd)) { + err("send 1st message(0x%x) failed\n", cmd.id); + return -EREMOTEIO; + } + + cmd.id = CMD_DISEQC_MSG2; + cmd.len = d->msg_len + 6; + cmd.arg[0] = 0x00; + cmd.arg[1] = 0x01; + cmd.arg[2] = 0x02; + cmd.arg[3] = 0x00; + cmd.arg[4] = 0x00; + cmd.arg[5] = d->msg_len; + + memcpy(&cmd.arg[6], &d->msg, d->msg_len); + + if (cx24120_message_send(state, &cmd)) { + err("send 2nd message(0x%x) failed\n", cmd.id); + return -EREMOTEIO; + } + + back_count = 500; + do { + if (!(cx24120_readreg(state, 0x93) & 0x01)) { + dev_dbg(&state->i2c->dev, + "%s: diseqc sequence sent success\n", + __func__); + return 0; + } + msleep(20); + back_count -= 20; + } while (back_count); + + err("Too long waiting for diseqc.\n"); + return -ETIMEDOUT; +} + + +/* Read current tuning status */ +static int cx24120_read_status(struct dvb_frontend *fe, fe_status_t *status) +{ + struct cx24120_state *state = fe->demodulator_priv; + int lock; + + lock = cx24120_readreg(state, CX24120_REG_STATUS); + + dev_dbg(&state->i2c->dev, "%s() status = 0x%02x\n", + __func__, lock); + + *status = 0; + + if (lock & CX24120_HAS_SIGNAL) + *status = FE_HAS_SIGNAL; + if (lock & CX24120_HAS_CARRIER) + *status |= FE_HAS_CARRIER; + if (lock & CX24120_HAS_VITERBI) + *status |= FE_HAS_VITERBI | FE_HAS_SYNC; + if (lock & CX24120_HAS_LOCK) + *status |= FE_HAS_LOCK; + + /* TODO: is FE_HAS_SYNC in the right place? + * Other cx241xx drivers have this slightly + * different */ + + return 0; +} + + +/* FEC & modulation lookup table + * Used for decoding the REG_FECMODE register + * once tuned in. + */ +static struct cx24120_modfec { + fe_delivery_system_t delsys; + fe_modulation_t mod; + fe_code_rate_t fec; + u8 val; +} modfec_lookup_table[] = { +/*delsys mod fec val */ +{ SYS_DVBS, QPSK, FEC_1_2, 0x01 }, +{ SYS_DVBS, QPSK, FEC_2_3, 0x02 }, +{ SYS_DVBS, QPSK, FEC_3_4, 0x03 }, +{ SYS_DVBS, QPSK, FEC_4_5, 0x04 }, +{ SYS_DVBS, QPSK, FEC_5_6, 0x05 }, +{ SYS_DVBS, QPSK, FEC_6_7, 0x06 }, +{ SYS_DVBS, QPSK, FEC_7_8, 0x07 }, + +{ SYS_DVBS2, QPSK, FEC_1_2, 0x04 }, +{ SYS_DVBS2, QPSK, FEC_3_5, 0x05 }, +{ SYS_DVBS2, QPSK, FEC_2_3, 0x06 }, +{ SYS_DVBS2, QPSK, FEC_3_4, 0x07 }, +{ SYS_DVBS2, QPSK, FEC_4_5, 0x08 }, +{ SYS_DVBS2, QPSK, FEC_5_6, 0x09 }, +{ SYS_DVBS2, QPSK, FEC_8_9, 0x0a }, +{ SYS_DVBS2, QPSK, FEC_9_10, 0x0b }, + +{ SYS_DVBS2, PSK_8, FEC_3_5, 0x0c }, +{ SYS_DVBS2, PSK_8, FEC_2_3, 0x0d }, +{ SYS_DVBS2, PSK_8, FEC_3_4, 0x0e }, +{ SYS_DVBS2, PSK_8, FEC_5_6, 0x0f }, +{ SYS_DVBS2, PSK_8, FEC_8_9, 0x10 }, +{ SYS_DVBS2, PSK_8, FEC_9_10, 0x11 }, +}; + + +/* Retrieve current fec, modulation & pilot values */ +static int cx24120_get_fec(struct dvb_frontend *fe) +{ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct cx24120_state *state = fe->demodulator_priv; + int idx; + int ret; + int GettedFEC; + + dev_dbg(&state->i2c->dev, "%s()\n", __func__); + + ret = cx24120_readreg(state, CX24120_REG_FECMODE); + GettedFEC = ret & 0x3f; /* Lower 6 bits */ + + dev_dbg(&state->i2c->dev, "%s: Get FEC: %d\n", __func__, GettedFEC); + + for (idx = 0; idx < ARRAY_SIZE(modfec_lookup_table); idx++) { + if (modfec_lookup_table[idx].delsys != state->dcur.delsys) + continue; + if (modfec_lookup_table[idx].val != GettedFEC) + continue; + + break; /* found */ + } + + if (idx >= ARRAY_SIZE(modfec_lookup_table)) { + dev_dbg(&state->i2c->dev, "%s: Couldn't find fec!\n", + __func__); + return -EINVAL; + } + + /* save values back to cache */ + c->modulation = modfec_lookup_table[idx].mod; + c->fec_inner = modfec_lookup_table[idx].fec; + c->pilot = (ret & 0x80) ? PILOT_ON : PILOT_OFF; + + dev_dbg(&state->i2c->dev, + "%s: mod(%d), fec(%d), pilot(%d)\n", + __func__, + c->modulation, c->fec_inner, c->pilot); + + return 0; +} + + +/* Clock ratios lookup table + * + * Values obtained from much larger table in old driver + * which had numerous entries which would never match. + * + * There's probably some way of calculating these but I + * can't determine the pattern +*/ +static struct cx24120_clock_ratios_table { + fe_delivery_system_t delsys; + fe_pilot_t pilot; + fe_modulation_t mod; + fe_code_rate_t fec; + u32 m_rat; + u32 n_rat; + u32 rate; +} clock_ratios_table[] = { +/*delsys pilot mod fec m_rat n_rat rate */ +{ SYS_DVBS2, PILOT_OFF, QPSK, FEC_1_2, 273088, 254505, 274 }, +{ SYS_DVBS2, PILOT_OFF, QPSK, FEC_3_5, 17272, 13395, 330 }, +{ SYS_DVBS2, PILOT_OFF, QPSK, FEC_2_3, 24344, 16967, 367 }, +{ SYS_DVBS2, PILOT_OFF, QPSK, FEC_3_4, 410788, 254505, 413 }, +{ SYS_DVBS2, PILOT_OFF, QPSK, FEC_4_5, 438328, 254505, 440 }, +{ SYS_DVBS2, PILOT_OFF, QPSK, FEC_5_6, 30464, 16967, 459 }, +{ SYS_DVBS2, PILOT_OFF, QPSK, FEC_8_9, 487832, 254505, 490 }, +{ SYS_DVBS2, PILOT_OFF, QPSK, FEC_9_10, 493952, 254505, 496 }, +{ SYS_DVBS2, PILOT_OFF, PSK_8, FEC_3_5, 328168, 169905, 494 }, +{ SYS_DVBS2, PILOT_OFF, PSK_8, FEC_2_3, 24344, 11327, 550 }, +{ SYS_DVBS2, PILOT_OFF, PSK_8, FEC_3_4, 410788, 169905, 618 }, +{ SYS_DVBS2, PILOT_OFF, PSK_8, FEC_5_6, 30464, 11327, 688 }, +{ SYS_DVBS2, PILOT_OFF, PSK_8, FEC_8_9, 487832, 169905, 735 }, +{ SYS_DVBS2, PILOT_OFF, PSK_8, FEC_9_10, 493952, 169905, 744 }, +{ SYS_DVBS2, PILOT_ON, QPSK, FEC_1_2, 273088, 260709, 268 }, +{ SYS_DVBS2, PILOT_ON, QPSK, FEC_3_5, 328168, 260709, 322 }, +{ SYS_DVBS2, PILOT_ON, QPSK, FEC_2_3, 121720, 86903, 358 }, +{ SYS_DVBS2, PILOT_ON, QPSK, FEC_3_4, 410788, 260709, 403 }, +{ SYS_DVBS2, PILOT_ON, QPSK, FEC_4_5, 438328, 260709, 430 }, +{ SYS_DVBS2, PILOT_ON, QPSK, FEC_5_6, 152320, 86903, 448 }, +{ SYS_DVBS2, PILOT_ON, QPSK, FEC_8_9, 487832, 260709, 479 }, +{ SYS_DVBS2, PILOT_ON, QPSK, FEC_9_10, 493952, 260709, 485 }, +{ SYS_DVBS2, PILOT_ON, PSK_8, FEC_3_5, 328168, 173853, 483 }, +{ SYS_DVBS2, PILOT_ON, PSK_8, FEC_2_3, 121720, 57951, 537 }, +{ SYS_DVBS2, PILOT_ON, PSK_8, FEC_3_4, 410788, 173853, 604 }, +{ SYS_DVBS2, PILOT_ON, PSK_8, FEC_5_6, 152320, 57951, 672 }, +{ SYS_DVBS2, PILOT_ON, PSK_8, FEC_8_9, 487832, 173853, 718 }, +{ SYS_DVBS2, PILOT_ON, PSK_8, FEC_9_10, 493952, 173853, 727 }, +{ SYS_DVBS, PILOT_OFF, QPSK, FEC_1_2, 152592, 152592, 256 }, +{ SYS_DVBS, PILOT_OFF, QPSK, FEC_2_3, 305184, 228888, 341 }, +{ SYS_DVBS, PILOT_OFF, QPSK, FEC_3_4, 457776, 305184, 384 }, +{ SYS_DVBS, PILOT_OFF, QPSK, FEC_5_6, 762960, 457776, 427 }, +{ SYS_DVBS, PILOT_OFF, QPSK, FEC_7_8, 1068144, 610368, 448 }, +}; + + +/* Set clock ratio from lookup table */ +static void cx24120_set_clock_ratios(struct dvb_frontend *fe) +{ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct cx24120_state *state = fe->demodulator_priv; + struct cx24120_cmd cmd; + int ret, idx; + + /* Find fec, modulation, pilot */ + ret = cx24120_get_fec(fe); + if (ret != 0) + return; + + /* Find the clock ratios in the lookup table */ + for (idx = 0; idx < ARRAY_SIZE(clock_ratios_table); idx++) { + if (clock_ratios_table[idx].delsys != state->dcur.delsys) + continue; + if (clock_ratios_table[idx].mod != c->modulation) + continue; + if (clock_ratios_table[idx].fec != c->fec_inner) + continue; + if (clock_ratios_table[idx].pilot != c->pilot) + continue; + + break; /* found */ + } + + if (idx >= ARRAY_SIZE(clock_ratios_table)) { + info("Clock ratio not found - data reception in danger\n"); + return; + } + + + /* Read current values? */ + cmd.id = CMD_CLOCK_READ; + cmd.len = 1; + cmd.arg[0] = 0x00; + ret = cx24120_message_sendrcv(state, &cmd, 6); + if (ret != 0) + return; + /* in cmd[0]-[5] - result */ + + dev_dbg(&state->i2c->dev, + "%s: m=%d, n=%d; idx: %d m=%d, n=%d, rate=%d\n", + __func__, + cmd.arg[2] | (cmd.arg[1] << 8) | (cmd.arg[0] << 16), + cmd.arg[5] | (cmd.arg[4] << 8) | (cmd.arg[3] << 16), + idx, + clock_ratios_table[idx].m_rat, + clock_ratios_table[idx].n_rat, + clock_ratios_table[idx].rate); + + + + /* Set the clock */ + cmd.id = CMD_CLOCK_SET; + cmd.len = 10; + cmd.arg[0] = 0; + cmd.arg[1] = 0x10; + cmd.arg[2] = (clock_ratios_table[idx].m_rat >> 16) & 0xff; + cmd.arg[3] = (clock_ratios_table[idx].m_rat >> 8) & 0xff; + cmd.arg[4] = (clock_ratios_table[idx].m_rat >> 0) & 0xff; + cmd.arg[5] = (clock_ratios_table[idx].n_rat >> 16) & 0xff; + cmd.arg[6] = (clock_ratios_table[idx].n_rat >> 8) & 0xff; + cmd.arg[7] = (clock_ratios_table[idx].n_rat >> 0) & 0xff; + cmd.arg[8] = (clock_ratios_table[idx].rate >> 8) & 0xff; + cmd.arg[9] = (clock_ratios_table[idx].rate >> 0) & 0xff; + + cx24120_message_send(state, &cmd); + +} + + +/* Set inversion value */ +static int cx24120_set_inversion(struct cx24120_state *state, + fe_spectral_inversion_t inversion) +{ + dev_dbg(&state->i2c->dev, "%s(%d)\n", + __func__, inversion); + + switch (inversion) { + case INVERSION_OFF: + state->dnxt.inversion_val = 0x00; + break; + case INVERSION_ON: + state->dnxt.inversion_val = 0x04; + break; + case INVERSION_AUTO: + state->dnxt.inversion_val = 0x0c; + break; + default: + return -EINVAL; + } + + state->dnxt.inversion = inversion; + + return 0; +} + +/* FEC lookup table for tuning + * Some DVB-S2 val's have been found by trial + * and error. Sofar it seems to match up with + * the contents of the REG_FECMODE after tuning + * The rest will probably be the same but would + * need testing. + * Anything not in the table will run with + * FEC_AUTO and take a while longer to tune in + * ( c.500ms instead of 30ms ) + */ +static struct cx24120_modfec_table { + fe_delivery_system_t delsys; + fe_modulation_t mod; + fe_code_rate_t fec; + u8 val; +} modfec_table[] = { +/*delsys mod fec val */ +{ SYS_DVBS, QPSK, FEC_1_2, 0x2e }, +{ SYS_DVBS, QPSK, FEC_2_3, 0x2f }, +{ SYS_DVBS, QPSK, FEC_3_4, 0x30 }, +{ SYS_DVBS, QPSK, FEC_5_6, 0x31 }, +{ SYS_DVBS, QPSK, FEC_6_7, 0x32 }, +{ SYS_DVBS, QPSK, FEC_7_8, 0x33 }, + +{ SYS_DVBS2, QPSK, FEC_3_4, 0x07 }, + +{ SYS_DVBS2, PSK_8, FEC_2_3, 0x0d }, +{ SYS_DVBS2, PSK_8, FEC_3_4, 0x0e }, +}; + +/* Set fec_val & fec_mask values from delsys, modulation & fec */ +static int cx24120_set_fec(struct cx24120_state *state, + fe_modulation_t mod, fe_code_rate_t fec) +{ + int idx; + + dev_dbg(&state->i2c->dev, + "%s(0x%02x,0x%02x)\n", __func__, mod, fec); + + state->dnxt.fec = fec; + + /* Lookup fec_val from modfec table */ + for (idx = 0; idx < ARRAY_SIZE(modfec_table); idx++) { + if (modfec_table[idx].delsys != state->dnxt.delsys) + continue; + if (modfec_table[idx].mod != mod) + continue; + if (modfec_table[idx].fec != fec) + continue; + + /* found */ + state->dnxt.fec_mask = 0x00; + state->dnxt.fec_val = modfec_table[idx].val; + return 0; + } + + + if (state->dnxt.delsys == SYS_DVBS2) { + /* DVBS2 auto is 0x00/0x00 */ + state->dnxt.fec_mask = 0x00; + state->dnxt.fec_val = 0x00; + } else { + /* Set DVB-S to auto */ + state->dnxt.fec_val = 0x2e; + state->dnxt.fec_mask = 0xac; + } + + return 0; +} + + +/* Set pilot */ +static int cx24120_set_pilot(struct cx24120_state *state, + fe_pilot_t pilot) { + + dev_dbg(&state->i2c->dev, + "%s(%d)\n", __func__, pilot); + + /* Pilot only valid in DVBS2 */ + if (state->dnxt.delsys != SYS_DVBS2) { + state->dnxt.pilot_val = CX24120_PILOT_OFF; + return 0; + } + + + switch (pilot) { + case PILOT_OFF: + state->dnxt.pilot_val = CX24120_PILOT_OFF; + break; + case PILOT_ON: + state->dnxt.pilot_val = CX24120_PILOT_ON; + break; + case PILOT_AUTO: + default: + state->dnxt.pilot_val = CX24120_PILOT_AUTO; + } + + return 0; +} + +/* Set symbol rate */ +static int cx24120_set_symbolrate(struct cx24120_state *state, u32 rate) +{ + dev_dbg(&state->i2c->dev, "%s(%d)\n", + __func__, rate); + + state->dnxt.symbol_rate = rate; + + /* Check symbol rate */ + if (rate > 31000000) { + state->dnxt.clkdiv = (-(rate < 31000001) & 3) + 2; + state->dnxt.ratediv = (-(rate < 31000001) & 6) + 4; + } else { + state->dnxt.clkdiv = 3; + state->dnxt.ratediv = 6; + } + + return 0; +} + + +/* Overwrite the current tuning params, we are about to tune */ +static void cx24120_clone_params(struct dvb_frontend *fe) +{ + struct cx24120_state *state = fe->demodulator_priv; + + state->dcur = state->dnxt; +} + + +/* Table of time to tune for different symrates */ +static struct cx24120_symrate_delay { + fe_delivery_system_t delsys; + u32 symrate; /* Check for >= this symrate */ + u32 delay; /* Timeout in ms */ +} symrates_delay_table[] = { +{ SYS_DVBS, 10000000, 400 }, +{ SYS_DVBS, 8000000, 2000 }, +{ SYS_DVBS, 6000000, 5000 }, +{ SYS_DVBS, 3000000, 10000 }, +{ SYS_DVBS, 0, 15000 }, +{ SYS_DVBS2, 10000000, 600 }, /* DVBS2 needs a little longer */ +{ SYS_DVBS2, 8000000, 2000 }, /* (so these might need bumping too) */ +{ SYS_DVBS2, 6000000, 5000 }, +{ SYS_DVBS2, 3000000, 10000 }, +{ SYS_DVBS2, 0, 15000 }, +}; + + +static int cx24120_set_frontend(struct dvb_frontend *fe) +{ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct cx24120_state *state = fe->demodulator_priv; + struct cx24120_cmd cmd; + int ret; + int delay_cnt, sd_idx = 0; + fe_status_t status; + + switch (c->delivery_system) { + case SYS_DVBS2: + dev_dbg(&state->i2c->dev, "%s() DVB-S2\n", + __func__); + break; + case SYS_DVBS: + dev_dbg(&state->i2c->dev, "%s() DVB-S\n", + __func__); + break; + default: + dev_dbg(&state->i2c->dev, + "%s() Delivery system(%d) not supported\n", + __func__, c->delivery_system); + ret = -EINVAL; + break; + } + + + state->dnxt.delsys = c->delivery_system; + state->dnxt.modulation = c->modulation; + state->dnxt.frequency = c->frequency; + state->dnxt.pilot = c->pilot; + + ret = cx24120_set_inversion(state, c->inversion); + if (ret != 0) + return ret; + + ret = cx24120_set_fec(state, c->modulation, c->fec_inner); + if (ret != 0) + return ret; + + ret = cx24120_set_pilot(state, c->pilot); + if (ret != 0) + return ret; + + ret = cx24120_set_symbolrate(state, c->symbol_rate); + if (ret != 0) + return ret; + + + /* discard the 'current' tuning parameters and prepare to tune */ + cx24120_clone_params(fe); + + dev_dbg(&state->i2c->dev, + "%s: delsys = %d\n", __func__, state->dcur.delsys); + dev_dbg(&state->i2c->dev, + "%s: modulation = %d\n", __func__, state->dcur.modulation); + dev_dbg(&state->i2c->dev, + "%s: frequency = %d\n", __func__, state->dcur.frequency); + dev_dbg(&state->i2c->dev, + "%s: pilot = %d (val = 0x%02x)\n", __func__, + state->dcur.pilot, state->dcur.pilot_val); + dev_dbg(&state->i2c->dev, + "%s: symbol_rate = %d (clkdiv/ratediv = 0x%02x/0x%02x)\n", + __func__, state->dcur.symbol_rate, + state->dcur.clkdiv, state->dcur.ratediv); + dev_dbg(&state->i2c->dev, + "%s: FEC = %d (mask/val = 0x%02x/0x%02x)\n", __func__, + state->dcur.fec, state->dcur.fec_mask, state->dcur.fec_val); + dev_dbg(&state->i2c->dev, + "%s: Inversion = %d (val = 0x%02x)\n", __func__, + state->dcur.inversion, state->dcur.inversion_val); + + + + /* Tune in */ + cmd.id = CMD_TUNEREQUEST; + cmd.len = 15; + cmd.arg[0] = 0; + cmd.arg[1] = (state->dcur.frequency & 0xff0000) >> 16; + cmd.arg[2] = (state->dcur.frequency & 0x00ff00) >> 8; + cmd.arg[3] = (state->dcur.frequency & 0x0000ff); + cmd.arg[4] = ((state->dcur.symbol_rate/1000) & 0xff00) >> 8; + cmd.arg[5] = ((state->dcur.symbol_rate/1000) & 0x00ff); + cmd.arg[6] = state->dcur.inversion; + cmd.arg[7] = state->dcur.fec_val | state->dcur.pilot_val; + cmd.arg[8] = CX24120_SEARCH_RANGE_KHZ >> 8; + cmd.arg[9] = CX24120_SEARCH_RANGE_KHZ & 0xff; + cmd.arg[10] = 0; /* maybe rolloff? */ + cmd.arg[11] = state->dcur.fec_mask; + cmd.arg[12] = state->dcur.ratediv; + cmd.arg[13] = state->dcur.clkdiv; + cmd.arg[14] = 0; + + + /* Send tune command */ + ret = cx24120_message_send(state, &cmd); + if (ret != 0) + return ret; + + /* Write symbol rate values */ + ret = cx24120_writereg(state, CX24120_REG_CLKDIV, state->dcur.clkdiv); + ret = cx24120_readreg(state, CX24120_REG_RATEDIV); + ret &= 0xfffffff0; + ret |= state->dcur.ratediv; + ret = cx24120_writereg(state, CX24120_REG_RATEDIV, ret); + + /* Default time to tune */ + delay_cnt = 500; + + /* Establish time to tune from symrates_delay_table */ + for (sd_idx = 0; sd_idx < ARRAY_SIZE(symrates_delay_table); sd_idx++) { + if (state->dcur.delsys != symrates_delay_table[sd_idx].delsys) + continue; + if (c->symbol_rate < symrates_delay_table[sd_idx].symrate) + continue; + + /* found */ + delay_cnt = symrates_delay_table[sd_idx].delay; + dev_dbg(&state->i2c->dev, "%s: Found symrate delay = %d\n", + __func__, delay_cnt); + break; + } + + /* Wait for tuning */ + while (delay_cnt >= 0) { + cx24120_read_status(fe, &status); + if (status & FE_HAS_LOCK) + goto tuned; + msleep(20); + delay_cnt -= 20; + } + + + /* Fail to tune */ + dev_dbg(&state->i2c->dev, "%s: Tuning failed\n", + __func__); + + return -EINVAL; + + +tuned: + dev_dbg(&state->i2c->dev, "%s: Tuning successful\n", + __func__); + + /* Set clock ratios */ + cx24120_set_clock_ratios(fe); + + /* Old driver would do a msleep(200) here */ + + /* Renable mpeg output */ + if (!state->mpeg_enabled) + cx24120_msg_mpeg_output_global_config(state, 1); + + return 0; +} + + +/* Calculate vco from config */ +static u64 cx24120_calculate_vco(struct cx24120_state *state) +{ + u32 vco; + u64 inv_vco, res, xxyyzz; + u32 xtal_khz = state->config->xtal_khz; + + xxyyzz = 0x400000000ULL; + vco = xtal_khz * 10 * 4; + inv_vco = xxyyzz / vco; + res = xxyyzz % vco; + + if (inv_vco > xtal_khz * 10 * 2) + ++inv_vco; + + dev_dbg(&state->i2c->dev, + "%s: xtal=%d, vco=%d, inv_vco=%lld, res=%lld\n", + __func__, xtal_khz, vco, inv_vco, res); + + return inv_vco; +} + + +int cx24120_init(struct dvb_frontend *fe) +{ + const struct firmware *fw; + struct cx24120_state *state = fe->demodulator_priv; + struct cx24120_cmd cmd; + u8 ret, ret_EA, reg1; + u64 inv_vco; + int reset_result; + + int i; + unsigned char vers[4]; + + if (state->cold_init) + return 0; + + /* ???? */ + ret = cx24120_writereg(state, 0xea, 0x00); + ret = cx24120_test_rom(state); + ret = cx24120_readreg(state, 0xfb) & 0xfe; + ret = cx24120_writereg(state, 0xfb, ret); + ret = cx24120_readreg(state, 0xfc) & 0xfe; + ret = cx24120_writereg(state, 0xfc, ret); + ret = cx24120_writereg(state, 0xc3, 0x04); + ret = cx24120_writereg(state, 0xc4, 0x04); + ret = cx24120_writereg(state, 0xce, 0x00); + ret = cx24120_writereg(state, 0xcf, 0x00); + ret_EA = cx24120_readreg(state, 0xea) & 0xfe; + ret = cx24120_writereg(state, 0xea, ret_EA); + ret = cx24120_writereg(state, 0xeb, 0x0c); + ret = cx24120_writereg(state, 0xec, 0x06); + ret = cx24120_writereg(state, 0xed, 0x05); + ret = cx24120_writereg(state, 0xee, 0x03); + ret = cx24120_writereg(state, 0xef, 0x05); + ret = cx24120_writereg(state, 0xf3, 0x03); + ret = cx24120_writereg(state, 0xf4, 0x44); + + for (reg1 = 0xf0; reg1 < 0xf3; reg1++) { + cx24120_writereg(state, reg1, 0x04); + cx24120_writereg(state, reg1 - 10, 0x02); + } + + ret = cx24120_writereg(state, 0xea, (ret_EA | 0x01)); + for (reg1 = 0xc5; reg1 < 0xcb; reg1 += 2) { + ret = cx24120_writereg(state, reg1, 0x00); + ret = cx24120_writereg(state, reg1 + 1, 0x00); + } + + ret = cx24120_writereg(state, 0xe4, 0x03); + ret = cx24120_writereg(state, 0xeb, 0x0a); + + dev_dbg(&state->i2c->dev, + "%s: Requesting firmware (%s) to download...\n", + __func__, CX24120_FIRMWARE); + + ret = state->config->request_firmware(fe, &fw, CX24120_FIRMWARE); + if (ret) { + err("Could not load firmware (%s): %d\n", + CX24120_FIRMWARE, ret); + return ret; + } + + dev_dbg(&state->i2c->dev, + "%s: Firmware found, size %d bytes (%02x %02x .. %02x %02x)\n", + __func__, + (int)fw->size, /* firmware_size in bytes */ + fw->data[0], /* fw 1st byte */ + fw->data[1], /* fw 2d byte */ + fw->data[fw->size - 2], /* fw before last byte */ + fw->data[fw->size - 1]); /* fw last byte */ + + ret = cx24120_test_rom(state); + ret = cx24120_readreg(state, 0xfb) & 0xfe; + ret = cx24120_writereg(state, 0xfb, ret); + ret = cx24120_writereg(state, 0xe0, 0x76); + ret = cx24120_writereg(state, 0xf7, 0x81); + ret = cx24120_writereg(state, 0xf8, 0x00); + ret = cx24120_writereg(state, 0xf9, 0x00); + ret = cx24120_writeregN(state, 0xfa, fw->data, (fw->size - 1), 0x00); + ret = cx24120_writereg(state, 0xf7, 0xc0); + ret = cx24120_writereg(state, 0xe0, 0x00); + ret = (fw->size - 2) & 0x00ff; + ret = cx24120_writereg(state, 0xf8, ret); + ret = ((fw->size - 2) >> 8) & 0x00ff; + ret = cx24120_writereg(state, 0xf9, ret); + ret = cx24120_writereg(state, 0xf7, 0x00); + ret = cx24120_writereg(state, 0xdc, 0x00); + ret = cx24120_writereg(state, 0xdc, 0x07); + msleep(500); + + /* Check final byte matches final byte of firmware */ + ret = cx24120_readreg(state, 0xe1); + if (ret == fw->data[fw->size - 1]) { + dev_dbg(&state->i2c->dev, + "%s: Firmware uploaded successfully\n", + __func__); + reset_result = 0; + } else { + err("Firmware upload failed. Last byte returned=0x%x\n", ret); + reset_result = -EREMOTEIO; + } + ret = cx24120_writereg(state, 0xdc, 0x00); + release_firmware(fw); + if (reset_result != 0) + return reset_result; + + + /* Start tuner */ + cmd.id = CMD_START_TUNER; + cmd.len = 3; + cmd.arg[0] = 0x00; + cmd.arg[1] = 0x00; + cmd.arg[2] = 0x00; + + if (cx24120_message_send(state, &cmd) != 0) { + err("Error tuner start! :(\n"); + return -EREMOTEIO; + } + + /* Set VCO */ + inv_vco = cx24120_calculate_vco(state); + + cmd.id = CMD_VCO_SET; + cmd.len = 12; + cmd.arg[0] = 0x06; + cmd.arg[1] = 0x2b; + cmd.arg[2] = 0xd8; + cmd.arg[3] = (inv_vco >> 8) & 0xff; + cmd.arg[4] = (inv_vco) & 0xff; + cmd.arg[5] = 0x03; + cmd.arg[6] = 0x9d; + cmd.arg[7] = 0xfc; + cmd.arg[8] = 0x06; + cmd.arg[9] = 0x03; + cmd.arg[10] = 0x27; + cmd.arg[11] = 0x7f; + + if (cx24120_message_send(state, &cmd)) { + err("Error set VCO! :(\n"); + return -EREMOTEIO; + } + + + /* set bandwidth */ + cmd.id = CMD_BANDWIDTH; + cmd.len = 12; + cmd.arg[0] = 0x00; + cmd.arg[1] = 0x00; + cmd.arg[2] = 0x00; + cmd.arg[3] = 0x00; + cmd.arg[4] = 0x05; + cmd.arg[5] = 0x02; + cmd.arg[6] = 0x02; + cmd.arg[7] = 0x00; + cmd.arg[8] = 0x05; + cmd.arg[9] = 0x02; + cmd.arg[10] = 0x02; + cmd.arg[11] = 0x00; + + if (cx24120_message_send(state, &cmd)) { + err("Error set bandwidth!\n"); + return -EREMOTEIO; + } + + ret = cx24120_readreg(state, 0xba); + if (ret > 3) { + dev_dbg(&state->i2c->dev, "%s: Reset-readreg 0xba: %x\n", + __func__, ret); + err("Error initialising tuner!\n"); + return -EREMOTEIO; + } + + dev_dbg(&state->i2c->dev, "%s: Tuner initialised correctly.\n", + __func__); + + + /* Initialise mpeg outputs */ + ret = cx24120_writereg(state, 0xeb, 0x0a); + if (cx24120_msg_mpeg_output_global_config(state, 0) || + cx24120_msg_mpeg_output_config(state, 0) || + cx24120_msg_mpeg_output_config(state, 1) || + cx24120_msg_mpeg_output_config(state, 2)) { + err("Error initialising mpeg output. :(\n"); + return -EREMOTEIO; + } + + + /* ???? */ + cmd.id = CMD_TUNER_INIT; + cmd.len = 3; + cmd.arg[0] = 0x00; + cmd.arg[1] = 0x10; + cmd.arg[2] = 0x10; + if (cx24120_message_send(state, &cmd)) { + err("Error sending final init message. :(\n"); + return -EREMOTEIO; + } + + + /* Firmware CMD 35: Get firmware version */ + cmd.id = CMD_FWVERSION; + cmd.len = 1; + for (i = 0; i < 4; i++) { + cmd.arg[0] = i; + ret = cx24120_message_send(state, &cmd); + if (ret != 0) + return ret; + vers[i] = cx24120_readreg(state, CX24120_REG_MAILBOX); + } + info("FW version %i.%i.%i.%i\n", vers[0], vers[1], vers[2], vers[3]); + + + state->cold_init = 1; + return 0; +} + + +static int cx24120_tune(struct dvb_frontend *fe, bool re_tune, + unsigned int mode_flags, unsigned int *delay, fe_status_t *status) +{ + struct cx24120_state *state = fe->demodulator_priv; + int ret; + + dev_dbg(&state->i2c->dev, "%s(%d)\n", __func__, re_tune); + + /* TODO: Do we need to set delay? */ + + if (re_tune) { + ret = cx24120_set_frontend(fe); + if (ret) + return ret; + } + + return cx24120_read_status(fe, status); +} + + + +static int cx24120_get_algo(struct dvb_frontend *fe) +{ + return DVBFE_ALGO_HW; +} + + +static int cx24120_sleep(struct dvb_frontend *fe) +{ + return 0; +} + + +/*static int cx24120_wakeup(struct dvb_frontend *fe) + * { + * return 0; + * } +*/ + + +static int cx24120_get_frontend(struct dvb_frontend *fe) +{ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct cx24120_state *state = fe->demodulator_priv; + u8 freq1, freq2, freq3; + + dev_dbg(&state->i2c->dev, "%s()", __func__); + + /* don't return empty data if we're not tuned in */ + if (state->mpeg_enabled) + return 0; + + /* Get frequency */ + freq1 = cx24120_readreg(state, CX24120_REG_FREQ1); + freq2 = cx24120_readreg(state, CX24120_REG_FREQ2); + freq3 = cx24120_readreg(state, CX24120_REG_FREQ3); + c->frequency = (freq3 << 16) | (freq2 << 8) | freq1; + dev_dbg(&state->i2c->dev, "%s frequency = %d\n", __func__, + c->frequency); + + /* Get modulation, fec, pilot */ + cx24120_get_fec(fe); + + return 0; +} + + +static void cx24120_release(struct dvb_frontend *fe) +{ + struct cx24120_state *state = fe->demodulator_priv; + + dev_dbg(&state->i2c->dev, "%s: Clear state structure\n", __func__); + kfree(state); +} + + +static int cx24120_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + struct cx24120_state *state = fe->demodulator_priv; + + *ucblocks = (cx24120_readreg(state, CX24120_REG_UCB_H) << 8) | + cx24120_readreg(state, CX24120_REG_UCB_L); + + dev_dbg(&state->i2c->dev, "%s: Blocks = %d\n", + __func__, *ucblocks); + return 0; +} + + +static struct dvb_frontend_ops cx24120_ops = { + .delsys = { SYS_DVBS, SYS_DVBS2 }, + .info = { + .name = "Conexant CX24120/CX24118", + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_stepsize = 1011, /* kHz for QPSK frontends */ + .frequency_tolerance = 5000, + .symbol_rate_min = 1000000, + .symbol_rate_max = 45000000, + .caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | + FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_2G_MODULATION | + FE_CAN_QPSK | FE_CAN_RECOVER + }, + .release = cx24120_release, + + .init = cx24120_init, + .sleep = cx24120_sleep, + + .tune = cx24120_tune, + .get_frontend_algo = cx24120_get_algo, + .set_frontend = cx24120_set_frontend, + + .get_frontend = cx24120_get_frontend, + .read_status = cx24120_read_status, + .read_ber = cx24120_read_ber, + .read_signal_strength = cx24120_read_signal_strength, + .read_snr = cx24120_read_snr, + .read_ucblocks = cx24120_read_ucblocks, + + .diseqc_send_master_cmd = cx24120_send_diseqc_msg, + + .diseqc_send_burst = cx24120_diseqc_send_burst, + .set_tone = cx24120_set_tone, + .set_voltage = cx24120_set_voltage, +}; + +MODULE_DESCRIPTION("DVB Frontend module for Conexant CX24120/CX24118 hardware"); +MODULE_AUTHOR("Jemma Denson"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb-frontends/cx24120.h b/drivers/media/dvb-frontends/cx24120.h new file mode 100644 index 000000000000..9a394d4c70e4 --- /dev/null +++ b/drivers/media/dvb-frontends/cx24120.h @@ -0,0 +1,56 @@ +/* + * Conexant CX24120/CX24118 - DVB-S/S2 demod/tuner driver + * + * Copyright (C) 2008 Patrick Boettcher + * Copyright (C) 2009 Sergey Tyurin + * Updated 2012 by Jannis Achstetter + * Copyright (C) 2015 Jemma Denson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef CX24120_H +#define CX24120_H + +#include +#include +#include + +struct cx24120_initial_mpeg_config { + u8 x1; + u8 x2; + u8 x3; +}; + +struct cx24120_config { + u8 i2c_addr; + u32 xtal_khz; + struct cx24120_initial_mpeg_config initial_mpeg_config; + + int (*request_firmware)(struct dvb_frontend *fe, + const struct firmware **fw, char *name); +}; + +#if IS_REACHABLE(CONFIG_DVB_CX24120) +extern struct dvb_frontend *cx24120_attach( + const struct cx24120_config *config, + struct i2c_adapter *i2c); +#else +static inline struct dvb_frontend *cx24120_attach( + const struct cx24120_config *config, + struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif + +#endif /* CX24120_H */ -- cgit v1.2.3-59-g8ed1b From c5fb0f5f545cdf90c451ea7c9a6fb98ae4c64e49 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Fri, 17 Apr 2015 06:04:53 -0300 Subject: [media] cx24120: minor checkpatch fixes This patch fixes printk-related checkpatch warnings. All printks have been converted to pr_warn or pr_info or pr_err. Signed-off-by: Patrick.Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 7 ++----- drivers/media/dvb-frontends/cx24120.h | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index 344d8b8e37e5..ff7f21496186 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -108,11 +108,8 @@ enum command_message_id { #define CX24120_STATUS_MASK (0x0f) #define CX24120_SIGNAL_MASK (0xc0) -#define info(args...) do { printk(KERN_INFO "cx24120: "); \ - printk(args); } while (0) -#define err(args...) do { printk(KERN_ERR "cx24120: ### ERROR: "); \ - printk(args); } while (0) - +#define info(args...) pr_info("cx24120: " args) +#define err(args...) pr_err("cx24120: ### ERROR: " args) /* The Demod/Tuner can't easily provide these, we cache them */ struct cx24120_tuning { diff --git a/drivers/media/dvb-frontends/cx24120.h b/drivers/media/dvb-frontends/cx24120.h index 9a394d4c70e4..076d2ddb5dde 100644 --- a/drivers/media/dvb-frontends/cx24120.h +++ b/drivers/media/dvb-frontends/cx24120.h @@ -48,7 +48,7 @@ static inline struct dvb_frontend *cx24120_attach( const struct cx24120_config *config, struct i2c_adapter *i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + pr_warn("%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif -- cgit v1.2.3-59-g8ed1b From f7a77ebf08536da5cafd4494855001be74176efb Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Tue, 28 Apr 2015 02:47:42 -0300 Subject: [media] cx24120: i2c-max-write-size is now configurable Some i2c-hosts are quite limited regarding maximum i2c-burst-write-sizes. This patch makes the previously hardcoded field configurable by users of the driver. Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/b2c2/flexcop-fe-tuner.c | 1 + drivers/media/dvb-frontends/cx24120.c | 38 ++++++++++++++++------------ drivers/media/dvb-frontends/cx24120.h | 3 +++ 3 files changed, 26 insertions(+), 16 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/b2c2/flexcop-fe-tuner.c b/drivers/media/common/b2c2/flexcop-fe-tuner.c index 66f6910a1810..9305266d0ac0 100644 --- a/drivers/media/common/b2c2/flexcop-fe-tuner.c +++ b/drivers/media/common/b2c2/flexcop-fe-tuner.c @@ -630,6 +630,7 @@ static const struct cx24120_config skystar2_rev3_3_cx24120_config = { .xtal_khz = 10111, .initial_mpeg_config = { 0xa1, 0x76, 0x07 }, .request_firmware = flexcop_fe_request_firmware, + .i2c_wr_max = 4, }; static int skystarS2_rev33_attach(struct flexcop_device *fc, diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index ff7f21496186..2ed3fbc81e29 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -209,46 +209,53 @@ static int cx24120_writereg(struct cx24120_state *state, u8 reg, u8 data) } -/* Write multiple registers */ +/* Write multiple registers in chunks of i2c_wr_max-sized buffers */ static int cx24120_writeregN(struct cx24120_state *state, u8 reg, const u8 *values, u16 len, u8 incr) { int ret; - u8 buf[5]; /* maximum 4 data bytes at once - flexcop limitation - (very limited i2c-interface this one) */ + u16 max = state->config->i2c_wr_max > 0 ? + state->config->i2c_wr_max : + len; struct i2c_msg msg = { .addr = state->config->i2c_addr, .flags = 0, - .buf = buf, - .len = len }; + }; + + msg.buf = kmalloc(max + 1, GFP_KERNEL); + if (msg.buf == NULL) + return -ENOMEM; while (len) { - buf[0] = reg; - msg.len = len > 4 ? 4 : len; - memcpy(&buf[1], values, msg.len); + msg.buf[0] = reg; + msg.len = len > max ? max : len; + memcpy(&msg.buf[1], values, msg.len); - len -= msg.len; /* data length revers counter */ - values += msg.len; /* incr data pointer */ + len -= msg.len; /* data length revers counter */ + values += msg.len; /* incr data pointer */ if (incr) reg += msg.len; - msg.len++; /* don't forget the addr byte */ + msg.len++; /* don't forget the addr byte */ ret = i2c_transfer(state->i2c, &msg, 1); if (ret != 1) { err("i2c_write error(err == %i, 0x%02x)\n", ret, reg); - return ret; + goto out; } dev_dbg(&state->i2c->dev, "%s: reg=0x%02x; data=0x%02x,0x%02x,0x%02x,0x%02x\n", __func__, reg, - buf[1], buf[2], buf[3], buf[4]); - + msg.buf[1], msg.buf[2], msg.buf[3], msg.buf[4]); } - return 0; + ret = 0; + +out: + kfree(msg.buf); + return ret; } @@ -1434,7 +1441,6 @@ int cx24120_init(struct dvb_frontend *fe) } info("FW version %i.%i.%i.%i\n", vers[0], vers[1], vers[2], vers[3]); - state->cold_init = 1; return 0; } diff --git a/drivers/media/dvb-frontends/cx24120.h b/drivers/media/dvb-frontends/cx24120.h index 076d2ddb5dde..e5748aaa8418 100644 --- a/drivers/media/dvb-frontends/cx24120.h +++ b/drivers/media/dvb-frontends/cx24120.h @@ -37,6 +37,9 @@ struct cx24120_config { int (*request_firmware)(struct dvb_frontend *fe, const struct firmware **fw, char *name); + + /* max bytes I2C provider can write at once */ + u16 i2c_wr_max; }; #if IS_REACHABLE(CONFIG_DVB_CX24120) -- cgit v1.2.3-59-g8ed1b From 2e89a5e085ca301506fb28793dd16f9f147ccc06 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Tue, 28 Apr 2015 13:18:05 -0300 Subject: [media] cx24120: fix codingstyle issue first round Mauro pointed out some coding style issues in his review. This patch fixes them. Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 287 ++++++++++++++++------------------ 1 file changed, 135 insertions(+), 152 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index 2ed3fbc81e29..e09cab62b2c6 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -36,34 +36,34 @@ #define CX24120_FIRMWARE "dvb-fe-cx24120-1.20.58.2.fw" /* cx24120 i2c registers */ -#define CX24120_REG_CMD_START (0x00) /* write cmd_id */ -#define CX24120_REG_CMD_ARGS (0x01) /* write command arguments */ -#define CX24120_REG_CMD_END (0x1f) /* write 0x01 for end */ +#define CX24120_REG_CMD_START 0x00 /* write cmd_id */ +#define CX24120_REG_CMD_ARGS 0x01 /* write command arguments */ +#define CX24120_REG_CMD_END 0x1f /* write 0x01 for end */ -#define CX24120_REG_MAILBOX (0x33) -#define CX24120_REG_FREQ3 (0x34) /* frequency */ -#define CX24120_REG_FREQ2 (0x35) -#define CX24120_REG_FREQ1 (0x36) +#define CX24120_REG_MAILBOX 0x33 +#define CX24120_REG_FREQ3 0x34 /* frequency */ +#define CX24120_REG_FREQ2 0x35 +#define CX24120_REG_FREQ1 0x36 -#define CX24120_REG_FECMODE (0x39) /* FEC status */ -#define CX24120_REG_STATUS (0x3a) /* Tuner status */ -#define CX24120_REG_SIGSTR_H (0x3a) /* Signal strength high */ -#define CX24120_REG_SIGSTR_L (0x3b) /* Signal strength low byte */ -#define CX24120_REG_QUALITY_H (0x40) /* SNR high byte */ -#define CX24120_REG_QUALITY_L (0x41) /* SNR low byte */ +#define CX24120_REG_FECMODE 0x39 /* FEC status */ +#define CX24120_REG_STATUS 0x3a /* Tuner status */ +#define CX24120_REG_SIGSTR_H 0x3a /* Signal strength high */ +#define CX24120_REG_SIGSTR_L 0x3b /* Signal strength low byte */ +#define CX24120_REG_QUALITY_H 0x40 /* SNR high byte */ +#define CX24120_REG_QUALITY_L 0x41 /* SNR low byte */ -#define CX24120_REG_BER_HH (0x47) /* BER high byte of high word */ -#define CX24120_REG_BER_HL (0x48) /* BER low byte of high word */ -#define CX24120_REG_BER_LH (0x49) /* BER high byte of low word */ -#define CX24120_REG_BER_LL (0x4a) /* BER low byte of low word */ +#define CX24120_REG_BER_HH 0x47 /* BER high byte of high word */ +#define CX24120_REG_BER_HL 0x48 /* BER low byte of high word */ +#define CX24120_REG_BER_LH 0x49 /* BER high byte of low word */ +#define CX24120_REG_BER_LL 0x4a /* BER low byte of low word */ -#define CX24120_REG_UCB_H (0x50) /* UCB high byte */ -#define CX24120_REG_UCB_L (0x51) /* UCB low byte */ +#define CX24120_REG_UCB_H 0x50 /* UCB high byte */ +#define CX24120_REG_UCB_L 0x51 /* UCB low byte */ -#define CX24120_REG_CLKDIV (0xe6) -#define CX24120_REG_RATEDIV (0xf0) +#define CX24120_REG_CLKDIV 0xe6 +#define CX24120_REG_RATEDIV 0xf0 -#define CX24120_REG_REVISION (0xff) /* Chip revision (ro) */ +#define CX24120_REG_REVISION 0xff /* Chip revision (ro) */ /* Command messages */ @@ -94,19 +94,19 @@ enum command_message_id { #define CX24120_MAX_CMD_LEN 30 /* pilot mask */ -#define CX24120_PILOT_OFF (0x00) -#define CX24120_PILOT_ON (0x40) -#define CX24120_PILOT_AUTO (0x80) +#define CX24120_PILOT_OFF 0x00 +#define CX24120_PILOT_ON 0x40 +#define CX24120_PILOT_AUTO 0x80 /* signal status */ -#define CX24120_HAS_SIGNAL (0x01) -#define CX24120_HAS_CARRIER (0x02) -#define CX24120_HAS_VITERBI (0x04) -#define CX24120_HAS_LOCK (0x08) -#define CX24120_HAS_UNK1 (0x10) -#define CX24120_HAS_UNK2 (0x20) -#define CX24120_STATUS_MASK (0x0f) -#define CX24120_SIGNAL_MASK (0xc0) +#define CX24120_HAS_SIGNAL 0x01 +#define CX24120_HAS_CARRIER 0x02 +#define CX24120_HAS_VITERBI 0x04 +#define CX24120_HAS_LOCK 0x08 +#define CX24120_HAS_UNK1 0x10 +#define CX24120_HAS_UNK2 0x20 +#define CX24120_STATUS_MASK 0x0f +#define CX24120_SIGNAL_MASK 0xc0 #define info(args...) pr_info("cx24120: " args) #define err(args...) pr_err("cx24120: ### ERROR: " args) @@ -164,16 +164,18 @@ static int cx24120_readreg(struct cx24120_state *state, u8 reg) { .addr = state->config->i2c_addr, .flags = 0, .len = 1, - .buf = ® }, - - { .addr = state->config->i2c_addr, + .buf = ® + }, { + .addr = state->config->i2c_addr, .flags = I2C_M_RD, .len = 1, - .buf = &buf } + .buf = &buf + } }; + ret = i2c_transfer(state->i2c, msg, 2); if (ret != 2) { - err("Read error: reg=0x%02x, ret=0x%02x)\n", reg, ret); + err("Read error: reg=0x%02x, ret=%i)\n", reg, ret); return ret; } @@ -192,7 +194,8 @@ static int cx24120_writereg(struct cx24120_state *state, u8 reg, u8 data) .addr = state->config->i2c_addr, .flags = 0, .buf = buf, - .len = 2 }; + .len = 2 + }; int ret; ret = i2c_transfer(state->i2c, &msg, 1); @@ -246,9 +249,8 @@ static int cx24120_writeregN(struct cx24120_state *state, } dev_dbg(&state->i2c->dev, - "%s: reg=0x%02x; data=0x%02x,0x%02x,0x%02x,0x%02x\n", - __func__, reg, - msg.buf[1], msg.buf[2], msg.buf[3], msg.buf[4]); + "%s: reg=0x%02x; data=%*ph\n", + __func__, reg, msg.len, msg.buf+1); } ret = 0; @@ -268,8 +270,7 @@ struct dvb_frontend *cx24120_attach(const struct cx24120_config *config, int demod_rev; info("Conexant cx24120/cx24118 - DVBS/S2 Satellite demod/tuner\n"); - state = kzalloc(sizeof(struct cx24120_state), - GFP_KERNEL); + state = kzalloc(sizeof(struct cx24120_state), GFP_KERNEL); if (state == NULL) { err("Unable to allocate memory for cx24120_state\n"); goto error; @@ -297,7 +298,7 @@ struct dvb_frontend *cx24120_attach(const struct cx24120_config *config, /* create dvb_frontend */ state->cold_init = 0; memcpy(&state->frontend.ops, &cx24120_ops, - sizeof(struct dvb_frontend_ops)); + sizeof(struct dvb_frontend_ops)); state->frontend.demodulator_priv = state; info("Conexant cx24120/cx24118 attached.\n"); @@ -677,30 +678,30 @@ static struct cx24120_modfec { fe_code_rate_t fec; u8 val; } modfec_lookup_table[] = { -/*delsys mod fec val */ -{ SYS_DVBS, QPSK, FEC_1_2, 0x01 }, -{ SYS_DVBS, QPSK, FEC_2_3, 0x02 }, -{ SYS_DVBS, QPSK, FEC_3_4, 0x03 }, -{ SYS_DVBS, QPSK, FEC_4_5, 0x04 }, -{ SYS_DVBS, QPSK, FEC_5_6, 0x05 }, -{ SYS_DVBS, QPSK, FEC_6_7, 0x06 }, -{ SYS_DVBS, QPSK, FEC_7_8, 0x07 }, - -{ SYS_DVBS2, QPSK, FEC_1_2, 0x04 }, -{ SYS_DVBS2, QPSK, FEC_3_5, 0x05 }, -{ SYS_DVBS2, QPSK, FEC_2_3, 0x06 }, -{ SYS_DVBS2, QPSK, FEC_3_4, 0x07 }, -{ SYS_DVBS2, QPSK, FEC_4_5, 0x08 }, -{ SYS_DVBS2, QPSK, FEC_5_6, 0x09 }, -{ SYS_DVBS2, QPSK, FEC_8_9, 0x0a }, -{ SYS_DVBS2, QPSK, FEC_9_10, 0x0b }, - -{ SYS_DVBS2, PSK_8, FEC_3_5, 0x0c }, -{ SYS_DVBS2, PSK_8, FEC_2_3, 0x0d }, -{ SYS_DVBS2, PSK_8, FEC_3_4, 0x0e }, -{ SYS_DVBS2, PSK_8, FEC_5_6, 0x0f }, -{ SYS_DVBS2, PSK_8, FEC_8_9, 0x10 }, -{ SYS_DVBS2, PSK_8, FEC_9_10, 0x11 }, + /*delsys mod fec val */ + { SYS_DVBS, QPSK, FEC_1_2, 0x01 }, + { SYS_DVBS, QPSK, FEC_2_3, 0x02 }, + { SYS_DVBS, QPSK, FEC_3_4, 0x03 }, + { SYS_DVBS, QPSK, FEC_4_5, 0x04 }, + { SYS_DVBS, QPSK, FEC_5_6, 0x05 }, + { SYS_DVBS, QPSK, FEC_6_7, 0x06 }, + { SYS_DVBS, QPSK, FEC_7_8, 0x07 }, + + { SYS_DVBS2, QPSK, FEC_1_2, 0x04 }, + { SYS_DVBS2, QPSK, FEC_3_5, 0x05 }, + { SYS_DVBS2, QPSK, FEC_2_3, 0x06 }, + { SYS_DVBS2, QPSK, FEC_3_4, 0x07 }, + { SYS_DVBS2, QPSK, FEC_4_5, 0x08 }, + { SYS_DVBS2, QPSK, FEC_5_6, 0x09 }, + { SYS_DVBS2, QPSK, FEC_8_9, 0x0a }, + { SYS_DVBS2, QPSK, FEC_9_10, 0x0b }, + + { SYS_DVBS2, PSK_8, FEC_3_5, 0x0c }, + { SYS_DVBS2, PSK_8, FEC_2_3, 0x0d }, + { SYS_DVBS2, PSK_8, FEC_3_4, 0x0e }, + { SYS_DVBS2, PSK_8, FEC_5_6, 0x0f }, + { SYS_DVBS2, PSK_8, FEC_8_9, 0x10 }, + { SYS_DVBS2, PSK_8, FEC_9_10, 0x11 }, }; @@ -716,7 +717,7 @@ static int cx24120_get_fec(struct dvb_frontend *fe) dev_dbg(&state->i2c->dev, "%s()\n", __func__); ret = cx24120_readreg(state, CX24120_REG_FECMODE); - GettedFEC = ret & 0x3f; /* Lower 6 bits */ + GettedFEC = ret & 0x3f; /* Lower 6 bits */ dev_dbg(&state->i2c->dev, "%s: Get FEC: %d\n", __func__, GettedFEC); @@ -726,7 +727,7 @@ static int cx24120_get_fec(struct dvb_frontend *fe) if (modfec_lookup_table[idx].val != GettedFEC) continue; - break; /* found */ + break; /* found */ } if (idx >= ARRAY_SIZE(modfec_lookup_table)) { @@ -766,40 +767,40 @@ static struct cx24120_clock_ratios_table { u32 n_rat; u32 rate; } clock_ratios_table[] = { -/*delsys pilot mod fec m_rat n_rat rate */ -{ SYS_DVBS2, PILOT_OFF, QPSK, FEC_1_2, 273088, 254505, 274 }, -{ SYS_DVBS2, PILOT_OFF, QPSK, FEC_3_5, 17272, 13395, 330 }, -{ SYS_DVBS2, PILOT_OFF, QPSK, FEC_2_3, 24344, 16967, 367 }, -{ SYS_DVBS2, PILOT_OFF, QPSK, FEC_3_4, 410788, 254505, 413 }, -{ SYS_DVBS2, PILOT_OFF, QPSK, FEC_4_5, 438328, 254505, 440 }, -{ SYS_DVBS2, PILOT_OFF, QPSK, FEC_5_6, 30464, 16967, 459 }, -{ SYS_DVBS2, PILOT_OFF, QPSK, FEC_8_9, 487832, 254505, 490 }, -{ SYS_DVBS2, PILOT_OFF, QPSK, FEC_9_10, 493952, 254505, 496 }, -{ SYS_DVBS2, PILOT_OFF, PSK_8, FEC_3_5, 328168, 169905, 494 }, -{ SYS_DVBS2, PILOT_OFF, PSK_8, FEC_2_3, 24344, 11327, 550 }, -{ SYS_DVBS2, PILOT_OFF, PSK_8, FEC_3_4, 410788, 169905, 618 }, -{ SYS_DVBS2, PILOT_OFF, PSK_8, FEC_5_6, 30464, 11327, 688 }, -{ SYS_DVBS2, PILOT_OFF, PSK_8, FEC_8_9, 487832, 169905, 735 }, -{ SYS_DVBS2, PILOT_OFF, PSK_8, FEC_9_10, 493952, 169905, 744 }, -{ SYS_DVBS2, PILOT_ON, QPSK, FEC_1_2, 273088, 260709, 268 }, -{ SYS_DVBS2, PILOT_ON, QPSK, FEC_3_5, 328168, 260709, 322 }, -{ SYS_DVBS2, PILOT_ON, QPSK, FEC_2_3, 121720, 86903, 358 }, -{ SYS_DVBS2, PILOT_ON, QPSK, FEC_3_4, 410788, 260709, 403 }, -{ SYS_DVBS2, PILOT_ON, QPSK, FEC_4_5, 438328, 260709, 430 }, -{ SYS_DVBS2, PILOT_ON, QPSK, FEC_5_6, 152320, 86903, 448 }, -{ SYS_DVBS2, PILOT_ON, QPSK, FEC_8_9, 487832, 260709, 479 }, -{ SYS_DVBS2, PILOT_ON, QPSK, FEC_9_10, 493952, 260709, 485 }, -{ SYS_DVBS2, PILOT_ON, PSK_8, FEC_3_5, 328168, 173853, 483 }, -{ SYS_DVBS2, PILOT_ON, PSK_8, FEC_2_3, 121720, 57951, 537 }, -{ SYS_DVBS2, PILOT_ON, PSK_8, FEC_3_4, 410788, 173853, 604 }, -{ SYS_DVBS2, PILOT_ON, PSK_8, FEC_5_6, 152320, 57951, 672 }, -{ SYS_DVBS2, PILOT_ON, PSK_8, FEC_8_9, 487832, 173853, 718 }, -{ SYS_DVBS2, PILOT_ON, PSK_8, FEC_9_10, 493952, 173853, 727 }, -{ SYS_DVBS, PILOT_OFF, QPSK, FEC_1_2, 152592, 152592, 256 }, -{ SYS_DVBS, PILOT_OFF, QPSK, FEC_2_3, 305184, 228888, 341 }, -{ SYS_DVBS, PILOT_OFF, QPSK, FEC_3_4, 457776, 305184, 384 }, -{ SYS_DVBS, PILOT_OFF, QPSK, FEC_5_6, 762960, 457776, 427 }, -{ SYS_DVBS, PILOT_OFF, QPSK, FEC_7_8, 1068144, 610368, 448 }, + /*delsys pilot mod fec m_rat n_rat rate */ + { SYS_DVBS2, PILOT_OFF, QPSK, FEC_1_2, 273088, 254505, 274 }, + { SYS_DVBS2, PILOT_OFF, QPSK, FEC_3_5, 17272, 13395, 330 }, + { SYS_DVBS2, PILOT_OFF, QPSK, FEC_2_3, 24344, 16967, 367 }, + { SYS_DVBS2, PILOT_OFF, QPSK, FEC_3_4, 410788, 254505, 413 }, + { SYS_DVBS2, PILOT_OFF, QPSK, FEC_4_5, 438328, 254505, 440 }, + { SYS_DVBS2, PILOT_OFF, QPSK, FEC_5_6, 30464, 16967, 459 }, + { SYS_DVBS2, PILOT_OFF, QPSK, FEC_8_9, 487832, 254505, 490 }, + { SYS_DVBS2, PILOT_OFF, QPSK, FEC_9_10, 493952, 254505, 496 }, + { SYS_DVBS2, PILOT_OFF, PSK_8, FEC_3_5, 328168, 169905, 494 }, + { SYS_DVBS2, PILOT_OFF, PSK_8, FEC_2_3, 24344, 11327, 550 }, + { SYS_DVBS2, PILOT_OFF, PSK_8, FEC_3_4, 410788, 169905, 618 }, + { SYS_DVBS2, PILOT_OFF, PSK_8, FEC_5_6, 30464, 11327, 688 }, + { SYS_DVBS2, PILOT_OFF, PSK_8, FEC_8_9, 487832, 169905, 735 }, + { SYS_DVBS2, PILOT_OFF, PSK_8, FEC_9_10, 493952, 169905, 744 }, + { SYS_DVBS2, PILOT_ON, QPSK, FEC_1_2, 273088, 260709, 268 }, + { SYS_DVBS2, PILOT_ON, QPSK, FEC_3_5, 328168, 260709, 322 }, + { SYS_DVBS2, PILOT_ON, QPSK, FEC_2_3, 121720, 86903, 358 }, + { SYS_DVBS2, PILOT_ON, QPSK, FEC_3_4, 410788, 260709, 403 }, + { SYS_DVBS2, PILOT_ON, QPSK, FEC_4_5, 438328, 260709, 430 }, + { SYS_DVBS2, PILOT_ON, QPSK, FEC_5_6, 152320, 86903, 448 }, + { SYS_DVBS2, PILOT_ON, QPSK, FEC_8_9, 487832, 260709, 479 }, + { SYS_DVBS2, PILOT_ON, QPSK, FEC_9_10, 493952, 260709, 485 }, + { SYS_DVBS2, PILOT_ON, PSK_8, FEC_3_5, 328168, 173853, 483 }, + { SYS_DVBS2, PILOT_ON, PSK_8, FEC_2_3, 121720, 57951, 537 }, + { SYS_DVBS2, PILOT_ON, PSK_8, FEC_3_4, 410788, 173853, 604 }, + { SYS_DVBS2, PILOT_ON, PSK_8, FEC_5_6, 152320, 57951, 672 }, + { SYS_DVBS2, PILOT_ON, PSK_8, FEC_8_9, 487832, 173853, 718 }, + { SYS_DVBS2, PILOT_ON, PSK_8, FEC_9_10, 493952, 173853, 727 }, + { SYS_DVBS, PILOT_OFF, QPSK, FEC_1_2, 152592, 152592, 256 }, + { SYS_DVBS, PILOT_OFF, QPSK, FEC_2_3, 305184, 228888, 341 }, + { SYS_DVBS, PILOT_OFF, QPSK, FEC_3_4, 457776, 305184, 384 }, + { SYS_DVBS, PILOT_OFF, QPSK, FEC_5_6, 762960, 457776, 427 }, + { SYS_DVBS, PILOT_OFF, QPSK, FEC_7_8, 1068144, 610368, 448 }, }; @@ -835,7 +836,6 @@ static void cx24120_set_clock_ratios(struct dvb_frontend *fe) return; } - /* Read current values? */ cmd.id = CMD_CLOCK_READ; cmd.len = 1; @@ -855,8 +855,6 @@ static void cx24120_set_clock_ratios(struct dvb_frontend *fe) clock_ratios_table[idx].n_rat, clock_ratios_table[idx].rate); - - /* Set the clock */ cmd.id = CMD_CLOCK_SET; cmd.len = 10; @@ -872,7 +870,6 @@ static void cx24120_set_clock_ratios(struct dvb_frontend *fe) cmd.arg[9] = (clock_ratios_table[idx].rate >> 0) & 0xff; cx24120_message_send(state, &cmd); - } @@ -902,15 +899,13 @@ static int cx24120_set_inversion(struct cx24120_state *state, return 0; } -/* FEC lookup table for tuning - * Some DVB-S2 val's have been found by trial - * and error. Sofar it seems to match up with - * the contents of the REG_FECMODE after tuning - * The rest will probably be the same but would - * need testing. - * Anything not in the table will run with - * FEC_AUTO and take a while longer to tune in - * ( c.500ms instead of 30ms ) +/* + * FEC lookup table for tuning Some DVB-S2 val's have been found by + * trial and error. Sofar it seems to match up with the contents of + * the REG_FECMODE after tuning The rest will probably be the same but + * would need testing. Anything not in the table will run with + * FEC_AUTO and take a while longer to tune in ( c.500ms instead of + * 30ms ) */ static struct cx24120_modfec_table { fe_delivery_system_t delsys; @@ -919,17 +914,17 @@ static struct cx24120_modfec_table { u8 val; } modfec_table[] = { /*delsys mod fec val */ -{ SYS_DVBS, QPSK, FEC_1_2, 0x2e }, -{ SYS_DVBS, QPSK, FEC_2_3, 0x2f }, -{ SYS_DVBS, QPSK, FEC_3_4, 0x30 }, -{ SYS_DVBS, QPSK, FEC_5_6, 0x31 }, -{ SYS_DVBS, QPSK, FEC_6_7, 0x32 }, -{ SYS_DVBS, QPSK, FEC_7_8, 0x33 }, + { SYS_DVBS, QPSK, FEC_1_2, 0x2e }, + { SYS_DVBS, QPSK, FEC_2_3, 0x2f }, + { SYS_DVBS, QPSK, FEC_3_4, 0x30 }, + { SYS_DVBS, QPSK, FEC_5_6, 0x31 }, + { SYS_DVBS, QPSK, FEC_6_7, 0x32 }, + { SYS_DVBS, QPSK, FEC_7_8, 0x33 }, -{ SYS_DVBS2, QPSK, FEC_3_4, 0x07 }, + { SYS_DVBS2, QPSK, FEC_3_4, 0x07 }, -{ SYS_DVBS2, PSK_8, FEC_2_3, 0x0d }, -{ SYS_DVBS2, PSK_8, FEC_3_4, 0x0e }, + { SYS_DVBS2, PSK_8, FEC_2_3, 0x0d }, + { SYS_DVBS2, PSK_8, FEC_3_4, 0x0e }, }; /* Set fec_val & fec_mask values from delsys, modulation & fec */ @@ -958,7 +953,6 @@ static int cx24120_set_fec(struct cx24120_state *state, return 0; } - if (state->dnxt.delsys == SYS_DVBS2) { /* DVBS2 auto is 0x00/0x00 */ state->dnxt.fec_mask = 0x00; @@ -977,8 +971,7 @@ static int cx24120_set_fec(struct cx24120_state *state, static int cx24120_set_pilot(struct cx24120_state *state, fe_pilot_t pilot) { - dev_dbg(&state->i2c->dev, - "%s(%d)\n", __func__, pilot); + dev_dbg(&state->i2c->dev, "%s(%d)\n", __func__, pilot); /* Pilot only valid in DVBS2 */ if (state->dnxt.delsys != SYS_DVBS2) { @@ -986,7 +979,6 @@ static int cx24120_set_pilot(struct cx24120_state *state, return 0; } - switch (pilot) { case PILOT_OFF: state->dnxt.pilot_val = CX24120_PILOT_OFF; @@ -1038,16 +1030,16 @@ static struct cx24120_symrate_delay { u32 symrate; /* Check for >= this symrate */ u32 delay; /* Timeout in ms */ } symrates_delay_table[] = { -{ SYS_DVBS, 10000000, 400 }, -{ SYS_DVBS, 8000000, 2000 }, -{ SYS_DVBS, 6000000, 5000 }, -{ SYS_DVBS, 3000000, 10000 }, -{ SYS_DVBS, 0, 15000 }, -{ SYS_DVBS2, 10000000, 600 }, /* DVBS2 needs a little longer */ -{ SYS_DVBS2, 8000000, 2000 }, /* (so these might need bumping too) */ -{ SYS_DVBS2, 6000000, 5000 }, -{ SYS_DVBS2, 3000000, 10000 }, -{ SYS_DVBS2, 0, 15000 }, + { SYS_DVBS, 10000000, 400 }, + { SYS_DVBS, 8000000, 2000 }, + { SYS_DVBS, 6000000, 5000 }, + { SYS_DVBS, 3000000, 10000 }, + { SYS_DVBS, 0, 15000 }, + { SYS_DVBS2, 10000000, 600 }, /* DVBS2 needs a little longer */ + { SYS_DVBS2, 8000000, 2000 }, /* (so these might need bumping too) */ + { SYS_DVBS2, 6000000, 5000 }, + { SYS_DVBS2, 3000000, 10000 }, + { SYS_DVBS2, 0, 15000 }, }; @@ -1077,7 +1069,6 @@ static int cx24120_set_frontend(struct dvb_frontend *fe) break; } - state->dnxt.delsys = c->delivery_system; state->dnxt.modulation = c->modulation; state->dnxt.frequency = c->frequency; @@ -1099,7 +1090,6 @@ static int cx24120_set_frontend(struct dvb_frontend *fe) if (ret != 0) return ret; - /* discard the 'current' tuning parameters and prepare to tune */ cx24120_clone_params(fe); @@ -1123,8 +1113,6 @@ static int cx24120_set_frontend(struct dvb_frontend *fe) "%s: Inversion = %d (val = 0x%02x)\n", __func__, state->dcur.inversion, state->dcur.inversion_val); - - /* Tune in */ cmd.id = CMD_TUNEREQUEST; cmd.len = 15; @@ -1144,7 +1132,6 @@ static int cx24120_set_frontend(struct dvb_frontend *fe) cmd.arg[13] = state->dcur.clkdiv; cmd.arg[14] = 0; - /* Send tune command */ ret = cx24120_message_send(state, &cmd); if (ret != 0) @@ -1183,17 +1170,13 @@ static int cx24120_set_frontend(struct dvb_frontend *fe) delay_cnt -= 20; } - /* Fail to tune */ - dev_dbg(&state->i2c->dev, "%s: Tuning failed\n", - __func__); + dev_dbg(&state->i2c->dev, "%s: Tuning failed\n", __func__); return -EINVAL; - tuned: - dev_dbg(&state->i2c->dev, "%s: Tuning successful\n", - __func__); + dev_dbg(&state->i2c->dev, "%s: Tuning successful\n", __func__); /* Set clock ratios */ cx24120_set_clock_ratios(fe); -- cgit v1.2.3-59-g8ed1b From 1ff2e8ed28e96f49b0f98b9a86e755ddd1a1078b Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Tue, 28 Apr 2015 13:39:20 -0300 Subject: [media] cx24120: fix strict checkpatch-errors This patches fixes all checkpatch-errors. Even the ones created --strict. Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 167 +++++++++++----------------------- drivers/media/dvb-frontends/cx24120.h | 11 +-- 2 files changed, 59 insertions(+), 119 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index e09cab62b2c6..441a963e7acf 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -65,7 +65,6 @@ #define CX24120_REG_REVISION 0xff /* Chip revision (ro) */ - /* Command messages */ enum command_message_id { CMD_VCO_SET = 0x10, /* cmd.len = 12; */ @@ -131,7 +130,6 @@ struct cx24120_tuning { u8 pilot_val; }; - /* Private state */ struct cx24120_state { struct i2c_adapter *i2c; @@ -146,7 +144,6 @@ struct cx24120_state { struct cx24120_tuning dnxt; }; - /* Command message to firmware */ struct cx24120_cmd { u8 id; @@ -154,7 +151,6 @@ struct cx24120_cmd { u8 arg[CX24120_MAX_CMD_LEN]; }; - /* Read single register */ static int cx24120_readreg(struct cx24120_state *state, u8 reg) { @@ -185,7 +181,6 @@ static int cx24120_readreg(struct cx24120_state *state, u8 reg) return buf; } - /* Write single register */ static int cx24120_writereg(struct cx24120_state *state, u8 reg, u8 data) { @@ -201,7 +196,7 @@ static int cx24120_writereg(struct cx24120_state *state, u8 reg, u8 data) ret = i2c_transfer(state->i2c, &msg, 1); if (ret != 1) { err("Write error: i2c_write error(err == %i, 0x%02x: 0x%02x)\n", - ret, reg, data); + ret, reg, data); return ret; } @@ -211,10 +206,9 @@ static int cx24120_writereg(struct cx24120_state *state, u8 reg, u8 data) return 0; } - /* Write multiple registers in chunks of i2c_wr_max-sized buffers */ -static int cx24120_writeregN(struct cx24120_state *state, - u8 reg, const u8 *values, u16 len, u8 incr) +static int cx24120_writeregs(struct cx24120_state *state, + u8 reg, const u8 *values, u16 len, u8 incr) { int ret; u16 max = state->config->i2c_wr_max > 0 ? @@ -227,7 +221,7 @@ static int cx24120_writeregN(struct cx24120_state *state, }; msg.buf = kmalloc(max + 1, GFP_KERNEL); - if (msg.buf == NULL) + if (!msg.buf) return -ENOMEM; while (len) { @@ -250,7 +244,7 @@ static int cx24120_writeregN(struct cx24120_state *state, dev_dbg(&state->i2c->dev, "%s: reg=0x%02x; data=%*ph\n", - __func__, reg, msg.len, msg.buf+1); + __func__, reg, msg.len, msg.buf + 1); } ret = 0; @@ -260,18 +254,17 @@ out: return ret; } - static struct dvb_frontend_ops cx24120_ops; struct dvb_frontend *cx24120_attach(const struct cx24120_config *config, - struct i2c_adapter *i2c) + struct i2c_adapter *i2c) { - struct cx24120_state *state = NULL; + struct cx24120_state *state; int demod_rev; info("Conexant cx24120/cx24118 - DVBS/S2 Satellite demod/tuner\n"); - state = kzalloc(sizeof(struct cx24120_state), GFP_KERNEL); - if (state == NULL) { + state = kzalloc(sizeof(*state), GFP_KERNEL); + if (!state) { err("Unable to allocate memory for cx24120_state\n"); goto error; } @@ -290,8 +283,7 @@ struct dvb_frontend *cx24120_attach(const struct cx24120_config *config, info("Demod cx24120 rev. 0x05 detected.\n"); break; default: - err("Unsupported demod revision: 0x%x detected.\n", - demod_rev); + err("Unsupported demod revision: 0x%x detected.\n", demod_rev); goto error; } @@ -322,36 +314,32 @@ static int cx24120_test_rom(struct cx24120_state *state) return err; } - static int cx24120_read_snr(struct dvb_frontend *fe, u16 *snr) { struct cx24120_state *state = fe->demodulator_priv; - *snr = (cx24120_readreg(state, CX24120_REG_QUALITY_H)<<8) | + *snr = (cx24120_readreg(state, CX24120_REG_QUALITY_H) << 8) | (cx24120_readreg(state, CX24120_REG_QUALITY_L)); - dev_dbg(&state->i2c->dev, "%s: read SNR index = %d\n", - __func__, *snr); + dev_dbg(&state->i2c->dev, "%s: read SNR index = %d\n", __func__, *snr); return 0; } - static int cx24120_read_ber(struct dvb_frontend *fe, u32 *ber) { struct cx24120_state *state = fe->demodulator_priv; *ber = (cx24120_readreg(state, CX24120_REG_BER_HH) << 24) | (cx24120_readreg(state, CX24120_REG_BER_HL) << 16) | - (cx24120_readreg(state, CX24120_REG_BER_LH) << 8) | + (cx24120_readreg(state, CX24120_REG_BER_LH) << 8) | cx24120_readreg(state, CX24120_REG_BER_LL); - dev_dbg(&state->i2c->dev, "%s: read BER index = %d\n", - __func__, *ber); + dev_dbg(&state->i2c->dev, "%s: read BER index = %d\n", __func__, *ber); return 0; } static int cx24120_msg_mpeg_output_global_config(struct cx24120_state *state, - u8 flag); + u8 flag); /* Check if we're running a command that needs to disable mpeg out */ static void cx24120_check_cmd(struct cx24120_state *state, u8 id) @@ -370,10 +358,9 @@ static void cx24120_check_cmd(struct cx24120_state *state, u8 id) } } - /* Send a message to the firmware */ static int cx24120_message_send(struct cx24120_state *state, - struct cx24120_cmd *cmd) + struct cx24120_cmd *cmd) { int ret, ficus; @@ -383,7 +370,7 @@ static int cx24120_message_send(struct cx24120_state *state, } ret = cx24120_writereg(state, CX24120_REG_CMD_START, cmd->id); - ret = cx24120_writeregN(state, CX24120_REG_CMD_ARGS, &cmd->arg[0], + ret = cx24120_writeregs(state, CX24120_REG_CMD_ARGS, &cmd->arg[0], cmd->len, 1); ret = cx24120_writereg(state, CX24120_REG_CMD_END, 0x01); @@ -404,7 +391,7 @@ static int cx24120_message_send(struct cx24120_state *state, /* Send a message and fill arg[] with the results */ static int cx24120_message_sendrcv(struct cx24120_state *state, - struct cx24120_cmd *cmd, u8 numreg) + struct cx24120_cmd *cmd, u8 numreg) { int ret, i; @@ -422,15 +409,13 @@ static int cx24120_message_sendrcv(struct cx24120_state *state, /* Read numreg registers starting from register cmd->len */ for (i = 0; i < numreg; i++) - cmd->arg[i] = cx24120_readreg(state, (cmd->len+i+1)); + cmd->arg[i] = cx24120_readreg(state, (cmd->len + i + 1)); return 0; } - - static int cx24120_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) + u16 *signal_strength) { struct cx24120_state *state = fe->demodulator_priv; struct cx24120_cmd cmd; @@ -450,19 +435,18 @@ static int cx24120_read_signal_strength(struct dvb_frontend *fe, sigstr_h = (cx24120_readreg(state, CX24120_REG_SIGSTR_H) >> 6) << 8; sigstr_l = cx24120_readreg(state, CX24120_REG_SIGSTR_L); dev_dbg(&state->i2c->dev, "%s: Signal strength from firmware= 0x%x\n", - __func__, (sigstr_h | sigstr_l)); + __func__, (sigstr_h | sigstr_l)); /* cooked */ *signal_strength = ((sigstr_h | sigstr_l) << 5) & 0x0000ffff; dev_dbg(&state->i2c->dev, "%s: Signal strength= 0x%x\n", - __func__, *signal_strength); + __func__, *signal_strength); return 0; } - static int cx24120_msg_mpeg_output_global_config(struct cx24120_state *state, - u8 enable) + u8 enable) { struct cx24120_cmd cmd; int ret; @@ -478,20 +462,17 @@ static int cx24120_msg_mpeg_output_global_config(struct cx24120_state *state, if (ret != 0) { dev_dbg(&state->i2c->dev, "%s: Failed to set MPEG output to %s\n", - __func__, - (enable)?"enabled":"disabled"); + __func__, enable ? "enabled" : "disabled"); return ret; } state->mpeg_enabled = enable; dev_dbg(&state->i2c->dev, "%s: MPEG output %s\n", - __func__, - (enable)?"enabled":"disabled"); + __func__, enable ? "enabled" : "disabled"); return 0; } - static int cx24120_msg_mpeg_output_config(struct cx24120_state *state, u8 seq) { struct cx24120_cmd cmd; @@ -500,7 +481,7 @@ static int cx24120_msg_mpeg_output_config(struct cx24120_state *state, u8 seq) cmd.id = CMD_MPEG_INIT; cmd.len = 7; - cmd.arg[0] = seq; /* sequental number - can be 0,1,2 */ + cmd.arg[0] = seq; /* sequental number - can be 0,1,2 */ cmd.arg[1] = ((i.x1 & 0x01) << 1) | ((i.x1 >> 1) & 0x01); cmd.arg[2] = 0x05; cmd.arg[3] = 0x02; @@ -511,9 +492,8 @@ static int cx24120_msg_mpeg_output_config(struct cx24120_state *state, u8 seq) return cx24120_message_send(state, &cmd); } - static int cx24120_diseqc_send_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t burst) + fe_sec_mini_cmd_t burst) { struct cx24120_state *state = fe->demodulator_priv; struct cx24120_cmd cmd; @@ -529,19 +509,18 @@ static int cx24120_diseqc_send_burst(struct dvb_frontend *fe, cmd.arg[0] = 0x00; if (burst) cmd.arg[1] = 0x01; + dev_dbg(&state->i2c->dev, "%s: burst sent.\n", __func__); return cx24120_message_send(state, &cmd); } - static int cx24120_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) { struct cx24120_state *state = fe->demodulator_priv; struct cx24120_cmd cmd; - dev_dbg(&state->i2c->dev, "%s(%d)\n", - __func__, tone); + dev_dbg(&state->i2c->dev, "%s(%d)\n", __func__, tone); if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) { err("Invalid tone=%d\n", tone); @@ -553,32 +532,29 @@ static int cx24120_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) cmd.arg[0] = 0x00; cmd.arg[1] = 0x00; cmd.arg[2] = 0x00; - cmd.arg[3] = (tone == SEC_TONE_ON)?0x01:0x00; + cmd.arg[3] = (tone == SEC_TONE_ON) ? 0x01 : 0x00; return cx24120_message_send(state, &cmd); } - static int cx24120_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) + fe_sec_voltage_t voltage) { struct cx24120_state *state = fe->demodulator_priv; struct cx24120_cmd cmd; - dev_dbg(&state->i2c->dev, "%s(%d)\n", - __func__, voltage); + dev_dbg(&state->i2c->dev, "%s(%d)\n", __func__, voltage); cmd.id = CMD_SETVOLTAGE; cmd.len = 2; cmd.arg[0] = 0x00; - cmd.arg[1] = (voltage == SEC_VOLTAGE_18)?0x01:0x00; + cmd.arg[1] = (voltage == SEC_VOLTAGE_18) ? 0x01 : 0x00; return cx24120_message_send(state, &cmd); } - static int cx24120_send_diseqc_msg(struct dvb_frontend *fe, - struct dvb_diseqc_master_cmd *d) + struct dvb_diseqc_master_cmd *d) { struct cx24120_state *state = fe->demodulator_priv; struct cx24120_cmd cmd; @@ -637,7 +613,6 @@ static int cx24120_send_diseqc_msg(struct dvb_frontend *fe, return -ETIMEDOUT; } - /* Read current tuning status */ static int cx24120_read_status(struct dvb_frontend *fe, fe_status_t *status) { @@ -667,7 +642,6 @@ static int cx24120_read_status(struct dvb_frontend *fe, fe_status_t *status) return 0; } - /* FEC & modulation lookup table * Used for decoding the REG_FECMODE register * once tuned in. @@ -704,7 +678,6 @@ static struct cx24120_modfec { { SYS_DVBS2, PSK_8, FEC_9_10, 0x11 }, }; - /* Retrieve current fec, modulation & pilot values */ static int cx24120_get_fec(struct dvb_frontend *fe) { @@ -712,19 +685,19 @@ static int cx24120_get_fec(struct dvb_frontend *fe) struct cx24120_state *state = fe->demodulator_priv; int idx; int ret; - int GettedFEC; + int fec; dev_dbg(&state->i2c->dev, "%s()\n", __func__); ret = cx24120_readreg(state, CX24120_REG_FECMODE); - GettedFEC = ret & 0x3f; /* Lower 6 bits */ + fec = ret & 0x3f; /* Lower 6 bits */ - dev_dbg(&state->i2c->dev, "%s: Get FEC: %d\n", __func__, GettedFEC); + dev_dbg(&state->i2c->dev, "%s: Get FEC: %d\n", __func__, fec); for (idx = 0; idx < ARRAY_SIZE(modfec_lookup_table); idx++) { if (modfec_lookup_table[idx].delsys != state->dcur.delsys) continue; - if (modfec_lookup_table[idx].val != GettedFEC) + if (modfec_lookup_table[idx].val != fec) continue; break; /* found */ @@ -749,7 +722,6 @@ static int cx24120_get_fec(struct dvb_frontend *fe) return 0; } - /* Clock ratios lookup table * * Values obtained from much larger table in old driver @@ -803,7 +775,6 @@ static struct cx24120_clock_ratios_table { { SYS_DVBS, PILOT_OFF, QPSK, FEC_7_8, 1068144, 610368, 448 }, }; - /* Set clock ratio from lookup table */ static void cx24120_set_clock_ratios(struct dvb_frontend *fe) { @@ -872,13 +843,11 @@ static void cx24120_set_clock_ratios(struct dvb_frontend *fe) cx24120_message_send(state, &cmd); } - /* Set inversion value */ static int cx24120_set_inversion(struct cx24120_state *state, - fe_spectral_inversion_t inversion) + fe_spectral_inversion_t inversion) { - dev_dbg(&state->i2c->dev, "%s(%d)\n", - __func__, inversion); + dev_dbg(&state->i2c->dev, "%s(%d)\n", __func__, inversion); switch (inversion) { case INVERSION_OFF: @@ -928,13 +897,12 @@ static struct cx24120_modfec_table { }; /* Set fec_val & fec_mask values from delsys, modulation & fec */ -static int cx24120_set_fec(struct cx24120_state *state, - fe_modulation_t mod, fe_code_rate_t fec) +static int cx24120_set_fec(struct cx24120_state *state, fe_modulation_t mod, + fe_code_rate_t fec) { int idx; - dev_dbg(&state->i2c->dev, - "%s(0x%02x,0x%02x)\n", __func__, mod, fec); + dev_dbg(&state->i2c->dev, "%s(0x%02x,0x%02x)\n", __func__, mod, fec); state->dnxt.fec = fec; @@ -966,11 +934,9 @@ static int cx24120_set_fec(struct cx24120_state *state, return 0; } - /* Set pilot */ -static int cx24120_set_pilot(struct cx24120_state *state, - fe_pilot_t pilot) { - +static int cx24120_set_pilot(struct cx24120_state *state, fe_pilot_t pilot) +{ dev_dbg(&state->i2c->dev, "%s(%d)\n", __func__, pilot); /* Pilot only valid in DVBS2 */ @@ -1014,7 +980,6 @@ static int cx24120_set_symbolrate(struct cx24120_state *state, u32 rate) return 0; } - /* Overwrite the current tuning params, we are about to tune */ static void cx24120_clone_params(struct dvb_frontend *fe) { @@ -1023,7 +988,6 @@ static void cx24120_clone_params(struct dvb_frontend *fe) state->dcur = state->dnxt; } - /* Table of time to tune for different symrates */ static struct cx24120_symrate_delay { fe_delivery_system_t delsys; @@ -1042,7 +1006,6 @@ static struct cx24120_symrate_delay { { SYS_DVBS2, 0, 15000 }, }; - static int cx24120_set_frontend(struct dvb_frontend *fe) { struct dtv_frontend_properties *c = &fe->dtv_property_cache; @@ -1120,8 +1083,8 @@ static int cx24120_set_frontend(struct dvb_frontend *fe) cmd.arg[1] = (state->dcur.frequency & 0xff0000) >> 16; cmd.arg[2] = (state->dcur.frequency & 0x00ff00) >> 8; cmd.arg[3] = (state->dcur.frequency & 0x0000ff); - cmd.arg[4] = ((state->dcur.symbol_rate/1000) & 0xff00) >> 8; - cmd.arg[5] = ((state->dcur.symbol_rate/1000) & 0x00ff); + cmd.arg[4] = ((state->dcur.symbol_rate / 1000) & 0xff00) >> 8; + cmd.arg[5] = ((state->dcur.symbol_rate / 1000) & 0x00ff); cmd.arg[6] = state->dcur.inversion; cmd.arg[7] = state->dcur.fec_val | state->dcur.pilot_val; cmd.arg[8] = CX24120_SEARCH_RANGE_KHZ >> 8; @@ -1190,7 +1153,6 @@ tuned: return 0; } - /* Calculate vco from config */ static u64 cx24120_calculate_vco(struct cx24120_state *state) { @@ -1213,7 +1175,6 @@ static u64 cx24120_calculate_vco(struct cx24120_state *state) return inv_vco; } - int cx24120_init(struct dvb_frontend *fe) { const struct firmware *fw; @@ -1270,8 +1231,8 @@ int cx24120_init(struct dvb_frontend *fe) ret = state->config->request_firmware(fe, &fw, CX24120_FIRMWARE); if (ret) { - err("Could not load firmware (%s): %d\n", - CX24120_FIRMWARE, ret); + err("Could not load firmware (%s): %d\n", CX24120_FIRMWARE, + ret); return ret; } @@ -1291,7 +1252,7 @@ int cx24120_init(struct dvb_frontend *fe) ret = cx24120_writereg(state, 0xf7, 0x81); ret = cx24120_writereg(state, 0xf8, 0x00); ret = cx24120_writereg(state, 0xf9, 0x00); - ret = cx24120_writeregN(state, 0xfa, fw->data, (fw->size - 1), 0x00); + ret = cx24120_writeregs(state, 0xfa, fw->data, (fw->size - 1), 0x00); ret = cx24120_writereg(state, 0xf7, 0xc0); ret = cx24120_writereg(state, 0xe0, 0x00); ret = (fw->size - 2) & 0x00ff; @@ -1319,7 +1280,6 @@ int cx24120_init(struct dvb_frontend *fe) if (reset_result != 0) return reset_result; - /* Start tuner */ cmd.id = CMD_START_TUNER; cmd.len = 3; @@ -1355,7 +1315,6 @@ int cx24120_init(struct dvb_frontend *fe) return -EREMOTEIO; } - /* set bandwidth */ cmd.id = CMD_BANDWIDTH; cmd.len = 12; @@ -1386,8 +1345,7 @@ int cx24120_init(struct dvb_frontend *fe) } dev_dbg(&state->i2c->dev, "%s: Tuner initialised correctly.\n", - __func__); - + __func__); /* Initialise mpeg outputs */ ret = cx24120_writereg(state, 0xeb, 0x0a); @@ -1399,7 +1357,6 @@ int cx24120_init(struct dvb_frontend *fe) return -EREMOTEIO; } - /* ???? */ cmd.id = CMD_TUNER_INIT; cmd.len = 3; @@ -1411,7 +1368,6 @@ int cx24120_init(struct dvb_frontend *fe) return -EREMOTEIO; } - /* Firmware CMD 35: Get firmware version */ cmd.id = CMD_FWVERSION; cmd.len = 1; @@ -1428,9 +1384,9 @@ int cx24120_init(struct dvb_frontend *fe) return 0; } - static int cx24120_tune(struct dvb_frontend *fe, bool re_tune, - unsigned int mode_flags, unsigned int *delay, fe_status_t *status) + unsigned int mode_flags, unsigned int *delay, + fe_status_t *status) { struct cx24120_state *state = fe->demodulator_priv; int ret; @@ -1448,27 +1404,16 @@ static int cx24120_tune(struct dvb_frontend *fe, bool re_tune, return cx24120_read_status(fe, status); } - - static int cx24120_get_algo(struct dvb_frontend *fe) { return DVBFE_ALGO_HW; } - static int cx24120_sleep(struct dvb_frontend *fe) { return 0; } - -/*static int cx24120_wakeup(struct dvb_frontend *fe) - * { - * return 0; - * } -*/ - - static int cx24120_get_frontend(struct dvb_frontend *fe) { struct dtv_frontend_properties *c = &fe->dtv_property_cache; @@ -1495,7 +1440,6 @@ static int cx24120_get_frontend(struct dvb_frontend *fe) return 0; } - static void cx24120_release(struct dvb_frontend *fe) { struct cx24120_state *state = fe->demodulator_priv; @@ -1504,7 +1448,6 @@ static void cx24120_release(struct dvb_frontend *fe) kfree(state); } - static int cx24120_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) { struct cx24120_state *state = fe->demodulator_priv; @@ -1512,12 +1455,10 @@ static int cx24120_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) *ucblocks = (cx24120_readreg(state, CX24120_REG_UCB_H) << 8) | cx24120_readreg(state, CX24120_REG_UCB_L); - dev_dbg(&state->i2c->dev, "%s: Blocks = %d\n", - __func__, *ucblocks); + dev_dbg(&state->i2c->dev, "%s: Blocks = %d\n", __func__, *ucblocks); return 0; } - static struct dvb_frontend_ops cx24120_ops = { .delsys = { SYS_DVBS, SYS_DVBS2 }, .info = { diff --git a/drivers/media/dvb-frontends/cx24120.h b/drivers/media/dvb-frontends/cx24120.h index e5748aaa8418..f0970423e16f 100644 --- a/drivers/media/dvb-frontends/cx24120.h +++ b/drivers/media/dvb-frontends/cx24120.h @@ -43,13 +43,12 @@ struct cx24120_config { }; #if IS_REACHABLE(CONFIG_DVB_CX24120) -extern struct dvb_frontend *cx24120_attach( - const struct cx24120_config *config, - struct i2c_adapter *i2c); +struct dvb_frontend *cx24120_attach(const struct cx24120_config *config, + struct i2c_adapter *i2c); #else -static inline struct dvb_frontend *cx24120_attach( - const struct cx24120_config *config, - struct i2c_adapter *i2c) +static inline +struct dvb_frontend *cx24120_attach(const struct cx24120_config *config, + struct i2c_adapter *i2c) { pr_warn("%s: driver disabled by Kconfig\n", __func__); return NULL; -- cgit v1.2.3-59-g8ed1b From cd20c596b5d2ec70a00945fbc7d8eb218b85cf84 Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Thu, 30 Apr 2015 15:01:11 -0300 Subject: [media] cx24120: Fix minor style typo in Kconfig This patch changes DVB-S/DVB-S2 to the more commonly used DVB-S/S2 in the description for DVB_CX24120 Signed-off-by: Jemma Denson Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index 7ff3ec4d8ab6..65034a82b24e 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -228,7 +228,7 @@ config DVB_CX24120 depends on DVB_CORE && I2C default m if !MEDIA_SUBDRV_AUTOSELECT help - A DVB-S/DVB-S2 tuner module. Say Y when you want to support this frontend. + A DVB-S/S2 tuner module. Say Y when you want to support this frontend. config DVB_SI21XX tristate "Silicon Labs SI21XX based" -- cgit v1.2.3-59-g8ed1b From 6138dc2f5f4f1eb02ac05a002de267d4e130c0cd Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Thu, 30 Apr 2015 16:37:42 -0300 Subject: [media] cx24120: Move clock set to read_status This patch removes the requirement of waiting for tune in set_frontend by moving the clock set call into read_status Signed-off-by: Jemma Denson Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 87 +++++++++-------------------------- 1 file changed, 23 insertions(+), 64 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index 441a963e7acf..554601512ee4 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -138,6 +138,7 @@ struct cx24120_state { u8 cold_init; u8 mpeg_enabled; + u8 need_clock_set; /* current and next tuning parameters */ struct cx24120_tuning dcur; @@ -613,6 +614,8 @@ static int cx24120_send_diseqc_msg(struct dvb_frontend *fe, return -ETIMEDOUT; } +static void cx24120_set_clock_ratios(struct dvb_frontend *fe); + /* Read current tuning status */ static int cx24120_read_status(struct dvb_frontend *fe, fe_status_t *status) { @@ -639,6 +642,20 @@ static int cx24120_read_status(struct dvb_frontend *fe, fe_status_t *status) * Other cx241xx drivers have this slightly * different */ + /* Set the clock once tuned in */ + if (state->need_clock_set && *status & FE_HAS_LOCK) { + /* Set clock ratios */ + cx24120_set_clock_ratios(fe); + + /* Old driver would do a msleep(200) here */ + + /* Renable mpeg output */ + if (!state->mpeg_enabled) + cx24120_msg_mpeg_output_global_config(state, 1); + + state->need_clock_set = 0; + } + return 0; } @@ -988,32 +1005,12 @@ static void cx24120_clone_params(struct dvb_frontend *fe) state->dcur = state->dnxt; } -/* Table of time to tune for different symrates */ -static struct cx24120_symrate_delay { - fe_delivery_system_t delsys; - u32 symrate; /* Check for >= this symrate */ - u32 delay; /* Timeout in ms */ -} symrates_delay_table[] = { - { SYS_DVBS, 10000000, 400 }, - { SYS_DVBS, 8000000, 2000 }, - { SYS_DVBS, 6000000, 5000 }, - { SYS_DVBS, 3000000, 10000 }, - { SYS_DVBS, 0, 15000 }, - { SYS_DVBS2, 10000000, 600 }, /* DVBS2 needs a little longer */ - { SYS_DVBS2, 8000000, 2000 }, /* (so these might need bumping too) */ - { SYS_DVBS2, 6000000, 5000 }, - { SYS_DVBS2, 3000000, 10000 }, - { SYS_DVBS2, 0, 15000 }, -}; - static int cx24120_set_frontend(struct dvb_frontend *fe) { struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct cx24120_state *state = fe->demodulator_priv; struct cx24120_cmd cmd; int ret; - int delay_cnt, sd_idx = 0; - fe_status_t status; switch (c->delivery_system) { case SYS_DVBS2: @@ -1076,6 +1073,9 @@ static int cx24120_set_frontend(struct dvb_frontend *fe) "%s: Inversion = %d (val = 0x%02x)\n", __func__, state->dcur.inversion, state->dcur.inversion_val); + /* Flag that clock needs to be set after tune */ + state->need_clock_set = 1; + /* Tune in */ cmd.id = CMD_TUNEREQUEST; cmd.len = 15; @@ -1107,49 +1107,6 @@ static int cx24120_set_frontend(struct dvb_frontend *fe) ret |= state->dcur.ratediv; ret = cx24120_writereg(state, CX24120_REG_RATEDIV, ret); - /* Default time to tune */ - delay_cnt = 500; - - /* Establish time to tune from symrates_delay_table */ - for (sd_idx = 0; sd_idx < ARRAY_SIZE(symrates_delay_table); sd_idx++) { - if (state->dcur.delsys != symrates_delay_table[sd_idx].delsys) - continue; - if (c->symbol_rate < symrates_delay_table[sd_idx].symrate) - continue; - - /* found */ - delay_cnt = symrates_delay_table[sd_idx].delay; - dev_dbg(&state->i2c->dev, "%s: Found symrate delay = %d\n", - __func__, delay_cnt); - break; - } - - /* Wait for tuning */ - while (delay_cnt >= 0) { - cx24120_read_status(fe, &status); - if (status & FE_HAS_LOCK) - goto tuned; - msleep(20); - delay_cnt -= 20; - } - - /* Fail to tune */ - dev_dbg(&state->i2c->dev, "%s: Tuning failed\n", __func__); - - return -EINVAL; - -tuned: - dev_dbg(&state->i2c->dev, "%s: Tuning successful\n", __func__); - - /* Set clock ratios */ - cx24120_set_clock_ratios(fe); - - /* Old driver would do a msleep(200) here */ - - /* Renable mpeg output */ - if (!state->mpeg_enabled) - cx24120_msg_mpeg_output_global_config(state, 1); - return 0; } @@ -1419,11 +1376,13 @@ static int cx24120_get_frontend(struct dvb_frontend *fe) struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct cx24120_state *state = fe->demodulator_priv; u8 freq1, freq2, freq3; + fe_status_t status; dev_dbg(&state->i2c->dev, "%s()", __func__); /* don't return empty data if we're not tuned in */ - if (state->mpeg_enabled) + cx24120_read_status(fe, &status); + if ((status & FE_HAS_LOCK) == 0) return 0; /* Get frequency */ -- cgit v1.2.3-59-g8ed1b From 270e70713b3a52fcd0a2f39f14b78b109ccfb944 Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Thu, 30 Apr 2015 17:05:14 -0300 Subject: [media] cx24120: Add missing command to cx24120_check_cmd This patch adds in a missing command to cx24120_check_cmd. This part of the old reverse engineered driver was quite hard to follow - it's presumed the compiler did some neat optimisation that wasn't easy to decode. This command was checked for in that version but not copied across to the new switch statement. For reference, old reverse engineered code: xxzz = cmd->id - 0x11; // look for specific message id if ( xxzz <= 0x13 ) { msg_cmd_mask = 1 << xxzz; //0x0F8021 // if cmd_id 17 or 22 or 33-36, 42, 47, 57-61 etc. disable mpeg output if ( msg_cmd_mask & 0x0F8021 ) { // 000011111000000000100001b cx24120_msg_mpeg_output_global_config(state, 0); msleep(100); state->dvb_s2_mode &= 0xFD; // reset mpeg out enable flag } } Signed-off-by: Jemma Denson Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index 554601512ee4..095af2e6f59f 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -352,6 +352,7 @@ static void cx24120_check_cmd(struct cx24120_state *state, u8 id) case CMD_DISEQC_MSG2: case CMD_SETVOLTAGE: case CMD_SETTONE: + case CMD_DISEQC_BURST: cx24120_msg_mpeg_output_global_config(state, 0); /* Old driver would do a msleep(100) here */ default: -- cgit v1.2.3-59-g8ed1b From 6ce412292a2ae15eea55c70f43449a9857404c00 Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Fri, 1 May 2015 16:20:16 -0300 Subject: [media] cx24120: Fix hexdump length in writeregs msg.len has been ++'d so msg.len is one too many. Signed-off-by: Jemma Denson Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index 095af2e6f59f..74ce7a75a961 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -245,7 +245,7 @@ static int cx24120_writeregs(struct cx24120_state *state, dev_dbg(&state->i2c->dev, "%s: reg=0x%02x; data=%*ph\n", - __func__, reg, msg.len, msg.buf + 1); + __func__, reg, msg.len - 1, msg.buf + 1); } ret = 0; -- cgit v1.2.3-59-g8ed1b From c84251bb122d6abcb0178f2c922f9ef51740e7ad Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Sun, 3 May 2015 08:55:15 -0300 Subject: [media] cx24120: Rework vco function to remove xxyyzz variable Change calculate_vco function to send_vco to tidy up cx24120_init function. xxyyzz variable is remnants of a manual div & remainder codepath to perform a u64 rounded div; replace with kernel macro DIV_ROUND_CLOSEST_ULL Hex values provided to the message are mainly variables calculated within this function, replace with these to remove hardcoding. Signed-off-by: Jemma Denson Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 63 ++++++++++++++++------------------- 1 file changed, 29 insertions(+), 34 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index 74ce7a75a961..8238f80ea98e 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -1111,26 +1111,38 @@ static int cx24120_set_frontend(struct dvb_frontend *fe) return 0; } -/* Calculate vco from config */ -static u64 cx24120_calculate_vco(struct cx24120_state *state) +/* Set vco from config */ +static int cx24120_set_vco(struct cx24120_state *state) { - u32 vco; - u64 inv_vco, res, xxyyzz; + struct cx24120_cmd cmd; + u32 nxtal_khz, vco; + u64 inv_vco; u32 xtal_khz = state->config->xtal_khz; - xxyyzz = 0x400000000ULL; - vco = xtal_khz * 10 * 4; - inv_vco = xxyyzz / vco; - res = xxyyzz % vco; - - if (inv_vco > xtal_khz * 10 * 2) - ++inv_vco; + nxtal_khz = xtal_khz * 4; + vco = nxtal_khz * 10; + inv_vco = DIV_ROUND_CLOSEST_ULL(0x400000000ULL, vco); dev_dbg(&state->i2c->dev, - "%s: xtal=%d, vco=%d, inv_vco=%lld, res=%lld\n", - __func__, xtal_khz, vco, inv_vco, res); + "%s: xtal=%d, vco=%d, inv_vco=%lld\n", + __func__, xtal_khz, vco, inv_vco); - return inv_vco; + cmd.id = CMD_VCO_SET; + cmd.len = 12; + cmd.arg[0] = (vco >> 16) & 0xff; + cmd.arg[1] = (vco >> 8) & 0xff; + cmd.arg[2] = vco & 0xff; + cmd.arg[3] = (inv_vco >> 8) & 0xff; + cmd.arg[4] = (inv_vco) & 0xff; + cmd.arg[5] = 0x03; + cmd.arg[6] = (nxtal_khz >> 8) & 0xff; + cmd.arg[7] = nxtal_khz & 0xff; + cmd.arg[8] = 0x06; + cmd.arg[9] = 0x03; + cmd.arg[10] = (xtal_khz >> 16) & 0xff; + cmd.arg[11] = xtal_khz & 0xff; + + return cx24120_message_send(state, &cmd); } int cx24120_init(struct dvb_frontend *fe) @@ -1139,7 +1151,6 @@ int cx24120_init(struct dvb_frontend *fe) struct cx24120_state *state = fe->demodulator_priv; struct cx24120_cmd cmd; u8 ret, ret_EA, reg1; - u64 inv_vco; int reset_result; int i; @@ -1251,26 +1262,10 @@ int cx24120_init(struct dvb_frontend *fe) } /* Set VCO */ - inv_vco = cx24120_calculate_vco(state); - - cmd.id = CMD_VCO_SET; - cmd.len = 12; - cmd.arg[0] = 0x06; - cmd.arg[1] = 0x2b; - cmd.arg[2] = 0xd8; - cmd.arg[3] = (inv_vco >> 8) & 0xff; - cmd.arg[4] = (inv_vco) & 0xff; - cmd.arg[5] = 0x03; - cmd.arg[6] = 0x9d; - cmd.arg[7] = 0xfc; - cmd.arg[8] = 0x06; - cmd.arg[9] = 0x03; - cmd.arg[10] = 0x27; - cmd.arg[11] = 0x7f; - - if (cx24120_message_send(state, &cmd)) { + ret = cx24120_set_vco(state); + if (ret != 0) { err("Error set VCO! :(\n"); - return -EREMOTEIO; + return ret; } /* set bandwidth */ -- cgit v1.2.3-59-g8ed1b From 9fc18f18a568a944e93de6f6c2148a688623429b Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Tue, 5 May 2015 16:59:27 -0300 Subject: [media] cx24120: Add DVBv5 signal strength stats Add new get_stats function, called from read_status, for collecting DVBv5 stats into the frontend cache. Only signal strength for now, can add others later. Not currently marked as available, future patch will enable. Signed-off-by: Jemma Denson Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index 8238f80ea98e..ff16611b5eb4 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -615,6 +615,32 @@ static int cx24120_send_diseqc_msg(struct dvb_frontend *fe, return -ETIMEDOUT; } +static void cx24120_get_stats(struct cx24120_state *state, fe_status_t status) +{ + struct dvb_frontend *fe = &state->frontend; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + int ret; + u16 u16tmp; + + dev_dbg(&state->i2c->dev, "%s()\n", __func__); + + /* signal strength */ + if (status & FE_HAS_SIGNAL) { + ret = cx24120_read_signal_strength(fe, &u16tmp); + if (ret != 0) + return; + + c->strength.stat[0].scale = FE_SCALE_RELATIVE; + c->strength.stat[0].uvalue = u16tmp; + } else { + c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + } + + /* FIXME: add CNR */ + + /* FIXME: add UCB/BER */ +} + static void cx24120_set_clock_ratios(struct dvb_frontend *fe); /* Read current tuning status */ @@ -643,6 +669,8 @@ static int cx24120_read_status(struct dvb_frontend *fe, fe_status_t *status) * Other cx241xx drivers have this slightly * different */ + cx24120_get_stats(state, *status); + /* Set the clock once tuned in */ if (state->need_clock_set && *status & FE_HAS_LOCK) { /* Set clock ratios */ -- cgit v1.2.3-59-g8ed1b From d3cf06bbe3088e0b6ede1cc0a91ff9b60d837be9 Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Tue, 5 May 2015 17:10:13 -0300 Subject: [media] cx24120: Enable DVBv5 signal strength stats Previous patch added in collection, this patch enables them by signalling they are available. Signed-off-by: Jemma Denson Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index ff16611b5eb4..57634c618d63 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -1176,6 +1176,7 @@ static int cx24120_set_vco(struct cx24120_state *state) int cx24120_init(struct dvb_frontend *fe) { const struct firmware *fw; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct cx24120_state *state = fe->demodulator_priv; struct cx24120_cmd cmd; u8 ret, ret_EA, reg1; @@ -1361,6 +1362,10 @@ int cx24120_init(struct dvb_frontend *fe) } info("FW version %i.%i.%i.%i\n", vers[0], vers[1], vers[2], vers[3]); + /* init stats here in order signal app which stats are supported */ + c->strength.len = 1; + c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + state->cold_init = 1; return 0; } -- cgit v1.2.3-59-g8ed1b From 1462612cb3172068c3f4dca1778e5fb115191c70 Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Tue, 5 May 2015 17:18:11 -0300 Subject: [media] cx24120: Remove additional calls to read_status get_frontend was making a call to read_status, which is being called periodically anyway. Have read_status store fe_status in the state struct instead and use that within get_frontend. Signed-off-by: Jemma Denson Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index 57634c618d63..dfa2b6de481c 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -143,6 +143,8 @@ struct cx24120_state { /* current and next tuning parameters */ struct cx24120_tuning dcur; struct cx24120_tuning dnxt; + + fe_status_t fe_status; }; /* Command message to firmware */ @@ -615,7 +617,7 @@ static int cx24120_send_diseqc_msg(struct dvb_frontend *fe, return -ETIMEDOUT; } -static void cx24120_get_stats(struct cx24120_state *state, fe_status_t status) +static void cx24120_get_stats(struct cx24120_state *state) { struct dvb_frontend *fe = &state->frontend; struct dtv_frontend_properties *c = &fe->dtv_property_cache; @@ -625,7 +627,7 @@ static void cx24120_get_stats(struct cx24120_state *state, fe_status_t status) dev_dbg(&state->i2c->dev, "%s()\n", __func__); /* signal strength */ - if (status & FE_HAS_SIGNAL) { + if (state->fe_status & FE_HAS_SIGNAL) { ret = cx24120_read_signal_strength(fe, &u16tmp); if (ret != 0) return; @@ -669,7 +671,8 @@ static int cx24120_read_status(struct dvb_frontend *fe, fe_status_t *status) * Other cx241xx drivers have this slightly * different */ - cx24120_get_stats(state, *status); + state->fe_status = *status; + cx24120_get_stats(state); /* Set the clock once tuned in */ if (state->need_clock_set && *status & FE_HAS_LOCK) { @@ -1405,13 +1408,11 @@ static int cx24120_get_frontend(struct dvb_frontend *fe) struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct cx24120_state *state = fe->demodulator_priv; u8 freq1, freq2, freq3; - fe_status_t status; dev_dbg(&state->i2c->dev, "%s()", __func__); /* don't return empty data if we're not tuned in */ - cx24120_read_status(fe, &status); - if ((status & FE_HAS_LOCK) == 0) + if ((state->fe_status & FE_HAS_LOCK) == 0) return 0; /* Get frequency */ -- cgit v1.2.3-59-g8ed1b From 34ce475d3272f3645561eb67048faf5537bae621 Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Tue, 5 May 2015 17:47:55 -0300 Subject: [media] cx24120: Return DVBv3 signal strength from cache This patch changes DVBv3 signal strength to read from the cache by moving the signal strength reading routine into get_stat, and reducing read_signal_strength to just returning the cached value. Signed-off-by: Jemma Denson Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 50 +++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 23 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index dfa2b6de481c..eecfe2284c91 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -422,28 +422,14 @@ static int cx24120_read_signal_strength(struct dvb_frontend *fe, u16 *signal_strength) { struct cx24120_state *state = fe->demodulator_priv; - struct cx24120_cmd cmd; - int ret, sigstr_h, sigstr_l; - - cmd.id = CMD_READ_SNR; - cmd.len = 1; - cmd.arg[0] = 0x00; - - ret = cx24120_message_send(state, &cmd); - if (ret != 0) { - err("error reading signal strength\n"); - return -EREMOTEIO; - } + struct dtv_frontend_properties *c = &fe->dtv_property_cache; - /* raw */ - sigstr_h = (cx24120_readreg(state, CX24120_REG_SIGSTR_H) >> 6) << 8; - sigstr_l = cx24120_readreg(state, CX24120_REG_SIGSTR_L); - dev_dbg(&state->i2c->dev, "%s: Signal strength from firmware= 0x%x\n", - __func__, (sigstr_h | sigstr_l)); + if (c->strength.stat[0].scale != FE_SCALE_RELATIVE) + *signal_strength = 0; + else + *signal_strength = c->strength.stat[0].uvalue; - /* cooked */ - *signal_strength = ((sigstr_h | sigstr_l) << 5) & 0x0000ffff; - dev_dbg(&state->i2c->dev, "%s: Signal strength= 0x%x\n", + dev_dbg(&state->i2c->dev, "%s: Signal strength from cache: 0x%x\n", __func__, *signal_strength); return 0; @@ -621,16 +607,34 @@ static void cx24120_get_stats(struct cx24120_state *state) { struct dvb_frontend *fe = &state->frontend; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int ret; + struct cx24120_cmd cmd; + int ret, sigstr_h, sigstr_l; u16 u16tmp; dev_dbg(&state->i2c->dev, "%s()\n", __func__); /* signal strength */ if (state->fe_status & FE_HAS_SIGNAL) { - ret = cx24120_read_signal_strength(fe, &u16tmp); - if (ret != 0) + cmd.id = CMD_READ_SNR; + cmd.len = 1; + cmd.arg[0] = 0x00; + + ret = cx24120_message_send(state, &cmd); + if (ret != 0) { + err("error reading signal strength\n"); return; + } + + /* raw */ + sigstr_h = (cx24120_readreg(state, CX24120_REG_SIGSTR_H) >> 6) << 8; + sigstr_l = cx24120_readreg(state, CX24120_REG_SIGSTR_L); + dev_dbg(&state->i2c->dev, "%s: Signal strength from firmware= 0x%x\n", + __func__, (sigstr_h | sigstr_l)); + + /* cooked */ + u16tmp = ((sigstr_h | sigstr_l) << 5) & 0x0000ffff; + dev_dbg(&state->i2c->dev, "%s: Signal strength= 0x%x\n", + __func__, u16tmp); c->strength.stat[0].scale = FE_SCALE_RELATIVE; c->strength.stat[0].uvalue = u16tmp; -- cgit v1.2.3-59-g8ed1b From b0cdf1a16f4058ac1c6c595455f276c5e3c54db3 Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Tue, 5 May 2015 18:09:45 -0300 Subject: [media] cx24120: Improve cooked signal strength value Algorithm copied from cx24117.c - it seems to work. Showing 95% on a signal I know to be somewhere around 74dBuV. [mchehab@osg.samsung.net: merged two patches, to avoid breaking compilation] Signed-off-by: Jemma Denson Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index eecfe2284c91..acdda036fe13 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -608,8 +608,8 @@ static void cx24120_get_stats(struct cx24120_state *state) struct dvb_frontend *fe = &state->frontend; struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct cx24120_cmd cmd; - int ret, sigstr_h, sigstr_l; - u16 u16tmp; + int ret; + u16 sig; dev_dbg(&state->i2c->dev, "%s()\n", __func__); @@ -626,18 +626,18 @@ static void cx24120_get_stats(struct cx24120_state *state) } /* raw */ - sigstr_h = (cx24120_readreg(state, CX24120_REG_SIGSTR_H) >> 6) << 8; - sigstr_l = cx24120_readreg(state, CX24120_REG_SIGSTR_L); - dev_dbg(&state->i2c->dev, "%s: Signal strength from firmware= 0x%x\n", - __func__, (sigstr_h | sigstr_l)); + sig = cx24120_readreg(state, CX24120_REG_SIGSTR_H) >> 6; + sig = sig << 8; + sig |= cx24120_readreg(state, CX24120_REG_SIGSTR_L); + dev_dbg(&state->i2c->dev, + "%s: Signal strength from firmware= 0x%x\n", + __func__, sig); /* cooked */ - u16tmp = ((sigstr_h | sigstr_l) << 5) & 0x0000ffff; - dev_dbg(&state->i2c->dev, "%s: Signal strength= 0x%x\n", - __func__, u16tmp); + sig = -100 * sig + 94324; c->strength.stat[0].scale = FE_SCALE_RELATIVE; - c->strength.stat[0].uvalue = u16tmp; + c->strength.stat[0].uvalue = sig; } else { c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; } -- cgit v1.2.3-59-g8ed1b From fbdbab72969b48367dcf5f0d42112b6f78fae794 Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Tue, 5 May 2015 18:31:10 -0300 Subject: [media] cx24120: More coding style fixes Signed-off-by: Jemma Denson Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index acdda036fe13..2876b8aae90a 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -160,7 +160,8 @@ static int cx24120_readreg(struct cx24120_state *state, u8 reg) int ret; u8 buf = 0; struct i2c_msg msg[] = { - { .addr = state->config->i2c_addr, + { + .addr = state->config->i2c_addr, .flags = 0, .len = 1, .buf = ® @@ -488,7 +489,8 @@ static int cx24120_diseqc_send_burst(struct dvb_frontend *fe, struct cx24120_state *state = fe->demodulator_priv; struct cx24120_cmd cmd; - /* Yes, cmd.len is set to zero. The old driver + /* + * Yes, cmd.len is set to zero. The old driver * didn't specify any len, but also had a * memset 0 before every use of the cmd struct * which would have set it to zero. @@ -671,9 +673,11 @@ static int cx24120_read_status(struct dvb_frontend *fe, fe_status_t *status) if (lock & CX24120_HAS_LOCK) *status |= FE_HAS_LOCK; - /* TODO: is FE_HAS_SYNC in the right place? + /* + * TODO: is FE_HAS_SYNC in the right place? * Other cx241xx drivers have this slightly - * different */ + * different + */ state->fe_status = *status; cx24120_get_stats(state); @@ -695,7 +699,8 @@ static int cx24120_read_status(struct dvb_frontend *fe, fe_status_t *status) return 0; } -/* FEC & modulation lookup table +/* + * FEC & modulation lookup table * Used for decoding the REG_FECMODE register * once tuned in. */ @@ -775,14 +780,15 @@ static int cx24120_get_fec(struct dvb_frontend *fe) return 0; } -/* Clock ratios lookup table +/* + * Clock ratios lookup table * * Values obtained from much larger table in old driver * which had numerous entries which would never match. * * There's probably some way of calculating these but I * can't determine the pattern -*/ + */ static struct cx24120_clock_ratios_table { fe_delivery_system_t delsys; fe_pilot_t pilot; @@ -935,7 +941,7 @@ static struct cx24120_modfec_table { fe_code_rate_t fec; u8 val; } modfec_table[] = { -/*delsys mod fec val */ + /*delsys mod fec val */ { SYS_DVBS, QPSK, FEC_1_2, 0x2e }, { SYS_DVBS, QPSK, FEC_2_3, 0x2f }, { SYS_DVBS, QPSK, FEC_3_4, 0x30 }, -- cgit v1.2.3-59-g8ed1b From 7c95e25e38c03a64659343ddbb64fdbb5ff2e25a Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Tue, 5 May 2015 18:33:27 -0300 Subject: [media] cx24120: Fix disecq_send_burst command Previous version of this driver had a memset before every call to cmd. This meant the default value of cmd.arg[1] was zero unless burst is set. Make sure it remains zero. Also fe_sec_mini_cmd_t is an enum, so test against it. Signed-off-by: Jemma Denson Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index 2876b8aae90a..2fa196a889d7 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -499,8 +499,7 @@ static int cx24120_diseqc_send_burst(struct dvb_frontend *fe, cmd.id = CMD_DISEQC_BURST; cmd.len = 0; cmd.arg[0] = 0x00; - if (burst) - cmd.arg[1] = 0x01; + cmd.arg[1] = (burst == SEC_MINI_B) ? 0x01 : 0x00; dev_dbg(&state->i2c->dev, "%s: burst sent.\n", __func__); -- cgit v1.2.3-59-g8ed1b From 3b5eb504fe7efc0637f43f6a641ee6e163800f98 Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Fri, 8 May 2015 15:52:45 -0300 Subject: [media] cx24120: Move CNR to DVBv5 stats Better to report CNR via DVBv5 stats, as scale can be used. Signed-off-by: Jemma Denson Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index 2fa196a889d7..9009a4f9a1fc 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -320,11 +320,12 @@ static int cx24120_test_rom(struct cx24120_state *state) static int cx24120_read_snr(struct dvb_frontend *fe, u16 *snr) { - struct cx24120_state *state = fe->demodulator_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; - *snr = (cx24120_readreg(state, CX24120_REG_QUALITY_H) << 8) | - (cx24120_readreg(state, CX24120_REG_QUALITY_L)); - dev_dbg(&state->i2c->dev, "%s: read SNR index = %d\n", __func__, *snr); + if (c->cnr.stat[0].scale != FE_SCALE_DECIBEL) + *snr = 0; + else + *snr = div_s64(c->cnr.stat[0].svalue, 100); return 0; } @@ -609,7 +610,7 @@ static void cx24120_get_stats(struct cx24120_state *state) struct dvb_frontend *fe = &state->frontend; struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct cx24120_cmd cmd; - int ret; + int ret, cnr; u16 sig; dev_dbg(&state->i2c->dev, "%s()\n", __func__); @@ -643,7 +644,21 @@ static void cx24120_get_stats(struct cx24120_state *state) c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; } - /* FIXME: add CNR */ + /* CNR */ + if (state->fe_status & FE_HAS_VITERBI) { + cnr = cx24120_readreg(state, CX24120_REG_QUALITY_H) << 8; + cnr |= cx24120_readreg(state, CX24120_REG_QUALITY_L); + dev_dbg(&state->i2c->dev, "%s: read SNR index = %d\n", + __func__, cnr); + + /* guessed - seems about right */ + cnr = cnr * 100; + + c->cnr.stat[0].scale = FE_SCALE_DECIBEL; + c->cnr.stat[0].svalue = cnr; + } else { + c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + } /* FIXME: add UCB/BER */ } @@ -1377,6 +1392,8 @@ int cx24120_init(struct dvb_frontend *fe) /* init stats here in order signal app which stats are supported */ c->strength.len = 1; c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->cnr.len = 1; + c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; state->cold_init = 1; return 0; -- cgit v1.2.3-59-g8ed1b From 2f3f07fbe28c245bc4a86c735664d57a6e3b197d Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Fri, 8 May 2015 16:34:31 -0300 Subject: [media] cx24120: Tidy up calls to dev_dbg Remove __func__ from calls to dev_dbg as dynamic debug can add in the function name anyway. Remove debug call in dvbv3 read_signal_strength as userspace has this value anyway. Reword some strings to make them simpler / more obvious. Signed-off-by: Jemma Denson Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 138 +++++++++++++--------------------- 1 file changed, 53 insertions(+), 85 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index 9009a4f9a1fc..dc5c69ce166b 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -179,8 +179,7 @@ static int cx24120_readreg(struct cx24120_state *state, u8 reg) return ret; } - dev_dbg(&state->i2c->dev, "%s: reg=0x%02x; data=0x%02x\n", - __func__, reg, buf); + dev_dbg(&state->i2c->dev, "reg=0x%02x; data=0x%02x\n", reg, buf); return buf; } @@ -204,8 +203,7 @@ static int cx24120_writereg(struct cx24120_state *state, u8 reg, u8 data) return ret; } - dev_dbg(&state->i2c->dev, "%s: reg=0x%02x; data=0x%02x\n", - __func__, reg, data); + dev_dbg(&state->i2c->dev, "reg=0x%02x; data=0x%02x\n", reg, data); return 0; } @@ -246,9 +244,8 @@ static int cx24120_writeregs(struct cx24120_state *state, goto out; } - dev_dbg(&state->i2c->dev, - "%s: reg=0x%02x; data=%*ph\n", - __func__, reg, msg.len - 1, msg.buf + 1); + dev_dbg(&state->i2c->dev, "reg=0x%02x; data=%*ph\n", + reg, msg.len - 1, msg.buf + 1); } ret = 0; @@ -338,7 +335,7 @@ static int cx24120_read_ber(struct dvb_frontend *fe, u32 *ber) (cx24120_readreg(state, CX24120_REG_BER_HL) << 16) | (cx24120_readreg(state, CX24120_REG_BER_LH) << 8) | cx24120_readreg(state, CX24120_REG_BER_LL); - dev_dbg(&state->i2c->dev, "%s: read BER index = %d\n", __func__, *ber); + dev_dbg(&state->i2c->dev, "read BER index = %d\n", *ber); return 0; } @@ -389,8 +386,7 @@ static int cx24120_message_send(struct cx24120_state *state, return -EREMOTEIO; } } - dev_dbg(&state->i2c->dev, "%s: Successfully send message 0x%02x\n", - __func__, cmd->id); + dev_dbg(&state->i2c->dev, "sent message 0x%02x\n", cmd->id); return 0; } @@ -423,7 +419,6 @@ static int cx24120_message_sendrcv(struct cx24120_state *state, static int cx24120_read_signal_strength(struct dvb_frontend *fe, u16 *signal_strength) { - struct cx24120_state *state = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; if (c->strength.stat[0].scale != FE_SCALE_RELATIVE) @@ -431,9 +426,6 @@ static int cx24120_read_signal_strength(struct dvb_frontend *fe, else *signal_strength = c->strength.stat[0].uvalue; - dev_dbg(&state->i2c->dev, "%s: Signal strength from cache: 0x%x\n", - __func__, *signal_strength); - return 0; } @@ -452,15 +444,14 @@ static int cx24120_msg_mpeg_output_global_config(struct cx24120_state *state, ret = cx24120_message_send(state, &cmd); if (ret != 0) { - dev_dbg(&state->i2c->dev, - "%s: Failed to set MPEG output to %s\n", - __func__, enable ? "enabled" : "disabled"); + dev_dbg(&state->i2c->dev, "failed to %s MPEG output\n", + enable ? "enable" : "disable"); return ret; } state->mpeg_enabled = enable; - dev_dbg(&state->i2c->dev, "%s: MPEG output %s\n", - __func__, enable ? "enabled" : "disabled"); + dev_dbg(&state->i2c->dev, "MPEG output %s\n", + enable ? "enabled" : "disabled"); return 0; } @@ -490,6 +481,8 @@ static int cx24120_diseqc_send_burst(struct dvb_frontend *fe, struct cx24120_state *state = fe->demodulator_priv; struct cx24120_cmd cmd; + dev_dbg(&state->i2c->dev, "\n"); + /* * Yes, cmd.len is set to zero. The old driver * didn't specify any len, but also had a @@ -502,8 +495,6 @@ static int cx24120_diseqc_send_burst(struct dvb_frontend *fe, cmd.arg[0] = 0x00; cmd.arg[1] = (burst == SEC_MINI_B) ? 0x01 : 0x00; - dev_dbg(&state->i2c->dev, "%s: burst sent.\n", __func__); - return cx24120_message_send(state, &cmd); } @@ -512,7 +503,7 @@ static int cx24120_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) struct cx24120_state *state = fe->demodulator_priv; struct cx24120_cmd cmd; - dev_dbg(&state->i2c->dev, "%s(%d)\n", __func__, tone); + dev_dbg(&state->i2c->dev, "(%d)\n", tone); if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) { err("Invalid tone=%d\n", tone); @@ -535,7 +526,7 @@ static int cx24120_set_voltage(struct dvb_frontend *fe, struct cx24120_state *state = fe->demodulator_priv; struct cx24120_cmd cmd; - dev_dbg(&state->i2c->dev, "%s(%d)\n", __func__, voltage); + dev_dbg(&state->i2c->dev, "(%d)\n", voltage); cmd.id = CMD_SETVOLTAGE; cmd.len = 2; @@ -552,7 +543,7 @@ static int cx24120_send_diseqc_msg(struct dvb_frontend *fe, struct cx24120_cmd cmd; int back_count; - dev_dbg(&state->i2c->dev, "%s()\n", __func__); + dev_dbg(&state->i2c->dev, "\n"); cmd.id = CMD_DISEQC_MSG1; cmd.len = 11; @@ -592,9 +583,7 @@ static int cx24120_send_diseqc_msg(struct dvb_frontend *fe, back_count = 500; do { if (!(cx24120_readreg(state, 0x93) & 0x01)) { - dev_dbg(&state->i2c->dev, - "%s: diseqc sequence sent success\n", - __func__); + dev_dbg(&state->i2c->dev, "diseqc sequence sent\n"); return 0; } msleep(20); @@ -613,7 +602,7 @@ static void cx24120_get_stats(struct cx24120_state *state) int ret, cnr; u16 sig; - dev_dbg(&state->i2c->dev, "%s()\n", __func__); + dev_dbg(&state->i2c->dev, "\n"); /* signal strength */ if (state->fe_status & FE_HAS_SIGNAL) { @@ -632,8 +621,7 @@ static void cx24120_get_stats(struct cx24120_state *state) sig = sig << 8; sig |= cx24120_readreg(state, CX24120_REG_SIGSTR_L); dev_dbg(&state->i2c->dev, - "%s: Signal strength from firmware= 0x%x\n", - __func__, sig); + "signal strength from firmware = 0x%x\n", sig); /* cooked */ sig = -100 * sig + 94324; @@ -648,8 +636,7 @@ static void cx24120_get_stats(struct cx24120_state *state) if (state->fe_status & FE_HAS_VITERBI) { cnr = cx24120_readreg(state, CX24120_REG_QUALITY_H) << 8; cnr |= cx24120_readreg(state, CX24120_REG_QUALITY_L); - dev_dbg(&state->i2c->dev, "%s: read SNR index = %d\n", - __func__, cnr); + dev_dbg(&state->i2c->dev, "read SNR index = %d\n", cnr); /* guessed - seems about right */ cnr = cnr * 100; @@ -673,8 +660,7 @@ static int cx24120_read_status(struct dvb_frontend *fe, fe_status_t *status) lock = cx24120_readreg(state, CX24120_REG_STATUS); - dev_dbg(&state->i2c->dev, "%s() status = 0x%02x\n", - __func__, lock); + dev_dbg(&state->i2c->dev, "status = 0x%02x\n", lock); *status = 0; @@ -759,12 +745,10 @@ static int cx24120_get_fec(struct dvb_frontend *fe) int ret; int fec; - dev_dbg(&state->i2c->dev, "%s()\n", __func__); - ret = cx24120_readreg(state, CX24120_REG_FECMODE); fec = ret & 0x3f; /* Lower 6 bits */ - dev_dbg(&state->i2c->dev, "%s: Get FEC: %d\n", __func__, fec); + dev_dbg(&state->i2c->dev, "raw fec = %d\n", fec); for (idx = 0; idx < ARRAY_SIZE(modfec_lookup_table); idx++) { if (modfec_lookup_table[idx].delsys != state->dcur.delsys) @@ -776,8 +760,7 @@ static int cx24120_get_fec(struct dvb_frontend *fe) } if (idx >= ARRAY_SIZE(modfec_lookup_table)) { - dev_dbg(&state->i2c->dev, "%s: Couldn't find fec!\n", - __func__); + dev_dbg(&state->i2c->dev, "couldn't find fec!\n"); return -EINVAL; } @@ -786,9 +769,7 @@ static int cx24120_get_fec(struct dvb_frontend *fe) c->fec_inner = modfec_lookup_table[idx].fec; c->pilot = (ret & 0x80) ? PILOT_ON : PILOT_OFF; - dev_dbg(&state->i2c->dev, - "%s: mod(%d), fec(%d), pilot(%d)\n", - __func__, + dev_dbg(&state->i2c->dev, "mod(%d), fec(%d), pilot(%d)\n", c->modulation, c->fec_inner, c->pilot); return 0; @@ -889,9 +870,7 @@ static void cx24120_set_clock_ratios(struct dvb_frontend *fe) return; /* in cmd[0]-[5] - result */ - dev_dbg(&state->i2c->dev, - "%s: m=%d, n=%d; idx: %d m=%d, n=%d, rate=%d\n", - __func__, + dev_dbg(&state->i2c->dev, "m=%d, n=%d; idx: %d m=%d, n=%d, rate=%d\n", cmd.arg[2] | (cmd.arg[1] << 8) | (cmd.arg[0] << 16), cmd.arg[5] | (cmd.arg[4] << 8) | (cmd.arg[3] << 16), idx, @@ -920,7 +899,7 @@ static void cx24120_set_clock_ratios(struct dvb_frontend *fe) static int cx24120_set_inversion(struct cx24120_state *state, fe_spectral_inversion_t inversion) { - dev_dbg(&state->i2c->dev, "%s(%d)\n", __func__, inversion); + dev_dbg(&state->i2c->dev, "(%d)\n", inversion); switch (inversion) { case INVERSION_OFF: @@ -975,7 +954,7 @@ static int cx24120_set_fec(struct cx24120_state *state, fe_modulation_t mod, { int idx; - dev_dbg(&state->i2c->dev, "%s(0x%02x,0x%02x)\n", __func__, mod, fec); + dev_dbg(&state->i2c->dev, "(0x%02x,0x%02x)\n", mod, fec); state->dnxt.fec = fec; @@ -1010,7 +989,7 @@ static int cx24120_set_fec(struct cx24120_state *state, fe_modulation_t mod, /* Set pilot */ static int cx24120_set_pilot(struct cx24120_state *state, fe_pilot_t pilot) { - dev_dbg(&state->i2c->dev, "%s(%d)\n", __func__, pilot); + dev_dbg(&state->i2c->dev, "(%d)\n", pilot); /* Pilot only valid in DVBS2 */ if (state->dnxt.delsys != SYS_DVBS2) { @@ -1036,8 +1015,7 @@ static int cx24120_set_pilot(struct cx24120_state *state, fe_pilot_t pilot) /* Set symbol rate */ static int cx24120_set_symbolrate(struct cx24120_state *state, u32 rate) { - dev_dbg(&state->i2c->dev, "%s(%d)\n", - __func__, rate); + dev_dbg(&state->i2c->dev, "(%d)\n", rate); state->dnxt.symbol_rate = rate; @@ -1070,17 +1048,15 @@ static int cx24120_set_frontend(struct dvb_frontend *fe) switch (c->delivery_system) { case SYS_DVBS2: - dev_dbg(&state->i2c->dev, "%s() DVB-S2\n", - __func__); + dev_dbg(&state->i2c->dev, "DVB-S2\n"); break; case SYS_DVBS: - dev_dbg(&state->i2c->dev, "%s() DVB-S\n", - __func__); + dev_dbg(&state->i2c->dev, "DVB-S\n"); break; default: dev_dbg(&state->i2c->dev, - "%s() Delivery system(%d) not supported\n", - __func__, c->delivery_system); + "delivery system(%d) not supported\n", + c->delivery_system); ret = -EINVAL; break; } @@ -1110,23 +1086,23 @@ static int cx24120_set_frontend(struct dvb_frontend *fe) cx24120_clone_params(fe); dev_dbg(&state->i2c->dev, - "%s: delsys = %d\n", __func__, state->dcur.delsys); + "delsys = %d\n", state->dcur.delsys); dev_dbg(&state->i2c->dev, - "%s: modulation = %d\n", __func__, state->dcur.modulation); + "modulation = %d\n", state->dcur.modulation); dev_dbg(&state->i2c->dev, - "%s: frequency = %d\n", __func__, state->dcur.frequency); + "frequency = %d\n", state->dcur.frequency); dev_dbg(&state->i2c->dev, - "%s: pilot = %d (val = 0x%02x)\n", __func__, + "pilot = %d (val = 0x%02x)\n", state->dcur.pilot, state->dcur.pilot_val); dev_dbg(&state->i2c->dev, - "%s: symbol_rate = %d (clkdiv/ratediv = 0x%02x/0x%02x)\n", - __func__, state->dcur.symbol_rate, + "symbol_rate = %d (clkdiv/ratediv = 0x%02x/0x%02x)\n", + state->dcur.symbol_rate, state->dcur.clkdiv, state->dcur.ratediv); dev_dbg(&state->i2c->dev, - "%s: FEC = %d (mask/val = 0x%02x/0x%02x)\n", __func__, + "FEC = %d (mask/val = 0x%02x/0x%02x)\n", state->dcur.fec, state->dcur.fec_mask, state->dcur.fec_val); dev_dbg(&state->i2c->dev, - "%s: Inversion = %d (val = 0x%02x)\n", __func__, + "Inversion = %d (val = 0x%02x)\n", state->dcur.inversion, state->dcur.inversion_val); /* Flag that clock needs to be set after tune */ @@ -1178,9 +1154,8 @@ static int cx24120_set_vco(struct cx24120_state *state) vco = nxtal_khz * 10; inv_vco = DIV_ROUND_CLOSEST_ULL(0x400000000ULL, vco); - dev_dbg(&state->i2c->dev, - "%s: xtal=%d, vco=%d, inv_vco=%lld\n", - __func__, xtal_khz, vco, inv_vco); + dev_dbg(&state->i2c->dev, "xtal=%d, vco=%d, inv_vco=%lld\n", + xtal_khz, vco, inv_vco); cmd.id = CMD_VCO_SET; cmd.len = 12; @@ -1250,9 +1225,8 @@ int cx24120_init(struct dvb_frontend *fe) ret = cx24120_writereg(state, 0xe4, 0x03); ret = cx24120_writereg(state, 0xeb, 0x0a); - dev_dbg(&state->i2c->dev, - "%s: Requesting firmware (%s) to download...\n", - __func__, CX24120_FIRMWARE); + dev_dbg(&state->i2c->dev, "requesting firmware (%s) to download...\n", + CX24120_FIRMWARE); ret = state->config->request_firmware(fe, &fw, CX24120_FIRMWARE); if (ret) { @@ -1262,8 +1236,7 @@ int cx24120_init(struct dvb_frontend *fe) } dev_dbg(&state->i2c->dev, - "%s: Firmware found, size %d bytes (%02x %02x .. %02x %02x)\n", - __func__, + "Firmware found, size %d bytes (%02x %02x .. %02x %02x)\n", (int)fw->size, /* firmware_size in bytes */ fw->data[0], /* fw 1st byte */ fw->data[1], /* fw 2d byte */ @@ -1292,9 +1265,7 @@ int cx24120_init(struct dvb_frontend *fe) /* Check final byte matches final byte of firmware */ ret = cx24120_readreg(state, 0xe1); if (ret == fw->data[fw->size - 1]) { - dev_dbg(&state->i2c->dev, - "%s: Firmware uploaded successfully\n", - __func__); + dev_dbg(&state->i2c->dev, "Firmware uploaded successfully\n"); reset_result = 0; } else { err("Firmware upload failed. Last byte returned=0x%x\n", ret); @@ -1347,14 +1318,12 @@ int cx24120_init(struct dvb_frontend *fe) ret = cx24120_readreg(state, 0xba); if (ret > 3) { - dev_dbg(&state->i2c->dev, "%s: Reset-readreg 0xba: %x\n", - __func__, ret); + dev_dbg(&state->i2c->dev, "Reset-readreg 0xba: %x\n", ret); err("Error initialising tuner!\n"); return -EREMOTEIO; } - dev_dbg(&state->i2c->dev, "%s: Tuner initialised correctly.\n", - __func__); + dev_dbg(&state->i2c->dev, "Tuner initialised correctly.\n"); /* Initialise mpeg outputs */ ret = cx24120_writereg(state, 0xeb, 0x0a); @@ -1406,7 +1375,7 @@ static int cx24120_tune(struct dvb_frontend *fe, bool re_tune, struct cx24120_state *state = fe->demodulator_priv; int ret; - dev_dbg(&state->i2c->dev, "%s(%d)\n", __func__, re_tune); + dev_dbg(&state->i2c->dev, "(%d)\n", re_tune); /* TODO: Do we need to set delay? */ @@ -1435,7 +1404,7 @@ static int cx24120_get_frontend(struct dvb_frontend *fe) struct cx24120_state *state = fe->demodulator_priv; u8 freq1, freq2, freq3; - dev_dbg(&state->i2c->dev, "%s()", __func__); + dev_dbg(&state->i2c->dev, "\n"); /* don't return empty data if we're not tuned in */ if ((state->fe_status & FE_HAS_LOCK) == 0) @@ -1446,8 +1415,7 @@ static int cx24120_get_frontend(struct dvb_frontend *fe) freq2 = cx24120_readreg(state, CX24120_REG_FREQ2); freq3 = cx24120_readreg(state, CX24120_REG_FREQ3); c->frequency = (freq3 << 16) | (freq2 << 8) | freq1; - dev_dbg(&state->i2c->dev, "%s frequency = %d\n", __func__, - c->frequency); + dev_dbg(&state->i2c->dev, "frequency = %d\n", c->frequency); /* Get modulation, fec, pilot */ cx24120_get_fec(fe); @@ -1459,7 +1427,7 @@ static void cx24120_release(struct dvb_frontend *fe) { struct cx24120_state *state = fe->demodulator_priv; - dev_dbg(&state->i2c->dev, "%s: Clear state structure\n", __func__); + dev_dbg(&state->i2c->dev, "Clear state structure\n"); kfree(state); } @@ -1470,7 +1438,7 @@ static int cx24120_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) *ucblocks = (cx24120_readreg(state, CX24120_REG_UCB_H) << 8) | cx24120_readreg(state, CX24120_REG_UCB_L); - dev_dbg(&state->i2c->dev, "%s: Blocks = %d\n", __func__, *ucblocks); + dev_dbg(&state->i2c->dev, "ucblocks = %d\n", *ucblocks); return 0; } -- cgit v1.2.3-59-g8ed1b From 92443cdb2362557e879ddcea10cb65bafe47153f Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Fri, 8 May 2015 16:57:56 -0300 Subject: [media] cx24120: Remove unneccesary assignments in cx24120_init Probably a remnant of this driver being reverse engineered, cx24120_init assigned ret on each call to writereg - they're not used for anything so remove them to clear up the codebase. Signed-off-by: Jemma Denson Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 74 +++++++++++++++++------------------ 1 file changed, 37 insertions(+), 37 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index dc5c69ce166b..0db03f301756 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -1191,39 +1191,39 @@ int cx24120_init(struct dvb_frontend *fe) return 0; /* ???? */ - ret = cx24120_writereg(state, 0xea, 0x00); - ret = cx24120_test_rom(state); + cx24120_writereg(state, 0xea, 0x00); + cx24120_test_rom(state); ret = cx24120_readreg(state, 0xfb) & 0xfe; - ret = cx24120_writereg(state, 0xfb, ret); + cx24120_writereg(state, 0xfb, ret); ret = cx24120_readreg(state, 0xfc) & 0xfe; - ret = cx24120_writereg(state, 0xfc, ret); - ret = cx24120_writereg(state, 0xc3, 0x04); - ret = cx24120_writereg(state, 0xc4, 0x04); - ret = cx24120_writereg(state, 0xce, 0x00); - ret = cx24120_writereg(state, 0xcf, 0x00); + cx24120_writereg(state, 0xfc, ret); + cx24120_writereg(state, 0xc3, 0x04); + cx24120_writereg(state, 0xc4, 0x04); + cx24120_writereg(state, 0xce, 0x00); + cx24120_writereg(state, 0xcf, 0x00); ret_EA = cx24120_readreg(state, 0xea) & 0xfe; - ret = cx24120_writereg(state, 0xea, ret_EA); - ret = cx24120_writereg(state, 0xeb, 0x0c); - ret = cx24120_writereg(state, 0xec, 0x06); - ret = cx24120_writereg(state, 0xed, 0x05); - ret = cx24120_writereg(state, 0xee, 0x03); - ret = cx24120_writereg(state, 0xef, 0x05); - ret = cx24120_writereg(state, 0xf3, 0x03); - ret = cx24120_writereg(state, 0xf4, 0x44); + cx24120_writereg(state, 0xea, ret_EA); + cx24120_writereg(state, 0xeb, 0x0c); + cx24120_writereg(state, 0xec, 0x06); + cx24120_writereg(state, 0xed, 0x05); + cx24120_writereg(state, 0xee, 0x03); + cx24120_writereg(state, 0xef, 0x05); + cx24120_writereg(state, 0xf3, 0x03); + cx24120_writereg(state, 0xf4, 0x44); for (reg1 = 0xf0; reg1 < 0xf3; reg1++) { cx24120_writereg(state, reg1, 0x04); cx24120_writereg(state, reg1 - 10, 0x02); } - ret = cx24120_writereg(state, 0xea, (ret_EA | 0x01)); + cx24120_writereg(state, 0xea, (ret_EA | 0x01)); for (reg1 = 0xc5; reg1 < 0xcb; reg1 += 2) { - ret = cx24120_writereg(state, reg1, 0x00); - ret = cx24120_writereg(state, reg1 + 1, 0x00); + cx24120_writereg(state, reg1, 0x00); + cx24120_writereg(state, reg1 + 1, 0x00); } - ret = cx24120_writereg(state, 0xe4, 0x03); - ret = cx24120_writereg(state, 0xeb, 0x0a); + cx24120_writereg(state, 0xe4, 0x03); + cx24120_writereg(state, 0xeb, 0x0a); dev_dbg(&state->i2c->dev, "requesting firmware (%s) to download...\n", CX24120_FIRMWARE); @@ -1243,23 +1243,23 @@ int cx24120_init(struct dvb_frontend *fe) fw->data[fw->size - 2], /* fw before last byte */ fw->data[fw->size - 1]); /* fw last byte */ - ret = cx24120_test_rom(state); + cx24120_test_rom(state); ret = cx24120_readreg(state, 0xfb) & 0xfe; - ret = cx24120_writereg(state, 0xfb, ret); - ret = cx24120_writereg(state, 0xe0, 0x76); - ret = cx24120_writereg(state, 0xf7, 0x81); - ret = cx24120_writereg(state, 0xf8, 0x00); - ret = cx24120_writereg(state, 0xf9, 0x00); - ret = cx24120_writeregs(state, 0xfa, fw->data, (fw->size - 1), 0x00); - ret = cx24120_writereg(state, 0xf7, 0xc0); - ret = cx24120_writereg(state, 0xe0, 0x00); + cx24120_writereg(state, 0xfb, ret); + cx24120_writereg(state, 0xe0, 0x76); + cx24120_writereg(state, 0xf7, 0x81); + cx24120_writereg(state, 0xf8, 0x00); + cx24120_writereg(state, 0xf9, 0x00); + cx24120_writeregs(state, 0xfa, fw->data, (fw->size - 1), 0x00); + cx24120_writereg(state, 0xf7, 0xc0); + cx24120_writereg(state, 0xe0, 0x00); ret = (fw->size - 2) & 0x00ff; - ret = cx24120_writereg(state, 0xf8, ret); + cx24120_writereg(state, 0xf8, ret); ret = ((fw->size - 2) >> 8) & 0x00ff; - ret = cx24120_writereg(state, 0xf9, ret); - ret = cx24120_writereg(state, 0xf7, 0x00); - ret = cx24120_writereg(state, 0xdc, 0x00); - ret = cx24120_writereg(state, 0xdc, 0x07); + cx24120_writereg(state, 0xf9, ret); + cx24120_writereg(state, 0xf7, 0x00); + cx24120_writereg(state, 0xdc, 0x00); + cx24120_writereg(state, 0xdc, 0x07); msleep(500); /* Check final byte matches final byte of firmware */ @@ -1271,7 +1271,7 @@ int cx24120_init(struct dvb_frontend *fe) err("Firmware upload failed. Last byte returned=0x%x\n", ret); reset_result = -EREMOTEIO; } - ret = cx24120_writereg(state, 0xdc, 0x00); + cx24120_writereg(state, 0xdc, 0x00); release_firmware(fw); if (reset_result != 0) return reset_result; @@ -1326,7 +1326,7 @@ int cx24120_init(struct dvb_frontend *fe) dev_dbg(&state->i2c->dev, "Tuner initialised correctly.\n"); /* Initialise mpeg outputs */ - ret = cx24120_writereg(state, 0xeb, 0x0a); + cx24120_writereg(state, 0xeb, 0x0a); if (cx24120_msg_mpeg_output_global_config(state, 0) || cx24120_msg_mpeg_output_config(state, 0) || cx24120_msg_mpeg_output_config(state, 1) || -- cgit v1.2.3-59-g8ed1b From 1668797d176d384c5148bd903b534125eae8d377 Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Fri, 8 May 2015 17:26:34 -0300 Subject: [media] cx24120: Tidy cx24120_init Use reg instead of ret for all calls to readreg, remove ret_EA as it doesn't need to be a separate var anymore. Signed-off-by: Jemma Denson Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 36 +++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index 0db03f301756..8f195afe4ecc 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -1181,7 +1181,7 @@ int cx24120_init(struct dvb_frontend *fe) struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct cx24120_state *state = fe->demodulator_priv; struct cx24120_cmd cmd; - u8 ret, ret_EA, reg1; + u8 ret, reg, reg1; int reset_result; int i; @@ -1193,16 +1193,16 @@ int cx24120_init(struct dvb_frontend *fe) /* ???? */ cx24120_writereg(state, 0xea, 0x00); cx24120_test_rom(state); - ret = cx24120_readreg(state, 0xfb) & 0xfe; - cx24120_writereg(state, 0xfb, ret); - ret = cx24120_readreg(state, 0xfc) & 0xfe; - cx24120_writereg(state, 0xfc, ret); + reg = cx24120_readreg(state, 0xfb) & 0xfe; + cx24120_writereg(state, 0xfb, reg); + reg = cx24120_readreg(state, 0xfc) & 0xfe; + cx24120_writereg(state, 0xfc, reg); cx24120_writereg(state, 0xc3, 0x04); cx24120_writereg(state, 0xc4, 0x04); cx24120_writereg(state, 0xce, 0x00); cx24120_writereg(state, 0xcf, 0x00); - ret_EA = cx24120_readreg(state, 0xea) & 0xfe; - cx24120_writereg(state, 0xea, ret_EA); + reg = cx24120_readreg(state, 0xea) & 0xfe; + cx24120_writereg(state, 0xea, reg); cx24120_writereg(state, 0xeb, 0x0c); cx24120_writereg(state, 0xec, 0x06); cx24120_writereg(state, 0xed, 0x05); @@ -1216,7 +1216,7 @@ int cx24120_init(struct dvb_frontend *fe) cx24120_writereg(state, reg1 - 10, 0x02); } - cx24120_writereg(state, 0xea, (ret_EA | 0x01)); + cx24120_writereg(state, 0xea, (reg | 0x01)); for (reg1 = 0xc5; reg1 < 0xcb; reg1 += 2) { cx24120_writereg(state, reg1, 0x00); cx24120_writereg(state, reg1 + 1, 0x00); @@ -1244,8 +1244,8 @@ int cx24120_init(struct dvb_frontend *fe) fw->data[fw->size - 1]); /* fw last byte */ cx24120_test_rom(state); - ret = cx24120_readreg(state, 0xfb) & 0xfe; - cx24120_writereg(state, 0xfb, ret); + reg = cx24120_readreg(state, 0xfb) & 0xfe; + cx24120_writereg(state, 0xfb, reg); cx24120_writereg(state, 0xe0, 0x76); cx24120_writereg(state, 0xf7, 0x81); cx24120_writereg(state, 0xf8, 0x00); @@ -1253,18 +1253,18 @@ int cx24120_init(struct dvb_frontend *fe) cx24120_writeregs(state, 0xfa, fw->data, (fw->size - 1), 0x00); cx24120_writereg(state, 0xf7, 0xc0); cx24120_writereg(state, 0xe0, 0x00); - ret = (fw->size - 2) & 0x00ff; - cx24120_writereg(state, 0xf8, ret); - ret = ((fw->size - 2) >> 8) & 0x00ff; - cx24120_writereg(state, 0xf9, ret); + reg = (fw->size - 2) & 0x00ff; + cx24120_writereg(state, 0xf8, reg); + reg = ((fw->size - 2) >> 8) & 0x00ff; + cx24120_writereg(state, 0xf9, reg); cx24120_writereg(state, 0xf7, 0x00); cx24120_writereg(state, 0xdc, 0x00); cx24120_writereg(state, 0xdc, 0x07); msleep(500); /* Check final byte matches final byte of firmware */ - ret = cx24120_readreg(state, 0xe1); - if (ret == fw->data[fw->size - 1]) { + reg = cx24120_readreg(state, 0xe1); + if (reg == fw->data[fw->size - 1]) { dev_dbg(&state->i2c->dev, "Firmware uploaded successfully\n"); reset_result = 0; } else { @@ -1316,8 +1316,8 @@ int cx24120_init(struct dvb_frontend *fe) return -EREMOTEIO; } - ret = cx24120_readreg(state, 0xba); - if (ret > 3) { + reg = cx24120_readreg(state, 0xba); + if (reg > 3) { dev_dbg(&state->i2c->dev, "Reset-readreg 0xba: %x\n", ret); err("Error initialising tuner!\n"); return -EREMOTEIO; -- cgit v1.2.3-59-g8ed1b From 4133601c31adcbcd3affc40e1035c25787cc5cd1 Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Fri, 8 May 2015 17:36:19 -0300 Subject: [media] cx24120: More tidying in cx24120_init Remove reg1 by refactoring for loops Change ret into an int as it's only used for return values now, and remove reset_result by using ret instead. Signed-off-by: Jemma Denson Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index 8f195afe4ecc..bc8d0ebb63b6 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -1181,10 +1181,8 @@ int cx24120_init(struct dvb_frontend *fe) struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct cx24120_state *state = fe->demodulator_priv; struct cx24120_cmd cmd; - u8 ret, reg, reg1; - int reset_result; - - int i; + u8 reg; + int ret, i; unsigned char vers[4]; if (state->cold_init) @@ -1211,15 +1209,15 @@ int cx24120_init(struct dvb_frontend *fe) cx24120_writereg(state, 0xf3, 0x03); cx24120_writereg(state, 0xf4, 0x44); - for (reg1 = 0xf0; reg1 < 0xf3; reg1++) { - cx24120_writereg(state, reg1, 0x04); - cx24120_writereg(state, reg1 - 10, 0x02); + for (i = 0; i < 3; i++) { + cx24120_writereg(state, 0xf0 + i, 0x04); + cx24120_writereg(state, 0xe6 + i, 0x02); } cx24120_writereg(state, 0xea, (reg | 0x01)); - for (reg1 = 0xc5; reg1 < 0xcb; reg1 += 2) { - cx24120_writereg(state, reg1, 0x00); - cx24120_writereg(state, reg1 + 1, 0x00); + for (i = 0; i < 6; i += 2) { + cx24120_writereg(state, 0xc5 + i, 0x00); + cx24120_writereg(state, 0xc6 + i, 0x00); } cx24120_writereg(state, 0xe4, 0x03); @@ -1266,15 +1264,15 @@ int cx24120_init(struct dvb_frontend *fe) reg = cx24120_readreg(state, 0xe1); if (reg == fw->data[fw->size - 1]) { dev_dbg(&state->i2c->dev, "Firmware uploaded successfully\n"); - reset_result = 0; + ret = 0; } else { err("Firmware upload failed. Last byte returned=0x%x\n", ret); - reset_result = -EREMOTEIO; + ret = -EREMOTEIO; } cx24120_writereg(state, 0xdc, 0x00); release_firmware(fw); - if (reset_result != 0) - return reset_result; + if (ret != 0) + return ret; /* Start tuner */ cmd.id = CMD_START_TUNER; -- cgit v1.2.3-59-g8ed1b From cf4f8114794cce3ccbf038c8ebcc16392caac485 Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Fri, 15 May 2015 15:40:29 -0300 Subject: [media] b2c2: Reset no_base_addr on skystarS2 attach failure If set, all the other drivers reset no_base_addr on failure to attach - git commit for this being added to some of them seems to be eccd15aad72f774b2059f708bc422dbb8493bb30 This driver has been floating around outside the mainline for so long it hasn't had this fix, so add it in. Whilst here tidy surrounding code to fix style issues. Signed-off-by: Jemma Denson Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/b2c2/flexcop-fe-tuner.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/b2c2/flexcop-fe-tuner.c b/drivers/media/common/b2c2/flexcop-fe-tuner.c index 9305266d0ac0..2426062fcb3c 100644 --- a/drivers/media/common/b2c2/flexcop-fe-tuner.c +++ b/drivers/media/common/b2c2/flexcop-fe-tuner.c @@ -637,15 +637,16 @@ static int skystarS2_rev33_attach(struct flexcop_device *fc, struct i2c_adapter *i2c) { fc->fe = dvb_attach(cx24120_attach, - &skystar2_rev3_3_cx24120_config, i2c); - if (fc->fe == NULL) + &skystar2_rev3_3_cx24120_config, i2c); + if (!fc->fe) return 0; fc->dev_type = FC_SKYS2_REV33; fc->fc_i2c_adap[2].no_base_addr = 1; - if ((dvb_attach(isl6421_attach, fc->fe, - &fc->fc_i2c_adap[2].i2c_adap, 0x08, 0, 0, false) == NULL)) { + if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap, + 0x08, 0, 0, false)) { err("ISL6421 could NOT be attached!"); + fc->fc_i2c_adap[2].no_base_addr = 0; return 0; } info("ISL6421 successfully attached."); -- cgit v1.2.3-59-g8ed1b From 5c0a1c28c064e5998f6d6f48826e9701e9f68af2 Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Fri, 15 May 2015 16:08:26 -0300 Subject: [media] cx24120: Complete modfec_table Add in all the likely values for setting fec on tuning. Some values yet to be tested but very likely to be correct. In the very unlikely event that these are wrong tuning with FEC_AUTO will still work. Signed-off-by: Jemma Denson Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 44 +++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 20 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index bc8d0ebb63b6..da50b9e1e9f8 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -920,32 +920,36 @@ static int cx24120_set_inversion(struct cx24120_state *state, return 0; } -/* - * FEC lookup table for tuning Some DVB-S2 val's have been found by - * trial and error. Sofar it seems to match up with the contents of - * the REG_FECMODE after tuning The rest will probably be the same but - * would need testing. Anything not in the table will run with - * FEC_AUTO and take a while longer to tune in ( c.500ms instead of - * 30ms ) - */ +/* FEC lookup table for tuning */ static struct cx24120_modfec_table { fe_delivery_system_t delsys; fe_modulation_t mod; fe_code_rate_t fec; u8 val; } modfec_table[] = { - /*delsys mod fec val */ - { SYS_DVBS, QPSK, FEC_1_2, 0x2e }, - { SYS_DVBS, QPSK, FEC_2_3, 0x2f }, - { SYS_DVBS, QPSK, FEC_3_4, 0x30 }, - { SYS_DVBS, QPSK, FEC_5_6, 0x31 }, - { SYS_DVBS, QPSK, FEC_6_7, 0x32 }, - { SYS_DVBS, QPSK, FEC_7_8, 0x33 }, - - { SYS_DVBS2, QPSK, FEC_3_4, 0x07 }, - - { SYS_DVBS2, PSK_8, FEC_2_3, 0x0d }, - { SYS_DVBS2, PSK_8, FEC_3_4, 0x0e }, + /*delsys mod fec val */ + { SYS_DVBS, QPSK, FEC_1_2, 0x2e }, + { SYS_DVBS, QPSK, FEC_2_3, 0x2f }, + { SYS_DVBS, QPSK, FEC_3_4, 0x30 }, + { SYS_DVBS, QPSK, FEC_5_6, 0x31 }, + { SYS_DVBS, QPSK, FEC_6_7, 0x32 }, + { SYS_DVBS, QPSK, FEC_7_8, 0x33 }, + + { SYS_DVBS2, QPSK, FEC_1_2, 0x04 }, + { SYS_DVBS2, QPSK, FEC_3_5, 0x05 }, + { SYS_DVBS2, QPSK, FEC_2_3, 0x06 }, + { SYS_DVBS2, QPSK, FEC_3_4, 0x07 }, + { SYS_DVBS2, QPSK, FEC_4_5, 0x08 }, + { SYS_DVBS2, QPSK, FEC_5_6, 0x09 }, + { SYS_DVBS2, QPSK, FEC_8_9, 0x0a }, + { SYS_DVBS2, QPSK, FEC_9_10, 0x0b }, + + { SYS_DVBS2, PSK_8, FEC_3_5, 0x0c }, + { SYS_DVBS2, PSK_8, FEC_2_3, 0x0d }, + { SYS_DVBS2, PSK_8, FEC_3_4, 0x0e }, + { SYS_DVBS2, PSK_8, FEC_5_6, 0x0f }, + { SYS_DVBS2, PSK_8, FEC_8_9, 0x10 }, + { SYS_DVBS2, PSK_8, FEC_9_10, 0x11 }, }; /* Set fec_val & fec_mask values from delsys, modulation & fec */ -- cgit v1.2.3-59-g8ed1b From 65b01665a98a8738371d945230f4bd6fb41a3594 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 May 2015 08:04:35 -0300 Subject: [media] cx24120: don't initialize a var that won't be used As reported by smatch: drivers/media/dvb-frontends/cx24120.c: In function 'cx24120_message_send': drivers/media/dvb-frontends/cx24120.c:368:6: warning: variable 'ret' set but not used [-Wunused-but-set-variable] int ret, ficus; ^ The values written by cx24120 are never checked. So, remove the check here too. That's said, the best would be to do the reverse, but globally: to properly handle the error codes. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Patrick Boettcher --- drivers/media/dvb-frontends/cx24120.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index da50b9e1e9f8..3ab8582e233b 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -365,17 +365,17 @@ static void cx24120_check_cmd(struct cx24120_state *state, u8 id) static int cx24120_message_send(struct cx24120_state *state, struct cx24120_cmd *cmd) { - int ret, ficus; + int ficus; if (state->mpeg_enabled) { /* Disable mpeg out on certain commands */ cx24120_check_cmd(state, cmd->id); } - ret = cx24120_writereg(state, CX24120_REG_CMD_START, cmd->id); - ret = cx24120_writeregs(state, CX24120_REG_CMD_ARGS, &cmd->arg[0], - cmd->len, 1); - ret = cx24120_writereg(state, CX24120_REG_CMD_END, 0x01); + cx24120_writereg(state, CX24120_REG_CMD_START, cmd->id); + cx24120_writeregs(state, CX24120_REG_CMD_ARGS, &cmd->arg[0], + cmd->len, 1); + cx24120_writereg(state, CX24120_REG_CMD_END, 0x01); ficus = 1000; while (cx24120_readreg(state, CX24120_REG_CMD_END)) { -- cgit v1.2.3-59-g8ed1b From 5b8bc802e79f4f1df7fcf6999c910d6e231e3c95 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 May 2015 08:06:52 -0300 Subject: [media] cx24120: declare cx24120_init() as static drivers/media/dvb-frontends/cx24120.c:1182:5: warning: no previous prototype for 'cx24120_init' [-Wmissing-prototypes] int cx24120_init(struct dvb_frontend *fe) ^ Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Patrick Boettcher --- drivers/media/dvb-frontends/cx24120.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index 3ab8582e233b..2dcd93f63408 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -1179,7 +1179,7 @@ static int cx24120_set_vco(struct cx24120_state *state) return cx24120_message_send(state, &cmd); } -int cx24120_init(struct dvb_frontend *fe) +static int cx24120_init(struct dvb_frontend *fe) { const struct firmware *fw; struct dtv_frontend_properties *c = &fe->dtv_property_cache; -- cgit v1.2.3-59-g8ed1b From ec8fe6c92576a0d6e2b04df2ef139125c3f341b5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 May 2015 08:19:47 -0300 Subject: [media] cx24120: constify static data Use const on the static data, as gcc may optimize better the code. Also, would prevent that some code would override the data there. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Patrick Boettcher --- drivers/media/dvb-frontends/cx24120.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index 2dcd93f63408..2b3f83d5b997 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -704,12 +704,14 @@ static int cx24120_read_status(struct dvb_frontend *fe, fe_status_t *status) * Used for decoding the REG_FECMODE register * once tuned in. */ -static struct cx24120_modfec { +struct cx24120_modfec { fe_delivery_system_t delsys; fe_modulation_t mod; fe_code_rate_t fec; u8 val; -} modfec_lookup_table[] = { +}; + +static const struct cx24120_modfec modfec_lookup_table[] = { /*delsys mod fec val */ { SYS_DVBS, QPSK, FEC_1_2, 0x01 }, { SYS_DVBS, QPSK, FEC_2_3, 0x02 }, @@ -784,7 +786,7 @@ static int cx24120_get_fec(struct dvb_frontend *fe) * There's probably some way of calculating these but I * can't determine the pattern */ -static struct cx24120_clock_ratios_table { +struct cx24120_clock_ratios_table { fe_delivery_system_t delsys; fe_pilot_t pilot; fe_modulation_t mod; @@ -792,7 +794,9 @@ static struct cx24120_clock_ratios_table { u32 m_rat; u32 n_rat; u32 rate; -} clock_ratios_table[] = { +}; + +static const struct cx24120_clock_ratios_table clock_ratios_table[] = { /*delsys pilot mod fec m_rat n_rat rate */ { SYS_DVBS2, PILOT_OFF, QPSK, FEC_1_2, 273088, 254505, 274 }, { SYS_DVBS2, PILOT_OFF, QPSK, FEC_3_5, 17272, 13395, 330 }, @@ -921,12 +925,14 @@ static int cx24120_set_inversion(struct cx24120_state *state, } /* FEC lookup table for tuning */ -static struct cx24120_modfec_table { +struct cx24120_modfec_table { fe_delivery_system_t delsys; fe_modulation_t mod; fe_code_rate_t fec; u8 val; -} modfec_table[] = { +}; + +static const struct cx24120_modfec_table modfec_table[] = { /*delsys mod fec val */ { SYS_DVBS, QPSK, FEC_1_2, 0x2e }, { SYS_DVBS, QPSK, FEC_2_3, 0x2f }, -- cgit v1.2.3-59-g8ed1b From ddcb252e41c15b360c0e9a172fbd29d3f0ed18cd Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Tue, 19 May 2015 15:17:23 -0300 Subject: [media] cx24120: Add in dvbv5 stats for bit error rate DVBv3 is a legacy API. Drivers should use DVBv5, in order to support modern applications. So, implement BER using dvbv5. Signed-off-by: Jemma Denson Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 71 +++++++++++++++++++++++++++++++---- 1 file changed, 63 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index 2b3f83d5b997..2d4678091d7a 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -87,7 +87,7 @@ enum command_message_id { CMD_FWVERSION = 0x35, - CMD_TUNER_INIT = 0x3c, /* cmd.len = 0x03; */ + CMD_BER_CTRL = 0x3c, /* cmd.len = 0x03; */ }; #define CX24120_MAX_CMD_LEN 30 @@ -107,6 +107,10 @@ enum command_message_id { #define CX24120_STATUS_MASK 0x0f #define CX24120_SIGNAL_MASK 0xc0 +/* ber window */ +#define CX24120_BER_WINDOW 16 +#define CX24120_BER_WSIZE ((1 << CX24120_BER_WINDOW) * 208 * 8) + #define info(args...) pr_info("cx24120: " args) #define err(args...) pr_err("cx24120: ### ERROR: " args) @@ -145,6 +149,10 @@ struct cx24120_state { struct cx24120_tuning dnxt; fe_status_t fe_status; + + /* ber stats calulations */ + u32 berw_usecs; + unsigned long ber_jiffies_stats; }; /* Command message to firmware */ @@ -599,8 +607,9 @@ static void cx24120_get_stats(struct cx24120_state *state) struct dvb_frontend *fe = &state->frontend; struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct cx24120_cmd cmd; - int ret, cnr; + int ret, cnr, msecs; u16 sig; + u32 ber; dev_dbg(&state->i2c->dev, "\n"); @@ -647,7 +656,23 @@ static void cx24120_get_stats(struct cx24120_state *state) c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; } - /* FIXME: add UCB/BER */ + /* BER */ + if (time_after(jiffies, state->ber_jiffies_stats)) { + msecs = (state->berw_usecs + 500) / 1000; + state->ber_jiffies_stats = jiffies + msecs_to_jiffies(msecs); + + ret = cx24120_read_ber(fe, &ber); + if (ret != 0) + return; + + c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_error.stat[0].uvalue += ber; + + c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_count.stat[0].uvalue += CX24120_BER_WSIZE; + } + + /* FIXME: add UCB */ } static void cx24120_set_clock_ratios(struct dvb_frontend *fe); @@ -777,6 +802,29 @@ static int cx24120_get_fec(struct dvb_frontend *fe) return 0; } +/* Calculate ber window time */ +void cx24120_calculate_ber_window(struct cx24120_state *state, u32 rate) +{ + struct dvb_frontend *fe = &state->frontend; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + u64 bitrate, tmp; + + /* + * Calculate bitrate from rate in the clock ratios table. + * This isn't *exactly* right but close enough. + */ + bitrate = (u64)c->symbol_rate * rate; + do_div(bitrate, 256); + + /* usecs per ber window */ + tmp = 1000000ULL * CX24120_BER_WSIZE; + do_div(tmp, bitrate); + state->berw_usecs = tmp; + + dev_dbg(&state->i2c->dev, "bitrate: %llu, berw_usecs: %u\n", + bitrate, state->berw_usecs); +} + /* * Clock ratios lookup table * @@ -897,6 +945,9 @@ static void cx24120_set_clock_ratios(struct dvb_frontend *fe) cmd.arg[9] = (clock_ratios_table[idx].rate >> 0) & 0xff; cx24120_message_send(state, &cmd); + + /* Calculate ber window rates for stat work */ + cx24120_calculate_ber_window(state, clock_ratios_table[idx].rate); } /* Set inversion value */ @@ -1343,14 +1394,14 @@ static int cx24120_init(struct dvb_frontend *fe) return -EREMOTEIO; } - /* ???? */ - cmd.id = CMD_TUNER_INIT; + /* Set size of BER window */ + cmd.id = CMD_BER_CTRL; cmd.len = 3; cmd.arg[0] = 0x00; - cmd.arg[1] = 0x10; - cmd.arg[2] = 0x10; + cmd.arg[1] = CX24120_BER_WINDOW; + cmd.arg[2] = CX24120_BER_WINDOW; if (cx24120_message_send(state, &cmd)) { - err("Error sending final init message. :(\n"); + err("Error setting ber window\n"); return -EREMOTEIO; } @@ -1371,6 +1422,10 @@ static int cx24120_init(struct dvb_frontend *fe) c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; c->cnr.len = 1; c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->post_bit_error.len = 1; + c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->post_bit_count.len = 1; + c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; state->cold_init = 1; return 0; -- cgit v1.2.3-59-g8ed1b From fc4432847866baf1d3ad3348cce976c0299be081 Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Tue, 19 May 2015 15:29:44 -0300 Subject: [media] cx24120: Convert read_ber to retrieve from cache Instead of reading BER again for DVBv3 call, use the value from the cache. Signed-off-by: Jemma Denson Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index 2d4678091d7a..3fe9da28e978 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -152,6 +152,7 @@ struct cx24120_state { /* ber stats calulations */ u32 berw_usecs; + u32 ber_prev; unsigned long ber_jiffies_stats; }; @@ -338,12 +339,15 @@ static int cx24120_read_snr(struct dvb_frontend *fe, u16 *snr) static int cx24120_read_ber(struct dvb_frontend *fe, u32 *ber) { struct cx24120_state *state = fe->demodulator_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + + if (c->post_bit_error.stat[0].scale != FE_SCALE_COUNTER) { + *ber = 0; + return 0; + } - *ber = (cx24120_readreg(state, CX24120_REG_BER_HH) << 24) | - (cx24120_readreg(state, CX24120_REG_BER_HL) << 16) | - (cx24120_readreg(state, CX24120_REG_BER_LH) << 8) | - cx24120_readreg(state, CX24120_REG_BER_LL); - dev_dbg(&state->i2c->dev, "read BER index = %d\n", *ber); + *ber = c->post_bit_error.stat[0].uvalue - state->ber_prev; + state->ber_prev = c->post_bit_error.stat[0].uvalue; return 0; } @@ -661,9 +665,11 @@ static void cx24120_get_stats(struct cx24120_state *state) msecs = (state->berw_usecs + 500) / 1000; state->ber_jiffies_stats = jiffies + msecs_to_jiffies(msecs); - ret = cx24120_read_ber(fe, &ber); - if (ret != 0) - return; + ber = cx24120_readreg(state, CX24120_REG_BER_HH) << 24; + ber |= cx24120_readreg(state, CX24120_REG_BER_HL) << 16; + ber |= cx24120_readreg(state, CX24120_REG_BER_LH) << 8; + ber |= cx24120_readreg(state, CX24120_REG_BER_LL); + dev_dbg(&state->i2c->dev, "read BER index = %d\n", ber); c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; c->post_bit_error.stat[0].uvalue += ber; -- cgit v1.2.3-59-g8ed1b From 80e9710b34550ae906424feb2cf40dee0422ce46 Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Tue, 19 May 2015 15:52:46 -0300 Subject: [media] cx24120: Convert ucblocks to dvbv5 stats DVBv3 is a legacy API. Drivers should use DVBv5, in order to support modern applications. So, implement UCB using dvbv5. Signed-off-by: Jemma Denson Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 49 +++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 11 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index 3fe9da28e978..ce784248b328 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -151,9 +151,12 @@ struct cx24120_state { fe_status_t fe_status; /* ber stats calulations */ + u32 bitrate; u32 berw_usecs; u32 ber_prev; + u32 per_prev; unsigned long ber_jiffies_stats; + unsigned long per_jiffies_stats; }; /* Command message to firmware */ @@ -612,7 +615,7 @@ static void cx24120_get_stats(struct cx24120_state *state) struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct cx24120_cmd cmd; int ret, cnr, msecs; - u16 sig; + u16 sig, ucb; u32 ber; dev_dbg(&state->i2c->dev, "\n"); @@ -678,7 +681,20 @@ static void cx24120_get_stats(struct cx24120_state *state) c->post_bit_count.stat[0].uvalue += CX24120_BER_WSIZE; } - /* FIXME: add UCB */ + /* UCB */ + if (time_after(jiffies, state->per_jiffies_stats)) { + state->per_jiffies_stats = jiffies + msecs_to_jiffies(1000); + + ucb = cx24120_readreg(state, CX24120_REG_UCB_H) << 8; + ucb |= cx24120_readreg(state, CX24120_REG_UCB_L); + dev_dbg(&state->i2c->dev, "ucblocks = %d\n", ucb); + + c->block_error.stat[0].scale = FE_SCALE_COUNTER; + c->block_error.stat[0].uvalue += ucb; + + c->block_count.stat[0].scale = FE_SCALE_COUNTER; + c->block_count.stat[0].uvalue += state->bitrate / 8 / 208; + } } static void cx24120_set_clock_ratios(struct dvb_frontend *fe); @@ -813,22 +829,23 @@ void cx24120_calculate_ber_window(struct cx24120_state *state, u32 rate) { struct dvb_frontend *fe = &state->frontend; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - u64 bitrate, tmp; + u64 tmp; /* * Calculate bitrate from rate in the clock ratios table. * This isn't *exactly* right but close enough. */ - bitrate = (u64)c->symbol_rate * rate; - do_div(bitrate, 256); + tmp = (u64)c->symbol_rate * rate; + do_div(tmp, 256); + state->bitrate = tmp; /* usecs per ber window */ tmp = 1000000ULL * CX24120_BER_WSIZE; - do_div(tmp, bitrate); + do_div(tmp, state->bitrate); state->berw_usecs = tmp; - dev_dbg(&state->i2c->dev, "bitrate: %llu, berw_usecs: %u\n", - bitrate, state->berw_usecs); + dev_dbg(&state->i2c->dev, "bitrate: %u, berw_usecs: %u\n", + state->bitrate, state->berw_usecs); } /* @@ -1432,6 +1449,11 @@ static int cx24120_init(struct dvb_frontend *fe) c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; c->post_bit_count.len = 1; c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->block_error.len = 1; + c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->block_count.len = 1; + c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + state->cold_init = 1; return 0; @@ -1503,11 +1525,16 @@ static void cx24120_release(struct dvb_frontend *fe) static int cx24120_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) { struct cx24120_state *state = fe->demodulator_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + + if (c->block_error.stat[0].scale != FE_SCALE_COUNTER) { + *ucblocks = 0; + return 0; + } - *ucblocks = (cx24120_readreg(state, CX24120_REG_UCB_H) << 8) | - cx24120_readreg(state, CX24120_REG_UCB_L); + *ucblocks = c->block_error.stat[0].uvalue - state->per_prev; + state->per_prev = c->block_error.stat[0].uvalue; - dev_dbg(&state->i2c->dev, "ucblocks = %d\n", *ucblocks); return 0; } -- cgit v1.2.3-59-g8ed1b From e3f2f63e8cc8a9b9a16f351b55a108ab82de6d2e Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Tue, 19 May 2015 17:23:14 -0300 Subject: [media] cx24120: Check for lock before updating BER & UCB BER & UCB aren't available unless we're locked; don't update dvbv5 stats when not locked and mark these counters as unavailable. Signed-off-by: Jemma Denson Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index ce784248b328..dc80e6affeae 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -663,6 +663,15 @@ static void cx24120_get_stats(struct cx24120_state *state) c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; } + /* BER & UCB require lock */ + if (!(state->fe_status & FE_HAS_LOCK)) { + c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + return; + } + /* BER */ if (time_after(jiffies, state->ber_jiffies_stats)) { msecs = (state->berw_usecs + 500) / 1000; -- cgit v1.2.3-59-g8ed1b From c9adafa3b2fd4bc5f15cdf95e6cbd25256ae0f28 Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Tue, 19 May 2015 17:32:55 -0300 Subject: [media] cx24120: Update comment & fix typo These state vars are used for more than just ber calculation, also fix typo. Signed-off-by: Jemma Denson Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index dc80e6affeae..d1c7ccb94c22 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -150,7 +150,7 @@ struct cx24120_state { fe_status_t fe_status; - /* ber stats calulations */ + /* dvbv5 stats calculations */ u32 bitrate; u32 berw_usecs; u32 ber_prev; -- cgit v1.2.3-59-g8ed1b From 71df673132cd5eef9ae2d9c79e3a446249de4961 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Wed, 20 May 2015 04:58:49 -0300 Subject: [media] cx24120: fix minor checkpatch-error Remove multiple blank likes. Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index d1c7ccb94c22..a14d0f1cc71e 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -1463,8 +1463,8 @@ static int cx24120_init(struct dvb_frontend *fe) c->block_count.len = 1; c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; - state->cold_init = 1; + return 0; } -- cgit v1.2.3-59-g8ed1b From f888ae7e6a9e7c0ddc2aa78adc1299747f202516 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 1 May 2015 11:31:30 -0300 Subject: [media] adv7842: Make output format configurable through pad format operations Replace the dummy video format operations by pad format operations that configure the output format. Copied from the adv7604 driver. Note: while arch/blackfin/mach-bf609/boards/ezkit.c uses adv7842_platform_data this source has not been updated because it is broken since the very beginning. It depends on a struct adv7842_output_format that does not exist. And besides that gcc has no support for bf609 so nobody can compile it except by installing a toolchain from ADI. Signed-off-by: Hans Verkuil Cc: Scott Jiang Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7842.c | 269 +++++++++++++++++++++++++++++++++++++++----- include/media/adv7842.h | 89 ++++++--------- 2 files changed, 276 insertions(+), 82 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index 86e65a8a5409..dceabc29239a 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -56,6 +56,28 @@ MODULE_LICENSE("GPL"); /* ADV7842 system clock frequency */ #define ADV7842_fsc (28636360) +#define ADV7842_RGB_OUT (1 << 1) + +#define ADV7842_OP_FORMAT_SEL_8BIT (0 << 0) +#define ADV7842_OP_FORMAT_SEL_10BIT (1 << 0) +#define ADV7842_OP_FORMAT_SEL_12BIT (2 << 0) + +#define ADV7842_OP_MODE_SEL_SDR_422 (0 << 5) +#define ADV7842_OP_MODE_SEL_DDR_422 (1 << 5) +#define ADV7842_OP_MODE_SEL_SDR_444 (2 << 5) +#define ADV7842_OP_MODE_SEL_DDR_444 (3 << 5) +#define ADV7842_OP_MODE_SEL_SDR_422_2X (4 << 5) +#define ADV7842_OP_MODE_SEL_ADI_CM (5 << 5) + +#define ADV7842_OP_CH_SEL_GBR (0 << 5) +#define ADV7842_OP_CH_SEL_GRB (1 << 5) +#define ADV7842_OP_CH_SEL_BGR (2 << 5) +#define ADV7842_OP_CH_SEL_RGB (3 << 5) +#define ADV7842_OP_CH_SEL_BRG (4 << 5) +#define ADV7842_OP_CH_SEL_RBG (5 << 5) + +#define ADV7842_OP_SWAP_CB_CR (1 << 0) + /* ********************************************************************** * @@ -64,6 +86,14 @@ MODULE_LICENSE("GPL"); ********************************************************************** */ +struct adv7842_format_info { + u32 code; + u8 op_ch_sel; + bool rgb_out; + bool swap_cb_cr; + u8 op_format_sel; +}; + struct adv7842_state { struct adv7842_platform_data pdata; struct v4l2_subdev sd; @@ -72,6 +102,9 @@ struct adv7842_state { enum adv7842_mode mode; struct v4l2_dv_timings timings; enum adv7842_vid_std_select vid_std_select; + + const struct adv7842_format_info *format; + v4l2_std_id norm; struct { u8 edid[256]; @@ -221,11 +254,21 @@ static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl) return &container_of(ctrl->handler, struct adv7842_state, hdl)->sd; } +static inline unsigned hblanking(const struct v4l2_bt_timings *t) +{ + return V4L2_DV_BT_BLANKING_WIDTH(t); +} + static inline unsigned htotal(const struct v4l2_bt_timings *t) { return V4L2_DV_BT_FRAME_WIDTH(t); } +static inline unsigned vblanking(const struct v4l2_bt_timings *t) +{ + return V4L2_DV_BT_BLANKING_HEIGHT(t); +} + static inline unsigned vtotal(const struct v4l2_bt_timings *t) { return V4L2_DV_BT_FRAME_HEIGHT(t); @@ -335,6 +378,12 @@ static inline int io_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 va return io_write(sd, reg, (io_read(sd, reg) & mask) | val); } +static inline int io_write_clr_set(struct v4l2_subdev *sd, + u8 reg, u8 mask, u8 val) +{ + return io_write(sd, reg, (io_read(sd, reg) & ~mask) | val); +} + static inline int avlink_read(struct v4l2_subdev *sd, u8 reg) { struct adv7842_state *state = to_state(sd); @@ -535,6 +584,64 @@ static void main_reset(struct v4l2_subdev *sd) mdelay(5); } +/* ----------------------------------------------------------------------------- + * Format helpers + */ + +static const struct adv7842_format_info adv7842_formats[] = { + { MEDIA_BUS_FMT_RGB888_1X24, ADV7842_OP_CH_SEL_RGB, true, false, + ADV7842_OP_MODE_SEL_SDR_444 | ADV7842_OP_FORMAT_SEL_8BIT }, + { MEDIA_BUS_FMT_YUYV8_2X8, ADV7842_OP_CH_SEL_RGB, false, false, + ADV7842_OP_MODE_SEL_SDR_422 | ADV7842_OP_FORMAT_SEL_8BIT }, + { MEDIA_BUS_FMT_YVYU8_2X8, ADV7842_OP_CH_SEL_RGB, false, true, + ADV7842_OP_MODE_SEL_SDR_422 | ADV7842_OP_FORMAT_SEL_8BIT }, + { MEDIA_BUS_FMT_YUYV10_2X10, ADV7842_OP_CH_SEL_RGB, false, false, + ADV7842_OP_MODE_SEL_SDR_422 | ADV7842_OP_FORMAT_SEL_10BIT }, + { MEDIA_BUS_FMT_YVYU10_2X10, ADV7842_OP_CH_SEL_RGB, false, true, + ADV7842_OP_MODE_SEL_SDR_422 | ADV7842_OP_FORMAT_SEL_10BIT }, + { MEDIA_BUS_FMT_YUYV12_2X12, ADV7842_OP_CH_SEL_RGB, false, false, + ADV7842_OP_MODE_SEL_SDR_422 | ADV7842_OP_FORMAT_SEL_12BIT }, + { MEDIA_BUS_FMT_YVYU12_2X12, ADV7842_OP_CH_SEL_RGB, false, true, + ADV7842_OP_MODE_SEL_SDR_422 | ADV7842_OP_FORMAT_SEL_12BIT }, + { MEDIA_BUS_FMT_UYVY8_1X16, ADV7842_OP_CH_SEL_RBG, false, false, + ADV7842_OP_MODE_SEL_SDR_422_2X | ADV7842_OP_FORMAT_SEL_8BIT }, + { MEDIA_BUS_FMT_VYUY8_1X16, ADV7842_OP_CH_SEL_RBG, false, true, + ADV7842_OP_MODE_SEL_SDR_422_2X | ADV7842_OP_FORMAT_SEL_8BIT }, + { MEDIA_BUS_FMT_YUYV8_1X16, ADV7842_OP_CH_SEL_RGB, false, false, + ADV7842_OP_MODE_SEL_SDR_422_2X | ADV7842_OP_FORMAT_SEL_8BIT }, + { MEDIA_BUS_FMT_YVYU8_1X16, ADV7842_OP_CH_SEL_RGB, false, true, + ADV7842_OP_MODE_SEL_SDR_422_2X | ADV7842_OP_FORMAT_SEL_8BIT }, + { MEDIA_BUS_FMT_UYVY10_1X20, ADV7842_OP_CH_SEL_RBG, false, false, + ADV7842_OP_MODE_SEL_SDR_422_2X | ADV7842_OP_FORMAT_SEL_10BIT }, + { MEDIA_BUS_FMT_VYUY10_1X20, ADV7842_OP_CH_SEL_RBG, false, true, + ADV7842_OP_MODE_SEL_SDR_422_2X | ADV7842_OP_FORMAT_SEL_10BIT }, + { MEDIA_BUS_FMT_YUYV10_1X20, ADV7842_OP_CH_SEL_RGB, false, false, + ADV7842_OP_MODE_SEL_SDR_422_2X | ADV7842_OP_FORMAT_SEL_10BIT }, + { MEDIA_BUS_FMT_YVYU10_1X20, ADV7842_OP_CH_SEL_RGB, false, true, + ADV7842_OP_MODE_SEL_SDR_422_2X | ADV7842_OP_FORMAT_SEL_10BIT }, + { MEDIA_BUS_FMT_UYVY12_1X24, ADV7842_OP_CH_SEL_RBG, false, false, + ADV7842_OP_MODE_SEL_SDR_422_2X | ADV7842_OP_FORMAT_SEL_12BIT }, + { MEDIA_BUS_FMT_VYUY12_1X24, ADV7842_OP_CH_SEL_RBG, false, true, + ADV7842_OP_MODE_SEL_SDR_422_2X | ADV7842_OP_FORMAT_SEL_12BIT }, + { MEDIA_BUS_FMT_YUYV12_1X24, ADV7842_OP_CH_SEL_RGB, false, false, + ADV7842_OP_MODE_SEL_SDR_422_2X | ADV7842_OP_FORMAT_SEL_12BIT }, + { MEDIA_BUS_FMT_YVYU12_1X24, ADV7842_OP_CH_SEL_RGB, false, true, + ADV7842_OP_MODE_SEL_SDR_422_2X | ADV7842_OP_FORMAT_SEL_12BIT }, +}; + +static const struct adv7842_format_info * +adv7842_format_info(struct adv7842_state *state, u32 code) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(adv7842_formats); ++i) { + if (adv7842_formats[i].code == code) + return &adv7842_formats[i]; + } + + return NULL; +} + /* ----------------------------------------------------------------------- */ static inline bool is_analog_input(struct v4l2_subdev *sd) @@ -1440,6 +1547,8 @@ static int adv7842_query_dv_timings(struct v4l2_subdev *sd, } bt->interlaced = stdi.interlaced ? V4L2_DV_INTERLACED : V4L2_DV_PROGRESSIVE; + bt->standards = V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | + V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT; if (is_digital_input(sd)) { uint32_t freq; @@ -1478,6 +1587,10 @@ static int adv7842_query_dv_timings(struct v4l2_subdev *sd, hdmi_read(sd, 0x31)) / 2; bt->il_vbackporch = ((hdmi_read(sd, 0x34) & 0x1f) * 256 + hdmi_read(sd, 0x35)) / 2; + } else { + bt->il_vfrontporch = 0; + bt->il_vsync = 0; + bt->il_vbackporch = 0; } adv7842_fill_optional_dv_timings_fields(sd, timings); } else { @@ -1871,47 +1984,145 @@ static int adv7842_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_mbus_code_enum *code) { - if (code->pad || code->index) + if (code->index >= ARRAY_SIZE(adv7842_formats)) return -EINVAL; - /* Good enough for now */ - code->code = MEDIA_BUS_FMT_FIXED; + code->code = adv7842_formats[code->index].code; return 0; } -static int adv7842_fill_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_format *format) +static void adv7842_fill_format(struct adv7842_state *state, + struct v4l2_mbus_framefmt *format) +{ + memset(format, 0, sizeof(*format)); + + format->width = state->timings.bt.width; + format->height = state->timings.bt.height; + format->field = V4L2_FIELD_NONE; + format->colorspace = V4L2_COLORSPACE_SRGB; + + if (state->timings.bt.flags & V4L2_DV_FL_IS_CE_VIDEO) + format->colorspace = (state->timings.bt.height <= 576) ? + V4L2_COLORSPACE_SMPTE170M : V4L2_COLORSPACE_REC709; +} + +/* + * Compute the op_ch_sel value required to obtain on the bus the component order + * corresponding to the selected format taking into account bus reordering + * applied by the board at the output of the device. + * + * The following table gives the op_ch_value from the format component order + * (expressed as op_ch_sel value in column) and the bus reordering (expressed as + * adv7842_bus_order value in row). + * + * | GBR(0) GRB(1) BGR(2) RGB(3) BRG(4) RBG(5) + * ----------+------------------------------------------------- + * RGB (NOP) | GBR GRB BGR RGB BRG RBG + * GRB (1-2) | BGR RGB GBR GRB RBG BRG + * RBG (2-3) | GRB GBR BRG RBG BGR RGB + * BGR (1-3) | RBG BRG RGB BGR GRB GBR + * BRG (ROR) | BRG RBG GRB GBR RGB BGR + * GBR (ROL) | RGB BGR RBG BRG GBR GRB + */ +static unsigned int adv7842_op_ch_sel(struct adv7842_state *state) +{ +#define _SEL(a, b, c, d, e, f) { \ + ADV7842_OP_CH_SEL_##a, ADV7842_OP_CH_SEL_##b, ADV7842_OP_CH_SEL_##c, \ + ADV7842_OP_CH_SEL_##d, ADV7842_OP_CH_SEL_##e, ADV7842_OP_CH_SEL_##f } +#define _BUS(x) [ADV7842_BUS_ORDER_##x] + + static const unsigned int op_ch_sel[6][6] = { + _BUS(RGB) /* NOP */ = _SEL(GBR, GRB, BGR, RGB, BRG, RBG), + _BUS(GRB) /* 1-2 */ = _SEL(BGR, RGB, GBR, GRB, RBG, BRG), + _BUS(RBG) /* 2-3 */ = _SEL(GRB, GBR, BRG, RBG, BGR, RGB), + _BUS(BGR) /* 1-3 */ = _SEL(RBG, BRG, RGB, BGR, GRB, GBR), + _BUS(BRG) /* ROR */ = _SEL(BRG, RBG, GRB, GBR, RGB, BGR), + _BUS(GBR) /* ROL */ = _SEL(RGB, BGR, RBG, BRG, GBR, GRB), + }; + + return op_ch_sel[state->pdata.bus_order][state->format->op_ch_sel >> 5]; +} + +static void adv7842_setup_format(struct adv7842_state *state) +{ + struct v4l2_subdev *sd = &state->sd; + + io_write_clr_set(sd, 0x02, 0x02, + state->format->rgb_out ? ADV7842_RGB_OUT : 0); + io_write(sd, 0x03, state->format->op_format_sel | + state->pdata.op_format_mode_sel); + io_write_clr_set(sd, 0x04, 0xe0, adv7842_op_ch_sel(state)); + io_write_clr_set(sd, 0x05, 0x01, + state->format->swap_cb_cr ? ADV7842_OP_SWAP_CB_CR : 0); +} + +static int adv7842_get_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { - struct v4l2_mbus_framefmt *fmt = &format->format; struct adv7842_state *state = to_state(sd); - if (format->pad) + if (format->pad != ADV7842_PAD_SOURCE) return -EINVAL; - fmt->width = state->timings.bt.width; - fmt->height = state->timings.bt.height; - fmt->code = MEDIA_BUS_FMT_FIXED; - fmt->field = V4L2_FIELD_NONE; - if (state->mode == ADV7842_MODE_SDP) { /* SPD block */ - if (!(sdp_read(sd, 0x5A) & 0x01)) + if (!(sdp_read(sd, 0x5a) & 0x01)) return -EINVAL; - fmt->width = 720; + format->format.code = MEDIA_BUS_FMT_YUYV8_2X8; + format->format.width = 720; /* valid signal */ if (state->norm & V4L2_STD_525_60) - fmt->height = 480; + format->format.height = 480; else - fmt->height = 576; - fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; + format->format.height = 576; + format->format.colorspace = V4L2_COLORSPACE_SMPTE170M; return 0; } - fmt->colorspace = V4L2_COLORSPACE_SRGB; - if (state->timings.bt.flags & V4L2_DV_FL_IS_CE_VIDEO) { - fmt->colorspace = (state->timings.bt.height <= 576) ? - V4L2_COLORSPACE_SMPTE170M : V4L2_COLORSPACE_REC709; + adv7842_fill_format(state, &format->format); + + if (format->which == V4L2_SUBDEV_FORMAT_TRY) { + struct v4l2_mbus_framefmt *fmt; + + fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad); + format->format.code = fmt->code; + } else { + format->format.code = state->format->code; } + + return 0; +} + +static int adv7842_set_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) +{ + struct adv7842_state *state = to_state(sd); + const struct adv7842_format_info *info; + + if (format->pad != ADV7842_PAD_SOURCE) + return -EINVAL; + + if (state->mode == ADV7842_MODE_SDP) + return adv7842_get_format(sd, cfg, format); + + info = adv7842_format_info(state, format->format.code); + if (info == NULL) + info = adv7842_format_info(state, MEDIA_BUS_FMT_YUYV8_2X8); + + adv7842_fill_format(state, &format->format); + format->format.code = info->code; + + if (format->which == V4L2_SUBDEV_FORMAT_TRY) { + struct v4l2_mbus_framefmt *fmt; + + fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad); + fmt->code = format->format.code; + } else { + state->format = info; + adv7842_setup_format(state); + } + return 0; } @@ -2551,14 +2762,11 @@ static int adv7842_core_init(struct v4l2_subdev *sd) 0xf0 | pdata->alt_gamma << 3 | pdata->op_656_range << 2 | - pdata->rgb_out << 1 | pdata->alt_data_sat << 0); - io_write(sd, 0x03, pdata->op_format_sel); - io_write_and_or(sd, 0x04, 0x1f, pdata->op_ch_sel << 5); io_write_and_or(sd, 0x05, 0xf0, pdata->blank_data << 3 | pdata->insert_av_codes << 2 | - pdata->replicate_av_codes << 1 | - pdata->invert_cbcr << 0); + pdata->replicate_av_codes << 1); + adv7842_setup_format(state); /* HDMI audio */ hdmi_write_and_or(sd, 0x1a, 0xf1, 0x08); /* Wait 1 s before unmute */ @@ -2818,13 +3026,13 @@ static const struct v4l2_subdev_video_ops adv7842_video_ops = { }; static const struct v4l2_subdev_pad_ops adv7842_pad_ops = { + .enum_mbus_code = adv7842_enum_mbus_code, + .get_fmt = adv7842_get_format, + .set_fmt = adv7842_set_format, .get_edid = adv7842_get_edid, .set_edid = adv7842_set_edid, .enum_dv_timings = adv7842_enum_dv_timings, .dv_timings_cap = adv7842_dv_timings_cap, - .enum_mbus_code = adv7842_enum_mbus_code, - .get_fmt = adv7842_fill_fmt, - .set_fmt = adv7842_fill_fmt, }; static const struct v4l2_subdev_ops adv7842_ops = { @@ -2991,6 +3199,7 @@ static int adv7842_probe(struct i2c_client *client, /* platform data */ state->pdata = *pdata; state->timings = cea640x480; + state->format = adv7842_format_info(state, MEDIA_BUS_FMT_YUYV8_2X8); sd = &state->sd; v4l2_i2c_subdev_init(sd, client, &adv7842_ops); diff --git a/include/media/adv7842.h b/include/media/adv7842.h index 924cbb8d004a..64a66d0ba9e1 100644 --- a/include/media/adv7842.h +++ b/include/media/adv7842.h @@ -30,14 +30,38 @@ enum adv7842_ain_sel { ADV7842_AIN9_4_5_6_SYNC_2_1 = 4, }; -/* Bus rotation and reordering (IO register 0x04, [7:5]) */ -enum adv7842_op_ch_sel { - ADV7842_OP_CH_SEL_GBR = 0, - ADV7842_OP_CH_SEL_GRB = 1, - ADV7842_OP_CH_SEL_BGR = 2, - ADV7842_OP_CH_SEL_RGB = 3, - ADV7842_OP_CH_SEL_BRG = 4, - ADV7842_OP_CH_SEL_RBG = 5, +/* + * Bus rotation and reordering. This is used to specify component reordering on + * the board and describes the components order on the bus when the ADV7842 + * outputs RGB. + */ +enum adv7842_bus_order { + ADV7842_BUS_ORDER_RGB, /* No operation */ + ADV7842_BUS_ORDER_GRB, /* Swap 1-2 */ + ADV7842_BUS_ORDER_RBG, /* Swap 2-3 */ + ADV7842_BUS_ORDER_BGR, /* Swap 1-3 */ + ADV7842_BUS_ORDER_BRG, /* Rotate right */ + ADV7842_BUS_ORDER_GBR, /* Rotate left */ +}; + +/* Input Color Space (IO register 0x02, [7:4]) */ +enum adv7842_inp_color_space { + ADV7842_INP_COLOR_SPACE_LIM_RGB = 0, + ADV7842_INP_COLOR_SPACE_FULL_RGB = 1, + ADV7842_INP_COLOR_SPACE_LIM_YCbCr_601 = 2, + ADV7842_INP_COLOR_SPACE_LIM_YCbCr_709 = 3, + ADV7842_INP_COLOR_SPACE_XVYCC_601 = 4, + ADV7842_INP_COLOR_SPACE_XVYCC_709 = 5, + ADV7842_INP_COLOR_SPACE_FULL_YCbCr_601 = 6, + ADV7842_INP_COLOR_SPACE_FULL_YCbCr_709 = 7, + ADV7842_INP_COLOR_SPACE_AUTO = 0xf, +}; + +/* Select output format (IO register 0x03, [4:2]) */ +enum adv7842_op_format_mode_sel { + ADV7842_OP_FORMAT_MODE0 = 0x00, + ADV7842_OP_FORMAT_MODE1 = 0x04, + ADV7842_OP_FORMAT_MODE2 = 0x08, }; /* Mode of operation */ @@ -61,44 +85,6 @@ enum adv7842_vid_std_select { ADV7842_HDMI_COMP_VID_STD_HD_1250P = 0x1e, }; -/* Input Color Space (IO register 0x02, [7:4]) */ -enum adv7842_inp_color_space { - ADV7842_INP_COLOR_SPACE_LIM_RGB = 0, - ADV7842_INP_COLOR_SPACE_FULL_RGB = 1, - ADV7842_INP_COLOR_SPACE_LIM_YCbCr_601 = 2, - ADV7842_INP_COLOR_SPACE_LIM_YCbCr_709 = 3, - ADV7842_INP_COLOR_SPACE_XVYCC_601 = 4, - ADV7842_INP_COLOR_SPACE_XVYCC_709 = 5, - ADV7842_INP_COLOR_SPACE_FULL_YCbCr_601 = 6, - ADV7842_INP_COLOR_SPACE_FULL_YCbCr_709 = 7, - ADV7842_INP_COLOR_SPACE_AUTO = 0xf, -}; - -/* Select output format (IO register 0x03, [7:0]) */ -enum adv7842_op_format_sel { - ADV7842_OP_FORMAT_SEL_SDR_ITU656_8 = 0x00, - ADV7842_OP_FORMAT_SEL_SDR_ITU656_10 = 0x01, - ADV7842_OP_FORMAT_SEL_SDR_ITU656_12_MODE0 = 0x02, - ADV7842_OP_FORMAT_SEL_SDR_ITU656_12_MODE1 = 0x06, - ADV7842_OP_FORMAT_SEL_SDR_ITU656_12_MODE2 = 0x0a, - ADV7842_OP_FORMAT_SEL_DDR_422_8 = 0x20, - ADV7842_OP_FORMAT_SEL_DDR_422_10 = 0x21, - ADV7842_OP_FORMAT_SEL_DDR_422_12_MODE0 = 0x22, - ADV7842_OP_FORMAT_SEL_DDR_422_12_MODE1 = 0x23, - ADV7842_OP_FORMAT_SEL_DDR_422_12_MODE2 = 0x24, - ADV7842_OP_FORMAT_SEL_SDR_444_24 = 0x40, - ADV7842_OP_FORMAT_SEL_SDR_444_30 = 0x41, - ADV7842_OP_FORMAT_SEL_SDR_444_36_MODE0 = 0x42, - ADV7842_OP_FORMAT_SEL_DDR_444_24 = 0x60, - ADV7842_OP_FORMAT_SEL_DDR_444_30 = 0x61, - ADV7842_OP_FORMAT_SEL_DDR_444_36 = 0x62, - ADV7842_OP_FORMAT_SEL_SDR_ITU656_16 = 0x80, - ADV7842_OP_FORMAT_SEL_SDR_ITU656_20 = 0x81, - ADV7842_OP_FORMAT_SEL_SDR_ITU656_24_MODE0 = 0x82, - ADV7842_OP_FORMAT_SEL_SDR_ITU656_24_MODE1 = 0x86, - ADV7842_OP_FORMAT_SEL_SDR_ITU656_24_MODE2 = 0x8a, -}; - enum adv7842_select_input { ADV7842_SELECT_HDMI_PORT_A, ADV7842_SELECT_HDMI_PORT_B, @@ -163,7 +149,10 @@ struct adv7842_platform_data { enum adv7842_ain_sel ain_sel; /* Bus rotation and reordering */ - enum adv7842_op_ch_sel op_ch_sel; + enum adv7842_bus_order bus_order; + + /* Select output format mode */ + enum adv7842_op_format_mode_sel op_format_mode_sel; /* Default mode */ enum adv7842_mode mode; @@ -174,20 +163,15 @@ struct adv7842_platform_data { /* Video standard */ enum adv7842_vid_std_select vid_std_select; - /* Select output format */ - enum adv7842_op_format_sel op_format_sel; - /* IO register 0x02 */ unsigned alt_gamma:1; unsigned op_656_range:1; - unsigned rgb_out:1; unsigned alt_data_sat:1; /* IO register 0x05 */ unsigned blank_data:1; unsigned insert_av_codes:1; unsigned replicate_av_codes:1; - unsigned invert_cbcr:1; /* IO register 0x30 */ unsigned output_bus_lsb_to_msb:1; @@ -256,5 +240,6 @@ struct adv7842_platform_data { #define ADV7842_EDID_PORT_A 0 #define ADV7842_EDID_PORT_B 1 #define ADV7842_EDID_PORT_VGA 2 +#define ADV7842_PAD_SOURCE 3 #endif -- cgit v1.2.3-59-g8ed1b From ce0eff016f7272faa6dc6eec722b1ca1970ff9aa Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 20 Jan 2015 12:18:16 -0300 Subject: [media] vb2: allow requeuing buffers while streaming vb2_buffer_done() already allows STATE_QUEUED, but currently only when not streaming. It is useful to allow it while streaming as well, as this makes it possible for drivers to requeue buffers while waiting for a stable video signal. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-core.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 552d7e127c39..1a096a62ef30 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -182,6 +182,7 @@ module_param(debug, int, 0644); V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_TIMECODE) static void __vb2_queue_cancel(struct vb2_queue *q); +static void __enqueue_in_driver(struct vb2_buffer *vb); /** * __vb2_buf_mem_alloc() - allocate video memory for the given buffer @@ -1153,8 +1154,9 @@ EXPORT_SYMBOL_GPL(vb2_plane_cookie); /** * vb2_buffer_done() - inform videobuf that an operation on a buffer is finished * @vb: vb2_buffer returned from the driver - * @state: either VB2_BUF_STATE_DONE if the operation finished successfully - * or VB2_BUF_STATE_ERROR if the operation finished with an error. + * @state: either VB2_BUF_STATE_DONE if the operation finished successfully, + * VB2_BUF_STATE_ERROR if the operation finished with an error or + * VB2_BUF_STATE_QUEUED if the driver wants to requeue buffers. * If start_streaming fails then it should return buffers with state * VB2_BUF_STATE_QUEUED to put them back into the queue. * @@ -1205,8 +1207,11 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) atomic_dec(&q->owned_by_drv_count); spin_unlock_irqrestore(&q->done_lock, flags); - if (state == VB2_BUF_STATE_QUEUED) + if (state == VB2_BUF_STATE_QUEUED) { + if (q->start_streaming_called) + __enqueue_in_driver(vb); return; + } /* Inform any processes that may be waiting for buffers */ wake_up(&q->done_wq); -- cgit v1.2.3-59-g8ed1b From 48519838cc915d1af7083662471d2eb939a024c9 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 7 May 2015 10:37:57 -0300 Subject: [media] adv7604/adv7842: replace FMT_CHANGED by V4L2_DEVICE_NOTIFY_EVENT This makes it easier for the bridge driver to just passthrough such events to the corresponding device node. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7604.c | 12 +++++++++--- drivers/media/i2c/adv7842.c | 11 +++++++++-- include/media/adv7604.h | 1 - include/media/adv7842.h | 3 --- 4 files changed, 18 insertions(+), 9 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index be3f8660e457..aaa37b0e9ed4 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -341,6 +341,11 @@ static const struct adv76xx_video_standards adv76xx_prim_mode_hdmi_gr[] = { { }, }; +static const struct v4l2_event adv76xx_ev_fmt = { + .type = V4L2_EVENT_SOURCE_CHANGE, + .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION, +}; + /* ----------------------------------------------------------------------- */ static inline struct adv76xx_state *to_state(struct v4l2_subdev *sd) @@ -1744,11 +1749,11 @@ static int adv76xx_s_routing(struct v4l2_subdev *sd, state->selected_input = input; disable_input(sd); - select_input(sd); - enable_input(sd); + v4l2_subdev_notify(sd, V4L2_DEVICE_NOTIFY_EVENT, + (void *)&adv76xx_ev_fmt); return 0; } @@ -1915,7 +1920,8 @@ static int adv76xx_isr(struct v4l2_subdev *sd, u32 status, bool *handled) "%s: fmt_change = 0x%x, fmt_change_digital = 0x%x\n", __func__, fmt_change, fmt_change_digital); - v4l2_subdev_notify(sd, ADV76XX_FMT_CHANGE, NULL); + v4l2_subdev_notify(sd, V4L2_DEVICE_NOTIFY_EVENT, + (void *)&adv76xx_ev_fmt); if (handled) *handled = true; diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index dceabc29239a..f5248baeb59e 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -242,6 +242,11 @@ static const struct adv7842_video_standards adv7842_prim_mode_hdmi_gr[] = { { }, }; +static const struct v4l2_event adv7842_ev_fmt = { + .type = V4L2_EVENT_SOURCE_CHANGE, + .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION, +}; + /* ----------------------------------------------------------------------- */ static inline struct adv7842_state *to_state(struct v4l2_subdev *sd) @@ -1975,7 +1980,8 @@ static int adv7842_s_routing(struct v4l2_subdev *sd, select_input(sd, state->vid_std_select); enable_input(sd); - v4l2_subdev_notify(sd, ADV7842_FMT_CHANGE, NULL); + v4l2_subdev_notify(sd, V4L2_DEVICE_NOTIFY_EVENT, + (void *)&adv7842_ev_fmt); return 0; } @@ -2208,7 +2214,8 @@ static int adv7842_isr(struct v4l2_subdev *sd, u32 status, bool *handled) "%s: fmt_change_cp = 0x%x, fmt_change_digital = 0x%x, fmt_change_sdp = 0x%x\n", __func__, fmt_change_cp, fmt_change_digital, fmt_change_sdp); - v4l2_subdev_notify(sd, ADV7842_FMT_CHANGE, NULL); + v4l2_subdev_notify(sd, V4L2_DEVICE_NOTIFY_EVENT, + (void *)&adv7842_ev_fmt); if (handled) *handled = true; } diff --git a/include/media/adv7604.h b/include/media/adv7604.h index 9ecf353160c1..a913859bfd30 100644 --- a/include/media/adv7604.h +++ b/include/media/adv7604.h @@ -168,6 +168,5 @@ enum adv76xx_pad { /* notify events */ #define ADV76XX_HOTPLUG 1 -#define ADV76XX_FMT_CHANGE 2 #endif diff --git a/include/media/adv7842.h b/include/media/adv7842.h index 64a66d0ba9e1..1f38db8d3c21 100644 --- a/include/media/adv7842.h +++ b/include/media/adv7842.h @@ -230,9 +230,6 @@ struct adv7842_platform_data { #define V4L2_CID_ADV_RX_FREE_RUN_COLOR_MANUAL (V4L2_CID_DV_CLASS_BASE + 0x1001) #define V4L2_CID_ADV_RX_FREE_RUN_COLOR (V4L2_CID_DV_CLASS_BASE + 0x1002) -/* notify events */ -#define ADV7842_FMT_CHANGE 1 - /* custom ioctl, used to test the external RAM that's used by the * deinterlacer. */ #define ADV7842_CMD_RAM_TEST _IO('V', BASE_VIDIOC_PRIVATE) -- cgit v1.2.3-59-g8ed1b From 85756a069c55e0315ac5990806899cfb607b987f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 12 May 2015 08:52:21 -0300 Subject: [media] cobalt: add new driver The cobalt device is a PCIe card with 4 HDMI inputs (adv7604) and a connector that can be used to hook up an adv7511 transmitter or an adv7842 receiver daughterboard. This device is used within Cisco but is sadly not available outside of Cisco. Nevertheless it is a very interesting driver that can serve as an example of how to support HDMI hardware and how to use the popular adv devices. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 8 + drivers/media/pci/Kconfig | 1 + drivers/media/pci/Makefile | 1 + drivers/media/pci/cobalt/Kconfig | 18 + drivers/media/pci/cobalt/Makefile | 5 + drivers/media/pci/cobalt/cobalt-alsa-main.c | 162 +++ drivers/media/pci/cobalt/cobalt-alsa-pcm.c | 603 ++++++++++ drivers/media/pci/cobalt/cobalt-alsa-pcm.h | 22 + drivers/media/pci/cobalt/cobalt-alsa.h | 41 + drivers/media/pci/cobalt/cobalt-cpld.c | 341 ++++++ drivers/media/pci/cobalt/cobalt-cpld.h | 29 + drivers/media/pci/cobalt/cobalt-driver.c | 821 +++++++++++++ drivers/media/pci/cobalt/cobalt-driver.h | 377 ++++++ drivers/media/pci/cobalt/cobalt-flash.c | 132 ++ drivers/media/pci/cobalt/cobalt-flash.h | 29 + drivers/media/pci/cobalt/cobalt-i2c.c | 396 ++++++ drivers/media/pci/cobalt/cobalt-i2c.h | 25 + drivers/media/pci/cobalt/cobalt-irq.c | 254 ++++ drivers/media/pci/cobalt/cobalt-irq.h | 25 + drivers/media/pci/cobalt/cobalt-omnitek.c | 341 ++++++ drivers/media/pci/cobalt/cobalt-omnitek.h | 62 + drivers/media/pci/cobalt/cobalt-v4l2.c | 1260 ++++++++++++++++++++ drivers/media/pci/cobalt/cobalt-v4l2.h | 22 + .../cobalt/m00233_video_measure_memmap_package.h | 115 ++ .../pci/cobalt/m00235_fdma_packer_memmap_package.h | 44 + .../media/pci/cobalt/m00389_cvi_memmap_package.h | 59 + .../media/pci/cobalt/m00460_evcnt_memmap_package.h | 44 + .../pci/cobalt/m00473_freewheel_memmap_package.h | 57 + .../m00479_clk_loss_detector_memmap_package.h | 53 + .../m00514_syncgen_flow_evcnt_memmap_package.h | 88 ++ 30 files changed, 5435 insertions(+) create mode 100644 drivers/media/pci/cobalt/Kconfig create mode 100644 drivers/media/pci/cobalt/Makefile create mode 100644 drivers/media/pci/cobalt/cobalt-alsa-main.c create mode 100644 drivers/media/pci/cobalt/cobalt-alsa-pcm.c create mode 100644 drivers/media/pci/cobalt/cobalt-alsa-pcm.h create mode 100644 drivers/media/pci/cobalt/cobalt-alsa.h create mode 100644 drivers/media/pci/cobalt/cobalt-cpld.c create mode 100644 drivers/media/pci/cobalt/cobalt-cpld.h create mode 100644 drivers/media/pci/cobalt/cobalt-driver.c create mode 100644 drivers/media/pci/cobalt/cobalt-driver.h create mode 100644 drivers/media/pci/cobalt/cobalt-flash.c create mode 100644 drivers/media/pci/cobalt/cobalt-flash.h create mode 100644 drivers/media/pci/cobalt/cobalt-i2c.c create mode 100644 drivers/media/pci/cobalt/cobalt-i2c.h create mode 100644 drivers/media/pci/cobalt/cobalt-irq.c create mode 100644 drivers/media/pci/cobalt/cobalt-irq.h create mode 100644 drivers/media/pci/cobalt/cobalt-omnitek.c create mode 100644 drivers/media/pci/cobalt/cobalt-omnitek.h create mode 100644 drivers/media/pci/cobalt/cobalt-v4l2.c create mode 100644 drivers/media/pci/cobalt/cobalt-v4l2.h create mode 100644 drivers/media/pci/cobalt/m00233_video_measure_memmap_package.h create mode 100644 drivers/media/pci/cobalt/m00235_fdma_packer_memmap_package.h create mode 100644 drivers/media/pci/cobalt/m00389_cvi_memmap_package.h create mode 100644 drivers/media/pci/cobalt/m00460_evcnt_memmap_package.h create mode 100644 drivers/media/pci/cobalt/m00473_freewheel_memmap_package.h create mode 100644 drivers/media/pci/cobalt/m00479_clk_loss_detector_memmap_package.h create mode 100644 drivers/media/pci/cobalt/m00514_syncgen_flow_evcnt_memmap_package.h (limited to 'drivers/media') diff --git a/MAINTAINERS b/MAINTAINERS index 5579b5546445..3cfb97959696 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2602,6 +2602,14 @@ L: platform-driver-x86@vger.kernel.org S: Supported F: drivers/platform/x86/classmate-laptop.c +COBALT MEDIA DRIVER +M: Hans Verkuil +L: linux-media@vger.kernel.org +T: git git://linuxtv.org/media_tree.git +W: http://linuxtv.org +S: Supported +F: drivers/media/pci/cobalt/ + COCCINELLE/Semantic Patches (SmPL) M: Julia Lawall M: Gilles Muller diff --git a/drivers/media/pci/Kconfig b/drivers/media/pci/Kconfig index fd359fb15e69..f318ae9bb57a 100644 --- a/drivers/media/pci/Kconfig +++ b/drivers/media/pci/Kconfig @@ -33,6 +33,7 @@ source "drivers/media/pci/cx88/Kconfig" source "drivers/media/pci/bt8xx/Kconfig" source "drivers/media/pci/saa7134/Kconfig" source "drivers/media/pci/saa7164/Kconfig" +source "drivers/media/pci/cobalt/Kconfig" endif diff --git a/drivers/media/pci/Makefile b/drivers/media/pci/Makefile index 3471ab6b9f22..23ce53bd47c3 100644 --- a/drivers/media/pci/Makefile +++ b/drivers/media/pci/Makefile @@ -28,3 +28,4 @@ obj-$(CONFIG_VIDEO_DT3155) += dt3155/ obj-$(CONFIG_VIDEO_MEYE) += meye/ obj-$(CONFIG_STA2X11_VIP) += sta2x11/ obj-$(CONFIG_VIDEO_SOLO6X10) += solo6x10/ +obj-$(CONFIG_VIDEO_COBALT) += cobalt/ diff --git a/drivers/media/pci/cobalt/Kconfig b/drivers/media/pci/cobalt/Kconfig new file mode 100644 index 000000000000..e3c03e9b8263 --- /dev/null +++ b/drivers/media/pci/cobalt/Kconfig @@ -0,0 +1,18 @@ +config VIDEO_COBALT + tristate "Cisco Cobalt support" + depends on VIDEO_V4L2 && I2C && MEDIA_CONTROLLER + depends on PCI_MSI && MTD_COMPLEX_MAPPINGS + select I2C_ALGOBIT + select VIDEO_ADV7604 + select VIDEO_ADV7511 + select VIDEO_ADV7842 + select VIDEOBUF2_DMA_SG + ---help--- + This is a video4linux driver for the Cisco PCIe Cobalt card. + + This board is sadly not available outside of Cisco, but it is + very useful as an example of a real driver that uses all the + latest frameworks and APIs. + + To compile this driver as a module, choose M here: the + module will be called cobalt. diff --git a/drivers/media/pci/cobalt/Makefile b/drivers/media/pci/cobalt/Makefile new file mode 100644 index 000000000000..b328955abbd2 --- /dev/null +++ b/drivers/media/pci/cobalt/Makefile @@ -0,0 +1,5 @@ +cobalt-objs := cobalt-driver.o cobalt-irq.o cobalt-v4l2.o \ + cobalt-i2c.o cobalt-omnitek.o cobalt-flash.o cobalt-cpld.o \ + cobalt-alsa-main.o cobalt-alsa-pcm.o + +obj-$(CONFIG_VIDEO_COBALT) += cobalt.o diff --git a/drivers/media/pci/cobalt/cobalt-alsa-main.c b/drivers/media/pci/cobalt/cobalt-alsa-main.c new file mode 100644 index 000000000000..720e3ad93a9e --- /dev/null +++ b/drivers/media/pci/cobalt/cobalt-alsa-main.c @@ -0,0 +1,162 @@ +/* + * ALSA interface to cobalt PCM capture streams + * + * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "cobalt-driver.h" +#include "cobalt-alsa.h" +#include "cobalt-alsa-pcm.h" + +static void snd_cobalt_card_free(struct snd_cobalt_card *cobsc) +{ + if (cobsc == NULL) + return; + + cobsc->s->alsa = NULL; + + kfree(cobsc); +} + +static void snd_cobalt_card_private_free(struct snd_card *sc) +{ + if (sc == NULL) + return; + snd_cobalt_card_free(sc->private_data); + sc->private_data = NULL; + sc->private_free = NULL; +} + +static int snd_cobalt_card_create(struct cobalt_stream *s, + struct snd_card *sc, + struct snd_cobalt_card **cobsc) +{ + *cobsc = kzalloc(sizeof(struct snd_cobalt_card), GFP_KERNEL); + if (*cobsc == NULL) + return -ENOMEM; + + (*cobsc)->s = s; + (*cobsc)->sc = sc; + + sc->private_data = *cobsc; + sc->private_free = snd_cobalt_card_private_free; + + return 0; +} + +static int snd_cobalt_card_set_names(struct snd_cobalt_card *cobsc) +{ + struct cobalt_stream *s = cobsc->s; + struct cobalt *cobalt = s->cobalt; + struct snd_card *sc = cobsc->sc; + + /* sc->driver is used by alsa-lib's configurator: simple, unique */ + strlcpy(sc->driver, "cobalt", sizeof(sc->driver)); + + /* sc->shortname is a symlink in /proc/asound: COBALT-M -> cardN */ + snprintf(sc->shortname, sizeof(sc->shortname), "cobalt-%d-%d", + cobalt->instance, s->video_channel); + + /* sc->longname is read from /proc/asound/cards */ + snprintf(sc->longname, sizeof(sc->longname), + "Cobalt %d HDMI %d", + cobalt->instance, s->video_channel); + + return 0; +} + +int cobalt_alsa_init(struct cobalt_stream *s) +{ + struct cobalt *cobalt = s->cobalt; + struct snd_card *sc = NULL; + struct snd_cobalt_card *cobsc; + int ret; + + /* Numbrs steps from "Writing an ALSA Driver" by Takashi Iwai */ + + /* (1) Check and increment the device index */ + /* This is a no-op for us. We'll use the cobalt->instance */ + + /* (2) Create a card instance */ + ret = snd_card_new(&cobalt->pci_dev->dev, SNDRV_DEFAULT_IDX1, + SNDRV_DEFAULT_STR1, THIS_MODULE, 0, &sc); + if (ret) { + cobalt_err("snd_card_new() failed with err %d\n", ret); + goto err_exit; + } + + /* (3) Create a main component */ + ret = snd_cobalt_card_create(s, sc, &cobsc); + if (ret) { + cobalt_err("snd_cobalt_card_create() failed with err %d\n", + ret); + goto err_exit_free; + } + + /* (4) Set the driver ID and name strings */ + snd_cobalt_card_set_names(cobsc); + + ret = snd_cobalt_pcm_create(cobsc); + if (ret) { + cobalt_err("snd_cobalt_pcm_create() failed with err %d\n", + ret); + goto err_exit_free; + } + /* FIXME - proc files */ + + /* (7) Set the driver data and return 0 */ + /* We do this out of normal order for PCI drivers to avoid races */ + s->alsa = cobsc; + + /* (6) Register the card instance */ + ret = snd_card_register(sc); + if (ret) { + s->alsa = NULL; + cobalt_err("snd_card_register() failed with err %d\n", ret); + goto err_exit_free; + } + + return 0; + +err_exit_free: + if (sc != NULL) + snd_card_free(sc); + kfree(cobsc); +err_exit: + return ret; +} + +void cobalt_alsa_exit(struct cobalt_stream *s) +{ + struct snd_cobalt_card *cobsc = s->alsa; + + if (cobsc) + snd_card_free(cobsc->sc); + s->alsa = NULL; +} diff --git a/drivers/media/pci/cobalt/cobalt-alsa-pcm.c b/drivers/media/pci/cobalt/cobalt-alsa-pcm.c new file mode 100644 index 000000000000..f0bdf10cfd57 --- /dev/null +++ b/drivers/media/pci/cobalt/cobalt-alsa-pcm.c @@ -0,0 +1,603 @@ +/* + * ALSA PCM device for the + * ALSA interface to cobalt PCM capture streams + * + * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include + +#include + +#include +#include + +#include "cobalt-driver.h" +#include "cobalt-alsa.h" +#include "cobalt-alsa-pcm.h" + +static unsigned int pcm_debug; +module_param(pcm_debug, int, 0644); +MODULE_PARM_DESC(pcm_debug, "enable debug messages for pcm"); + +#define dprintk(fmt, arg...) \ + do { \ + if (pcm_debug) \ + pr_info("cobalt-alsa-pcm %s: " fmt, __func__, ##arg); \ + } while (0) + +static struct snd_pcm_hardware snd_cobalt_hdmi_capture = { + .info = SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP_VALID, + + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, + + .rates = SNDRV_PCM_RATE_48000, + + .rate_min = 48000, + .rate_max = 48000, + .channels_min = 1, + .channels_max = 8, + .buffer_bytes_max = 4 * 240 * 8 * 4, /* 5 ms of data */ + .period_bytes_min = 1920, /* 1 sample = 8 * 4 bytes */ + .period_bytes_max = 240 * 8 * 4, /* 5 ms of 8 channel data */ + .periods_min = 1, + .periods_max = 4, +}; + +static struct snd_pcm_hardware snd_cobalt_playback = { + .info = SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP_VALID, + + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, + + .rates = SNDRV_PCM_RATE_48000, + + .rate_min = 48000, + .rate_max = 48000, + .channels_min = 1, + .channels_max = 8, + .buffer_bytes_max = 4 * 240 * 8 * 4, /* 5 ms of data */ + .period_bytes_min = 1920, /* 1 sample = 8 * 4 bytes */ + .period_bytes_max = 240 * 8 * 4, /* 5 ms of 8 channel data */ + .periods_min = 1, + .periods_max = 4, +}; + +static void sample_cpy(u8 *dst, const u8 *src, u32 len, bool is_s32) +{ + static const unsigned map[8] = { 0, 1, 5, 4, 2, 3, 6, 7 }; + unsigned idx = 0; + + while (len >= (is_s32 ? 4 : 2)) { + unsigned offset = map[idx] * 4; + u32 val = src[offset + 1] + (src[offset + 2] << 8) + + (src[offset + 3] << 16); + + if (is_s32) { + *dst++ = 0; + *dst++ = val & 0xff; + } + *dst++ = (val >> 8) & 0xff; + *dst++ = (val >> 16) & 0xff; + len -= is_s32 ? 4 : 2; + idx++; + } +} + +static void cobalt_alsa_announce_pcm_data(struct snd_cobalt_card *cobsc, + u8 *pcm_data, + size_t skip, + size_t samples) +{ + struct snd_pcm_substream *substream; + struct snd_pcm_runtime *runtime; + unsigned long flags; + unsigned int oldptr; + unsigned int stride; + int length = samples; + int period_elapsed = 0; + bool is_s32; + + dprintk("cobalt alsa announce ptr=%p data=%p num_bytes=%zd\n", cobsc, + pcm_data, samples); + + substream = cobsc->capture_pcm_substream; + if (substream == NULL) { + dprintk("substream was NULL\n"); + return; + } + + runtime = substream->runtime; + if (runtime == NULL) { + dprintk("runtime was NULL\n"); + return; + } + is_s32 = runtime->format == SNDRV_PCM_FORMAT_S32_LE; + + stride = runtime->frame_bits >> 3; + if (stride == 0) { + dprintk("stride is zero\n"); + return; + } + + if (length == 0) { + dprintk("%s: length was zero\n", __func__); + return; + } + + if (runtime->dma_area == NULL) { + dprintk("dma area was NULL - ignoring\n"); + return; + } + + oldptr = cobsc->hwptr_done_capture; + if (oldptr + length >= runtime->buffer_size) { + unsigned int cnt = runtime->buffer_size - oldptr; + unsigned i; + + for (i = 0; i < cnt; i++) + sample_cpy(runtime->dma_area + (oldptr + i) * stride, + pcm_data + i * skip, + stride, is_s32); + for (i = cnt; i < length; i++) + sample_cpy(runtime->dma_area + (i - cnt) * stride, + pcm_data + i * skip, stride, is_s32); + } else { + unsigned i; + + for (i = 0; i < length; i++) + sample_cpy(runtime->dma_area + (oldptr + i) * stride, + pcm_data + i * skip, + stride, is_s32); + } + snd_pcm_stream_lock_irqsave(substream, flags); + + cobsc->hwptr_done_capture += length; + if (cobsc->hwptr_done_capture >= + runtime->buffer_size) + cobsc->hwptr_done_capture -= + runtime->buffer_size; + + cobsc->capture_transfer_done += length; + if (cobsc->capture_transfer_done >= + runtime->period_size) { + cobsc->capture_transfer_done -= + runtime->period_size; + period_elapsed = 1; + } + + snd_pcm_stream_unlock_irqrestore(substream, flags); + + if (period_elapsed) + snd_pcm_period_elapsed(substream); +} + +static int alsa_fnc(struct vb2_buffer *vb, void *priv) +{ + struct cobalt_stream *s = priv; + unsigned char *p = vb2_plane_vaddr(vb, 0); + int i; + + if (pcm_debug) { + pr_info("alsa: "); + for (i = 0; i < 8 * 4; i++) { + if (!(i & 3)) + pr_cont(" "); + pr_cont("%02x", p[i]); + } + pr_cont("\n"); + } + cobalt_alsa_announce_pcm_data(s->alsa, + vb2_plane_vaddr(vb, 0), + 8 * 4, + vb2_get_plane_payload(vb, 0) / (8 * 4)); + return 0; +} + +static int snd_cobalt_pcm_capture_open(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_cobalt_card *cobsc = snd_pcm_substream_chip(substream); + struct cobalt_stream *s = cobsc->s; + + runtime->hw = snd_cobalt_hdmi_capture; + snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); + cobsc->capture_pcm_substream = substream; + runtime->private_data = s; + cobsc->alsa_record_cnt++; + if (cobsc->alsa_record_cnt == 1) { + int rc; + + rc = vb2_thread_start(&s->q, alsa_fnc, s, s->vdev.name); + if (rc) { + cobsc->alsa_record_cnt--; + return rc; + } + } + return 0; +} + +static int snd_cobalt_pcm_capture_close(struct snd_pcm_substream *substream) +{ + struct snd_cobalt_card *cobsc = snd_pcm_substream_chip(substream); + struct cobalt_stream *s = cobsc->s; + + cobsc->alsa_record_cnt--; + if (cobsc->alsa_record_cnt == 0) + vb2_thread_stop(&s->q); + return 0; +} + +static int snd_cobalt_pcm_ioctl(struct snd_pcm_substream *substream, + unsigned int cmd, void *arg) +{ + return snd_pcm_lib_ioctl(substream, cmd, arg); +} + + +static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, + size_t size) +{ + struct snd_pcm_runtime *runtime = subs->runtime; + + dprintk("Allocating vbuffer\n"); + if (runtime->dma_area) { + if (runtime->dma_bytes > size) + return 0; + + vfree(runtime->dma_area); + } + runtime->dma_area = vmalloc(size); + if (!runtime->dma_area) + return -ENOMEM; + + runtime->dma_bytes = size; + + return 0; +} + +static int snd_cobalt_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + dprintk("%s called\n", __func__); + + return snd_pcm_alloc_vmalloc_buffer(substream, + params_buffer_bytes(params)); +} + +static int snd_cobalt_pcm_hw_free(struct snd_pcm_substream *substream) +{ + if (substream->runtime->dma_area) { + dprintk("freeing pcm capture region\n"); + vfree(substream->runtime->dma_area); + substream->runtime->dma_area = NULL; + } + + return 0; +} + +static int snd_cobalt_pcm_prepare(struct snd_pcm_substream *substream) +{ + struct snd_cobalt_card *cobsc = snd_pcm_substream_chip(substream); + + cobsc->hwptr_done_capture = 0; + cobsc->capture_transfer_done = 0; + + return 0; +} + +static int snd_cobalt_pcm_trigger(struct snd_pcm_substream *substream, int cmd) +{ + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_STOP: + return 0; + default: + return -EINVAL; + } + return 0; +} + +static +snd_pcm_uframes_t snd_cobalt_pcm_pointer(struct snd_pcm_substream *substream) +{ + snd_pcm_uframes_t hwptr_done; + struct snd_cobalt_card *cobsc = snd_pcm_substream_chip(substream); + + hwptr_done = cobsc->hwptr_done_capture; + + return hwptr_done; +} + +static void pb_sample_cpy(u8 *dst, const u8 *src, u32 len, bool is_s32) +{ + static const unsigned map[8] = { 0, 1, 5, 4, 2, 3, 6, 7 }; + unsigned idx = 0; + + while (len >= (is_s32 ? 4 : 2)) { + unsigned offset = map[idx] * 4; + u8 *out = dst + offset; + + *out++ = 0; + if (is_s32) { + src++; + *out++ = *src++; + } else { + *out++ = 0; + } + *out++ = *src++; + *out = *src++; + len -= is_s32 ? 4 : 2; + idx++; + } +} + +static void cobalt_alsa_pb_pcm_data(struct snd_cobalt_card *cobsc, + u8 *pcm_data, + size_t skip, + size_t samples) +{ + struct snd_pcm_substream *substream; + struct snd_pcm_runtime *runtime; + unsigned long flags; + unsigned int pos; + unsigned int stride; + bool is_s32; + unsigned i; + + dprintk("cobalt alsa pb ptr=%p data=%p samples=%zd\n", cobsc, + pcm_data, samples); + + substream = cobsc->playback_pcm_substream; + if (substream == NULL) { + dprintk("substream was NULL\n"); + return; + } + + runtime = substream->runtime; + if (runtime == NULL) { + dprintk("runtime was NULL\n"); + return; + } + + is_s32 = runtime->format == SNDRV_PCM_FORMAT_S32_LE; + stride = runtime->frame_bits >> 3; + if (stride == 0) { + dprintk("stride is zero\n"); + return; + } + + if (samples == 0) { + dprintk("%s: samples was zero\n", __func__); + return; + } + + if (runtime->dma_area == NULL) { + dprintk("dma area was NULL - ignoring\n"); + return; + } + + pos = cobsc->pb_pos % cobsc->pb_size; + for (i = 0; i < cobsc->pb_count / (8 * 4); i++) + pb_sample_cpy(pcm_data + i * skip, + runtime->dma_area + pos + i * stride, + stride, is_s32); + snd_pcm_stream_lock_irqsave(substream, flags); + + cobsc->pb_pos += i * stride; + + snd_pcm_stream_unlock_irqrestore(substream, flags); + if (cobsc->pb_pos % cobsc->pb_count == 0) + snd_pcm_period_elapsed(substream); +} + +static int alsa_pb_fnc(struct vb2_buffer *vb, void *priv) +{ + struct cobalt_stream *s = priv; + + if (s->alsa->alsa_pb_channel) + cobalt_alsa_pb_pcm_data(s->alsa, + vb2_plane_vaddr(vb, 0), + 8 * 4, + vb2_get_plane_payload(vb, 0) / (8 * 4)); + return 0; +} + +static int snd_cobalt_pcm_playback_open(struct snd_pcm_substream *substream) +{ + struct snd_cobalt_card *cobsc = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + struct cobalt_stream *s = cobsc->s; + + runtime->hw = snd_cobalt_playback; + snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); + cobsc->playback_pcm_substream = substream; + runtime->private_data = s; + cobsc->alsa_playback_cnt++; + if (cobsc->alsa_playback_cnt == 1) { + int rc; + + rc = vb2_thread_start(&s->q, alsa_pb_fnc, s, s->vdev.name); + if (rc) { + cobsc->alsa_playback_cnt--; + return rc; + } + } + + return 0; +} + +static int snd_cobalt_pcm_playback_close(struct snd_pcm_substream *substream) +{ + struct snd_cobalt_card *cobsc = snd_pcm_substream_chip(substream); + struct cobalt_stream *s = cobsc->s; + + cobsc->alsa_playback_cnt--; + if (cobsc->alsa_playback_cnt == 0) + vb2_thread_stop(&s->q); + return 0; +} + +static int snd_cobalt_pcm_pb_prepare(struct snd_pcm_substream *substream) +{ + struct snd_cobalt_card *cobsc = snd_pcm_substream_chip(substream); + + cobsc->pb_size = snd_pcm_lib_buffer_bytes(substream); + cobsc->pb_count = snd_pcm_lib_period_bytes(substream); + cobsc->pb_pos = 0; + + return 0; +} + +static int snd_cobalt_pcm_pb_trigger(struct snd_pcm_substream *substream, + int cmd) +{ + struct snd_cobalt_card *cobsc = snd_pcm_substream_chip(substream); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + if (cobsc->alsa_pb_channel) + return -EBUSY; + cobsc->alsa_pb_channel = true; + return 0; + case SNDRV_PCM_TRIGGER_STOP: + cobsc->alsa_pb_channel = false; + return 0; + default: + return -EINVAL; + } +} + +static +snd_pcm_uframes_t snd_cobalt_pcm_pb_pointer(struct snd_pcm_substream *substream) +{ + struct snd_cobalt_card *cobsc = snd_pcm_substream_chip(substream); + size_t ptr; + + ptr = cobsc->pb_pos; + + return bytes_to_frames(substream->runtime, ptr) % + substream->runtime->buffer_size; +} + +static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs, + unsigned long offset) +{ + void *pageptr = subs->runtime->dma_area + offset; + + return vmalloc_to_page(pageptr); +} + +static struct snd_pcm_ops snd_cobalt_pcm_capture_ops = { + .open = snd_cobalt_pcm_capture_open, + .close = snd_cobalt_pcm_capture_close, + .ioctl = snd_cobalt_pcm_ioctl, + .hw_params = snd_cobalt_pcm_hw_params, + .hw_free = snd_cobalt_pcm_hw_free, + .prepare = snd_cobalt_pcm_prepare, + .trigger = snd_cobalt_pcm_trigger, + .pointer = snd_cobalt_pcm_pointer, + .page = snd_pcm_get_vmalloc_page, +}; + +static struct snd_pcm_ops snd_cobalt_pcm_playback_ops = { + .open = snd_cobalt_pcm_playback_open, + .close = snd_cobalt_pcm_playback_close, + .ioctl = snd_cobalt_pcm_ioctl, + .hw_params = snd_cobalt_pcm_hw_params, + .hw_free = snd_cobalt_pcm_hw_free, + .prepare = snd_cobalt_pcm_pb_prepare, + .trigger = snd_cobalt_pcm_pb_trigger, + .pointer = snd_cobalt_pcm_pb_pointer, + .page = snd_pcm_get_vmalloc_page, +}; + +int snd_cobalt_pcm_create(struct snd_cobalt_card *cobsc) +{ + struct snd_pcm *sp; + struct snd_card *sc = cobsc->sc; + struct cobalt_stream *s = cobsc->s; + struct cobalt *cobalt = s->cobalt; + int ret; + + s->q.gfp_flags |= __GFP_ZERO; + + if (!s->is_output) { + cobalt_s_bit_sysctrl(cobalt, + COBALT_SYS_CTRL_AUDIO_IPP_RESETN_BIT(s->video_channel), + 0); + mdelay(2); + cobalt_s_bit_sysctrl(cobalt, + COBALT_SYS_CTRL_AUDIO_IPP_RESETN_BIT(s->video_channel), + 1); + mdelay(1); + + ret = snd_pcm_new(sc, "Cobalt PCM-In HDMI", + 0, /* PCM device 0, the only one for this card */ + 0, /* 0 playback substreams */ + 1, /* 1 capture substream */ + &sp); + if (ret) { + cobalt_err("snd_cobalt_pcm_create() failed for input with err %d\n", + ret); + goto err_exit; + } + + snd_pcm_set_ops(sp, SNDRV_PCM_STREAM_CAPTURE, + &snd_cobalt_pcm_capture_ops); + sp->info_flags = 0; + sp->private_data = cobsc; + strlcpy(sp->name, "cobalt", sizeof(sp->name)); + } else { + cobalt_s_bit_sysctrl(cobalt, + COBALT_SYS_CTRL_AUDIO_OPP_RESETN_BIT, 0); + mdelay(2); + cobalt_s_bit_sysctrl(cobalt, + COBALT_SYS_CTRL_AUDIO_OPP_RESETN_BIT, 1); + mdelay(1); + + ret = snd_pcm_new(sc, "Cobalt PCM-Out HDMI", + 0, /* PCM device 0, the only one for this card */ + 1, /* 0 playback substreams */ + 0, /* 1 capture substream */ + &sp); + if (ret) { + cobalt_err("snd_cobalt_pcm_create() failed for output with err %d\n", + ret); + goto err_exit; + } + + snd_pcm_set_ops(sp, SNDRV_PCM_STREAM_PLAYBACK, + &snd_cobalt_pcm_playback_ops); + sp->info_flags = 0; + sp->private_data = cobsc; + strlcpy(sp->name, "cobalt", sizeof(sp->name)); + } + + return 0; + +err_exit: + return ret; +} diff --git a/drivers/media/pci/cobalt/cobalt-alsa-pcm.h b/drivers/media/pci/cobalt/cobalt-alsa-pcm.h new file mode 100644 index 000000000000..513fb1f71794 --- /dev/null +++ b/drivers/media/pci/cobalt/cobalt-alsa-pcm.h @@ -0,0 +1,22 @@ +/* + * ALSA PCM device for the + * ALSA interface to cobalt PCM capture streams + * + * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +int snd_cobalt_pcm_create(struct snd_cobalt_card *cobsc); diff --git a/drivers/media/pci/cobalt/cobalt-alsa.h b/drivers/media/pci/cobalt/cobalt-alsa.h new file mode 100644 index 000000000000..08db699ced37 --- /dev/null +++ b/drivers/media/pci/cobalt/cobalt-alsa.h @@ -0,0 +1,41 @@ +/* + * ALSA interface to cobalt PCM capture streams + * + * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +struct snd_card; + +struct snd_cobalt_card { + struct cobalt_stream *s; + struct snd_card *sc; + unsigned int capture_transfer_done; + unsigned int hwptr_done_capture; + unsigned alsa_record_cnt; + struct snd_pcm_substream *capture_pcm_substream; + + unsigned int pb_size; + unsigned int pb_count; + unsigned int pb_pos; + unsigned pb_filled; + bool alsa_pb_channel; + unsigned alsa_playback_cnt; + struct snd_pcm_substream *playback_pcm_substream; +}; + +int cobalt_alsa_init(struct cobalt_stream *s); +void cobalt_alsa_exit(struct cobalt_stream *s); diff --git a/drivers/media/pci/cobalt/cobalt-cpld.c b/drivers/media/pci/cobalt/cobalt-cpld.c new file mode 100644 index 000000000000..77ed9e57d306 --- /dev/null +++ b/drivers/media/pci/cobalt/cobalt-cpld.c @@ -0,0 +1,341 @@ +/* + * Cobalt CPLD functions + * + * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include + +#include "cobalt-driver.h" + +#define ADRS(offset) (COBALT_BUS_CPLD_BASE + offset) + +static u16 cpld_read(struct cobalt *cobalt, u32 offset) +{ + return cobalt_bus_read32(cobalt, ADRS(offset)); +} + +static void cpld_write(struct cobalt *cobalt, u32 offset, u16 val) +{ + return cobalt_bus_write32(cobalt, ADRS(offset), val); +} + +static void cpld_info_ver3(struct cobalt *cobalt) +{ + u32 rd; + u32 tmp; + + cobalt_info("CPLD System control register (read/write)\n"); + cobalt_info("\t\tSystem control: 0x%04x (0x0f00)\n", + cpld_read(cobalt, 0)); + cobalt_info("CPLD Clock control register (read/write)\n"); + cobalt_info("\t\tClock control: 0x%04x (0x0000)\n", + cpld_read(cobalt, 0x04)); + cobalt_info("CPLD HSMA Clk Osc register (read/write) - Must set wr trigger to load default values\n"); + cobalt_info("\t\tRegister #7:\t0x%04x (0x0022)\n", + cpld_read(cobalt, 0x08)); + cobalt_info("\t\tRegister #8:\t0x%04x (0x0047)\n", + cpld_read(cobalt, 0x0c)); + cobalt_info("\t\tRegister #9:\t0x%04x (0x00fa)\n", + cpld_read(cobalt, 0x10)); + cobalt_info("\t\tRegister #10:\t0x%04x (0x0061)\n", + cpld_read(cobalt, 0x14)); + cobalt_info("\t\tRegister #11:\t0x%04x (0x001e)\n", + cpld_read(cobalt, 0x18)); + cobalt_info("\t\tRegister #12:\t0x%04x (0x0045)\n", + cpld_read(cobalt, 0x1c)); + cobalt_info("\t\tRegister #135:\t0x%04x\n", + cpld_read(cobalt, 0x20)); + cobalt_info("\t\tRegister #137:\t0x%04x\n", + cpld_read(cobalt, 0x24)); + cobalt_info("CPLD System status register (read only)\n"); + cobalt_info("\t\tSystem status: 0x%04x\n", + cpld_read(cobalt, 0x28)); + cobalt_info("CPLD MAXII info register (read only)\n"); + cobalt_info("\t\tBoard serial number: 0x%04x\n", + cpld_read(cobalt, 0x2c)); + cobalt_info("\t\tMAXII program revision: 0x%04x\n", + cpld_read(cobalt, 0x30)); + cobalt_info("CPLD temp and voltage ADT7411 registers (read only)\n"); + cobalt_info("\t\tBoard temperature: %u Celcius\n", + cpld_read(cobalt, 0x34) / 4); + cobalt_info("\t\tFPGA temperature: %u Celcius\n", + cpld_read(cobalt, 0x38) / 4); + rd = cpld_read(cobalt, 0x3c); + tmp = (rd * 33 * 1000) / (483 * 10); + cobalt_info("\t\tVDD 3V3: %u,%03uV\n", tmp / 1000, tmp % 1000); + rd = cpld_read(cobalt, 0x40); + tmp = (rd * 74 * 2197) / (27 * 1000); + cobalt_info("\t\tADC ch3 5V: %u,%03uV\n", tmp / 1000, tmp % 1000); + rd = cpld_read(cobalt, 0x44); + tmp = (rd * 74 * 2197) / (47 * 1000); + cobalt_info("\t\tADC ch4 3V: %u,%03uV\n", tmp / 1000, tmp % 1000); + rd = cpld_read(cobalt, 0x48); + tmp = (rd * 57 * 2197) / (47 * 1000); + cobalt_info("\t\tADC ch5 2V5: %u,%03uV\n", tmp / 1000, tmp % 1000); + rd = cpld_read(cobalt, 0x4c); + tmp = (rd * 2197) / 1000; + cobalt_info("\t\tADC ch6 1V8: %u,%03uV\n", tmp / 1000, tmp % 1000); + rd = cpld_read(cobalt, 0x50); + tmp = (rd * 2197) / 1000; + cobalt_info("\t\tADC ch7 1V5: %u,%03uV\n", tmp / 1000, tmp % 1000); + rd = cpld_read(cobalt, 0x54); + tmp = (rd * 2197) / 1000; + cobalt_info("\t\tADC ch8 0V9: %u,%03uV\n", tmp / 1000, tmp % 1000); +} + +void cobalt_cpld_status(struct cobalt *cobalt) +{ + u32 rev = cpld_read(cobalt, 0x30); + + switch (rev) { + case 3: + case 4: + case 5: + cpld_info_ver3(cobalt); + break; + default: + cobalt_info("CPLD revision %u is not supported!\n", rev); + break; + } +} + +#define DCO_MIN 4850000000ULL +#define DCO_MAX 5670000000ULL + +#define SI570_CLOCK_CTRL 0x04 +#define S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_WR_TRIGGER 0x200 +#define S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_RST_TRIGGER 0x100 +#define S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_FPGA_CTRL 0x80 +#define S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_EN 0x40 + +#define SI570_REG7 0x08 +#define SI570_REG8 0x0c +#define SI570_REG9 0x10 +#define SI570_REG10 0x14 +#define SI570_REG11 0x18 +#define SI570_REG12 0x1c +#define SI570_REG135 0x20 +#define SI570_REG137 0x24 + +struct multiplier { + unsigned mult, hsdiv, n1; +}; + +/* List all possible multipliers (= hsdiv * n1). There are lots of duplicates, + which are all removed in this list to keep the list as short as possible. + The values for hsdiv and n1 are the actual values, not the register values. + */ +static const struct multiplier multipliers[] = { + { 4, 4, 1 }, { 5, 5, 1 }, { 6, 6, 1 }, + { 7, 7, 1 }, { 8, 4, 2 }, { 9, 9, 1 }, + { 10, 5, 2 }, { 11, 11, 1 }, { 12, 6, 2 }, + { 14, 7, 2 }, { 16, 4, 4 }, { 18, 9, 2 }, + { 20, 5, 4 }, { 22, 11, 2 }, { 24, 4, 6 }, + { 28, 7, 4 }, { 30, 5, 6 }, { 32, 4, 8 }, + { 36, 6, 6 }, { 40, 4, 10 }, { 42, 7, 6 }, + { 44, 11, 4 }, { 48, 4, 12 }, { 50, 5, 10 }, + { 54, 9, 6 }, { 56, 4, 14 }, { 60, 5, 12 }, + { 64, 4, 16 }, { 66, 11, 6 }, { 70, 5, 14 }, + { 72, 4, 18 }, { 80, 4, 20 }, { 84, 6, 14 }, + { 88, 11, 8 }, { 90, 5, 18 }, { 96, 4, 24 }, + { 98, 7, 14 }, { 100, 5, 20 }, { 104, 4, 26 }, + { 108, 6, 18 }, { 110, 11, 10 }, { 112, 4, 28 }, + { 120, 4, 30 }, { 126, 7, 18 }, { 128, 4, 32 }, + { 130, 5, 26 }, { 132, 11, 12 }, { 136, 4, 34 }, + { 140, 5, 28 }, { 144, 4, 36 }, { 150, 5, 30 }, + { 152, 4, 38 }, { 154, 11, 14 }, { 156, 6, 26 }, + { 160, 4, 40 }, { 162, 9, 18 }, { 168, 4, 42 }, + { 170, 5, 34 }, { 176, 11, 16 }, { 180, 5, 36 }, + { 182, 7, 26 }, { 184, 4, 46 }, { 190, 5, 38 }, + { 192, 4, 48 }, { 196, 7, 28 }, { 198, 11, 18 }, + { 198, 9, 22 }, { 200, 4, 50 }, { 204, 6, 34 }, + { 208, 4, 52 }, { 210, 5, 42 }, { 216, 4, 54 }, + { 220, 11, 20 }, { 224, 4, 56 }, { 228, 6, 38 }, + { 230, 5, 46 }, { 232, 4, 58 }, { 234, 9, 26 }, + { 238, 7, 34 }, { 240, 4, 60 }, { 242, 11, 22 }, + { 248, 4, 62 }, { 250, 5, 50 }, { 252, 6, 42 }, + { 256, 4, 64 }, { 260, 5, 52 }, { 264, 11, 24 }, + { 266, 7, 38 }, { 270, 5, 54 }, { 272, 4, 68 }, + { 276, 6, 46 }, { 280, 4, 70 }, { 286, 11, 26 }, + { 288, 4, 72 }, { 290, 5, 58 }, { 294, 7, 42 }, + { 296, 4, 74 }, { 300, 5, 60 }, { 304, 4, 76 }, + { 306, 9, 34 }, { 308, 11, 28 }, { 310, 5, 62 }, + { 312, 4, 78 }, { 320, 4, 80 }, { 322, 7, 46 }, + { 324, 6, 54 }, { 328, 4, 82 }, { 330, 11, 30 }, + { 336, 4, 84 }, { 340, 5, 68 }, { 342, 9, 38 }, + { 344, 4, 86 }, { 348, 6, 58 }, { 350, 5, 70 }, + { 352, 11, 32 }, { 360, 4, 90 }, { 364, 7, 52 }, + { 368, 4, 92 }, { 370, 5, 74 }, { 372, 6, 62 }, + { 374, 11, 34 }, { 376, 4, 94 }, { 378, 7, 54 }, + { 380, 5, 76 }, { 384, 4, 96 }, { 390, 5, 78 }, + { 392, 4, 98 }, { 396, 11, 36 }, { 400, 4, 100 }, + { 406, 7, 58 }, { 408, 4, 102 }, { 410, 5, 82 }, + { 414, 9, 46 }, { 416, 4, 104 }, { 418, 11, 38 }, + { 420, 5, 84 }, { 424, 4, 106 }, { 430, 5, 86 }, + { 432, 4, 108 }, { 434, 7, 62 }, { 440, 11, 40 }, + { 444, 6, 74 }, { 448, 4, 112 }, { 450, 5, 90 }, + { 456, 4, 114 }, { 460, 5, 92 }, { 462, 11, 42 }, + { 464, 4, 116 }, { 468, 6, 78 }, { 470, 5, 94 }, + { 472, 4, 118 }, { 476, 7, 68 }, { 480, 4, 120 }, + { 484, 11, 44 }, { 486, 9, 54 }, { 488, 4, 122 }, + { 490, 5, 98 }, { 492, 6, 82 }, { 496, 4, 124 }, + { 500, 5, 100 }, { 504, 4, 126 }, { 506, 11, 46 }, + { 510, 5, 102 }, { 512, 4, 128 }, { 516, 6, 86 }, + { 518, 7, 74 }, { 520, 5, 104 }, { 522, 9, 58 }, + { 528, 11, 48 }, { 530, 5, 106 }, { 532, 7, 76 }, + { 540, 5, 108 }, { 546, 7, 78 }, { 550, 11, 50 }, + { 552, 6, 92 }, { 558, 9, 62 }, { 560, 5, 112 }, + { 564, 6, 94 }, { 570, 5, 114 }, { 572, 11, 52 }, + { 574, 7, 82 }, { 576, 6, 96 }, { 580, 5, 116 }, + { 588, 6, 98 }, { 590, 5, 118 }, { 594, 11, 54 }, + { 600, 5, 120 }, { 602, 7, 86 }, { 610, 5, 122 }, + { 612, 6, 102 }, { 616, 11, 56 }, { 620, 5, 124 }, + { 624, 6, 104 }, { 630, 5, 126 }, { 636, 6, 106 }, + { 638, 11, 58 }, { 640, 5, 128 }, { 644, 7, 92 }, + { 648, 6, 108 }, { 658, 7, 94 }, { 660, 11, 60 }, + { 666, 9, 74 }, { 672, 6, 112 }, { 682, 11, 62 }, + { 684, 6, 114 }, { 686, 7, 98 }, { 696, 6, 116 }, + { 700, 7, 100 }, { 702, 9, 78 }, { 704, 11, 64 }, + { 708, 6, 118 }, { 714, 7, 102 }, { 720, 6, 120 }, + { 726, 11, 66 }, { 728, 7, 104 }, { 732, 6, 122 }, + { 738, 9, 82 }, { 742, 7, 106 }, { 744, 6, 124 }, + { 748, 11, 68 }, { 756, 6, 126 }, { 768, 6, 128 }, + { 770, 11, 70 }, { 774, 9, 86 }, { 784, 7, 112 }, + { 792, 11, 72 }, { 798, 7, 114 }, { 810, 9, 90 }, + { 812, 7, 116 }, { 814, 11, 74 }, { 826, 7, 118 }, + { 828, 9, 92 }, { 836, 11, 76 }, { 840, 7, 120 }, + { 846, 9, 94 }, { 854, 7, 122 }, { 858, 11, 78 }, + { 864, 9, 96 }, { 868, 7, 124 }, { 880, 11, 80 }, + { 882, 7, 126 }, { 896, 7, 128 }, { 900, 9, 100 }, + { 902, 11, 82 }, { 918, 9, 102 }, { 924, 11, 84 }, + { 936, 9, 104 }, { 946, 11, 86 }, { 954, 9, 106 }, + { 968, 11, 88 }, { 972, 9, 108 }, { 990, 11, 90 }, + { 1008, 9, 112 }, { 1012, 11, 92 }, { 1026, 9, 114 }, + { 1034, 11, 94 }, { 1044, 9, 116 }, { 1056, 11, 96 }, + { 1062, 9, 118 }, { 1078, 11, 98 }, { 1080, 9, 120 }, + { 1098, 9, 122 }, { 1100, 11, 100 }, { 1116, 9, 124 }, + { 1122, 11, 102 }, { 1134, 9, 126 }, { 1144, 11, 104 }, + { 1152, 9, 128 }, { 1166, 11, 106 }, { 1188, 11, 108 }, + { 1210, 11, 110 }, { 1232, 11, 112 }, { 1254, 11, 114 }, + { 1276, 11, 116 }, { 1298, 11, 118 }, { 1320, 11, 120 }, + { 1342, 11, 122 }, { 1364, 11, 124 }, { 1386, 11, 126 }, + { 1408, 11, 128 }, +}; + +bool cobalt_cpld_set_freq(struct cobalt *cobalt, unsigned f_out) +{ + const unsigned f_xtal = 39170000; /* xtal for si598 */ + unsigned long long dco; + unsigned long long rfreq; + unsigned delta = 0xffffffff; + unsigned i_best = 0; + unsigned i; + u8 n1, hsdiv; + u8 regs[6]; + int found = 0; + u16 clock_ctrl; + int retries = 3; + + for (i = 0; i < ARRAY_SIZE(multipliers); i++) { + unsigned mult = multipliers[i].mult; + unsigned d; + + dco = (unsigned long long)f_out * mult; + if (dco < DCO_MIN || dco > DCO_MAX) + continue; + d = ((dco << 28) + f_xtal / 2) % f_xtal; + if (d < delta) { + found = 1; + i_best = i; + delta = d; + } + } + if (!found) + return false; + dco = (unsigned long long)f_out * multipliers[i_best].mult; + n1 = multipliers[i_best].n1 - 1; + hsdiv = multipliers[i_best].hsdiv - 4; + rfreq = (dco << 28) / f_xtal; + + clock_ctrl = cpld_read(cobalt, SI570_CLOCK_CTRL); + clock_ctrl |= S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_FPGA_CTRL; + clock_ctrl |= S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_EN; + + regs[0] = (hsdiv << 5) | (n1 >> 2); + regs[1] = ((n1 & 0x3) << 6) | (rfreq >> 32); + regs[2] = (rfreq >> 24) & 0xff; + regs[3] = (rfreq >> 16) & 0xff; + regs[4] = (rfreq >> 8) & 0xff; + regs[5] = rfreq & 0xff; + + /* The sequence of clock_ctrl flags to set is very weird. It looks + like I have to reset it, then set the new frequency and reset it + again. It shouldn't be necessary to do a reset, but if I don't, + then a strange frequency is set (156.412034 MHz, or register values + 0x01, 0xc7, 0xfc, 0x7f, 0x53, 0x62). + */ + + cobalt_dbg(1, "%u: %02x %02x %02x %02x %02x %02x\n", f_out, + regs[0], regs[1], regs[2], regs[3], regs[4], regs[5]); + while (retries--) { + u8 read_regs[6]; + + cpld_write(cobalt, SI570_CLOCK_CTRL, + S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_EN | + S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_FPGA_CTRL); + usleep_range(10000, 15000); + cpld_write(cobalt, SI570_REG7, regs[0]); + cpld_write(cobalt, SI570_REG8, regs[1]); + cpld_write(cobalt, SI570_REG9, regs[2]); + cpld_write(cobalt, SI570_REG10, regs[3]); + cpld_write(cobalt, SI570_REG11, regs[4]); + cpld_write(cobalt, SI570_REG12, regs[5]); + cpld_write(cobalt, SI570_CLOCK_CTRL, + S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_EN | + S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_WR_TRIGGER); + usleep_range(10000, 15000); + cpld_write(cobalt, SI570_CLOCK_CTRL, + S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_EN | + S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_FPGA_CTRL); + usleep_range(10000, 15000); + read_regs[0] = cpld_read(cobalt, SI570_REG7); + read_regs[1] = cpld_read(cobalt, SI570_REG8); + read_regs[2] = cpld_read(cobalt, SI570_REG9); + read_regs[3] = cpld_read(cobalt, SI570_REG10); + read_regs[4] = cpld_read(cobalt, SI570_REG11); + read_regs[5] = cpld_read(cobalt, SI570_REG12); + cpld_write(cobalt, SI570_CLOCK_CTRL, + S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_EN | + S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_FPGA_CTRL | + S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_RST_TRIGGER); + usleep_range(10000, 15000); + cpld_write(cobalt, SI570_CLOCK_CTRL, + S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_EN); + usleep_range(10000, 15000); + + if (!memcmp(read_regs, regs, sizeof(read_regs))) + break; + cobalt_dbg(1, "retry: %02x %02x %02x %02x %02x %02x\n", + read_regs[0], read_regs[1], read_regs[2], + read_regs[3], read_regs[4], read_regs[5]); + } + if (2 - retries) + cobalt_info("Needed %d retries\n", 2 - retries); + + return true; +} diff --git a/drivers/media/pci/cobalt/cobalt-cpld.h b/drivers/media/pci/cobalt/cobalt-cpld.h new file mode 100644 index 000000000000..0fc88fd5fa7b --- /dev/null +++ b/drivers/media/pci/cobalt/cobalt-cpld.h @@ -0,0 +1,29 @@ +/* + * Cobalt CPLD functions + * + * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef COBALT_CPLD_H +#define COBALT_CPLD_H + +#include "cobalt-driver.h" + +void cobalt_cpld_status(struct cobalt *cobalt); +bool cobalt_cpld_set_freq(struct cobalt *cobalt, unsigned freq); + +#endif diff --git a/drivers/media/pci/cobalt/cobalt-driver.c b/drivers/media/pci/cobalt/cobalt-driver.c new file mode 100644 index 000000000000..0f2549ab4c2b --- /dev/null +++ b/drivers/media/pci/cobalt/cobalt-driver.c @@ -0,0 +1,821 @@ +/* + * cobalt driver initialization and card probing + * + * Derived from cx18-driver.c + * + * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include "cobalt-driver.h" +#include "cobalt-irq.h" +#include "cobalt-i2c.h" +#include "cobalt-v4l2.h" +#include "cobalt-flash.h" +#include "cobalt-alsa.h" +#include "cobalt-omnitek.h" + +/* add your revision and whatnot here */ +static struct pci_device_id cobalt_pci_tbl[] = { + {PCI_VENDOR_ID_CISCO, PCI_DEVICE_ID_COBALT, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0,} +}; + +MODULE_DEVICE_TABLE(pci, cobalt_pci_tbl); + +static atomic_t cobalt_instance = ATOMIC_INIT(0); + +int cobalt_debug; +module_param_named(debug, cobalt_debug, int, 0644); +MODULE_PARM_DESC(debug, "Debug level. Default: 0\n"); + +int cobalt_ignore_err; +module_param_named(ignore_err, cobalt_ignore_err, int, 0644); +MODULE_PARM_DESC(ignore_err, + "If set then ignore missing i2c adapters/receivers. Default: 0\n"); + +MODULE_AUTHOR("Hans Verkuil & Morten Hestnes"); +MODULE_DESCRIPTION("cobalt driver"); +MODULE_LICENSE("GPL"); + +static u8 edid[256] = { + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x50, 0x21, 0x9C, 0x27, 0x00, 0x00, 0x00, 0x00, + 0x19, 0x12, 0x01, 0x03, 0x80, 0x00, 0x00, 0x78, + 0x0E, 0x00, 0xB2, 0xA0, 0x57, 0x49, 0x9B, 0x26, + 0x10, 0x48, 0x4F, 0x2F, 0xCF, 0x00, 0x31, 0x59, + 0x45, 0x59, 0x61, 0x59, 0x81, 0x99, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3A, + 0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 0x58, 0x2C, + 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, + 0x00, 0x00, 0x00, 0xFD, 0x00, 0x31, 0x55, 0x18, + 0x5E, 0x11, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x43, + 0x20, 0x39, 0x30, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, + 0x0A, 0x0A, 0x0A, 0x0A, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x68, + 0x02, 0x03, 0x1a, 0xc0, 0x48, 0xa2, 0x10, 0x04, + 0x02, 0x01, 0x21, 0x14, 0x13, 0x23, 0x09, 0x07, + 0x07, 0x65, 0x03, 0x0c, 0x00, 0x10, 0x00, 0xe2, + 0x00, 0x2a, 0x01, 0x1d, 0x00, 0x80, 0x51, 0xd0, + 0x1c, 0x20, 0x40, 0x80, 0x35, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1e, 0x8c, 0x0a, 0xd0, 0x8a, + 0x20, 0xe0, 0x2d, 0x10, 0x10, 0x3e, 0x96, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd7 +}; + +static void cobalt_set_interrupt(struct cobalt *cobalt, bool enable) +{ + if (enable) { + unsigned irqs = COBALT_SYSSTAT_VI0_INT1_MSK | + COBALT_SYSSTAT_VI1_INT1_MSK | + COBALT_SYSSTAT_VI2_INT1_MSK | + COBALT_SYSSTAT_VI3_INT1_MSK | + COBALT_SYSSTAT_VI0_INT2_MSK | + COBALT_SYSSTAT_VI1_INT2_MSK | + COBALT_SYSSTAT_VI2_INT2_MSK | + COBALT_SYSSTAT_VI3_INT2_MSK | + COBALT_SYSSTAT_VI0_LOST_DATA_MSK | + COBALT_SYSSTAT_VI1_LOST_DATA_MSK | + COBALT_SYSSTAT_VI2_LOST_DATA_MSK | + COBALT_SYSSTAT_VI3_LOST_DATA_MSK | + COBALT_SYSSTAT_AUD_IN_LOST_DATA_MSK; + + if (cobalt->have_hsma_rx) + irqs |= COBALT_SYSSTAT_VIHSMA_INT1_MSK | + COBALT_SYSSTAT_VIHSMA_INT2_MSK | + COBALT_SYSSTAT_VIHSMA_LOST_DATA_MSK; + + if (cobalt->have_hsma_tx) + irqs |= COBALT_SYSSTAT_VOHSMA_INT1_MSK | + COBALT_SYSSTAT_VOHSMA_LOST_DATA_MSK | + COBALT_SYSSTAT_AUD_OUT_LOST_DATA_MSK; + /* Clear any existing interrupts */ + cobalt_write_bar1(cobalt, COBALT_SYS_STAT_EDGE, 0xffffffff); + /* PIO Core interrupt mask register. + Enable ADV7604 INT1 interrupts */ + cobalt_write_bar1(cobalt, COBALT_SYS_STAT_MASK, irqs); + } else { + /* Disable all ADV7604 interrupts */ + cobalt_write_bar1(cobalt, COBALT_SYS_STAT_MASK, 0); + } +} + +static unsigned cobalt_get_sd_nr(struct v4l2_subdev *sd) +{ + struct cobalt *cobalt = to_cobalt(sd->v4l2_dev); + unsigned i; + + for (i = 0; i < COBALT_NUM_NODES; i++) + if (sd == cobalt->streams[i].sd) + return i; + cobalt_err("Invalid adv7604 subdev pointer!\n"); + return 0; +} + +static void cobalt_notify(struct v4l2_subdev *sd, + unsigned int notification, void *arg) +{ + struct cobalt *cobalt = to_cobalt(sd->v4l2_dev); + unsigned sd_nr = cobalt_get_sd_nr(sd); + struct cobalt_stream *s = &cobalt->streams[sd_nr]; + bool hotplug = arg ? *((int *)arg) : false; + + if (s->is_output) + return; + + switch (notification) { + case ADV76XX_HOTPLUG: + cobalt_s_bit_sysctrl(cobalt, + COBALT_SYS_CTRL_HPD_TO_CONNECTOR_BIT(sd_nr), hotplug); + cobalt_dbg(1, "Set hotplug for adv %d to %d\n", sd_nr, hotplug); + break; + case V4L2_DEVICE_NOTIFY_EVENT: + cobalt_dbg(1, "Format changed for adv %d\n", sd_nr); + v4l2_event_queue(&s->vdev, arg); + break; + default: + break; + } +} + +static int get_payload_size(u16 code) +{ + switch (code) { + case 0: return 128; + case 1: return 256; + case 2: return 512; + case 3: return 1024; + case 4: return 2048; + case 5: return 4096; + default: return 0; + } + return 0; +} + +static const char *get_link_speed(u16 stat) +{ + switch (stat & PCI_EXP_LNKSTA_CLS) { + case 1: return "2.5 Gbit/s"; + case 2: return "5 Gbit/s"; + case 3: return "10 Gbit/s"; + } + return "Unknown speed"; +} + +void cobalt_pcie_status_show(struct cobalt *cobalt) +{ + struct pci_dev *pci_dev = cobalt->pci_dev; + struct pci_dev *pci_bus_dev = cobalt->pci_dev->bus->self; + int offset; + int bus_offset; + u32 capa; + u16 stat, ctrl; + + offset = pci_find_capability(pci_dev, PCI_CAP_ID_EXP); + bus_offset = pci_find_capability(pci_bus_dev, PCI_CAP_ID_EXP); + + /* Device */ + pci_read_config_dword(pci_dev, offset + PCI_EXP_DEVCAP, &capa); + pci_read_config_word(pci_dev, offset + PCI_EXP_DEVCTL, &ctrl); + pci_read_config_word(pci_dev, offset + PCI_EXP_DEVSTA, &stat); + cobalt_info("PCIe device capability 0x%08x: Max payload %d\n", + capa, get_payload_size(capa & PCI_EXP_DEVCAP_PAYLOAD)); + cobalt_info("PCIe device control 0x%04x: Max payload %d. Max read request %d\n", + ctrl, + get_payload_size((ctrl & PCI_EXP_DEVCTL_PAYLOAD) >> 5), + get_payload_size((ctrl & PCI_EXP_DEVCTL_READRQ) >> 12)); + cobalt_info("PCIe device status 0x%04x\n", stat); + + /* Link */ + pci_read_config_dword(pci_dev, offset + PCI_EXP_LNKCAP, &capa); + pci_read_config_word(pci_dev, offset + PCI_EXP_LNKCTL, &ctrl); + pci_read_config_word(pci_dev, offset + PCI_EXP_LNKSTA, &stat); + cobalt_info("PCIe link capability 0x%08x: %s per lane and %u lanes\n", + capa, get_link_speed(capa), + (capa & PCI_EXP_LNKCAP_MLW) >> 4); + cobalt_info("PCIe link control 0x%04x\n", ctrl); + cobalt_info("PCIe link status 0x%04x: %s per lane and %u lanes\n", + stat, get_link_speed(stat), + (stat & PCI_EXP_LNKSTA_NLW) >> 4); + + /* Bus */ + pci_read_config_dword(pci_bus_dev, bus_offset + PCI_EXP_LNKCAP, &capa); + cobalt_info("PCIe bus link capability 0x%08x: %s per lane and %u lanes\n", + capa, get_link_speed(capa), + (capa & PCI_EXP_LNKCAP_MLW) >> 4); + + /* Slot */ + pci_read_config_dword(pci_dev, offset + PCI_EXP_SLTCAP, &capa); + pci_read_config_word(pci_dev, offset + PCI_EXP_SLTCTL, &ctrl); + pci_read_config_word(pci_dev, offset + PCI_EXP_SLTSTA, &stat); + cobalt_info("PCIe slot capability 0x%08x\n", capa); + cobalt_info("PCIe slot control 0x%04x\n", ctrl); + cobalt_info("PCIe slot status 0x%04x\n", stat); +} + +static unsigned pcie_link_get_lanes(struct cobalt *cobalt) +{ + struct pci_dev *pci_dev = cobalt->pci_dev; + unsigned offset; + u16 link; + + offset = pci_find_capability(pci_dev, PCI_CAP_ID_EXP); + if (!offset) + return 0; + pci_read_config_word(pci_dev, offset + PCI_EXP_LNKSTA, &link); + return (link & PCI_EXP_LNKSTA_NLW) >> 4; +} + +static unsigned pcie_bus_link_get_lanes(struct cobalt *cobalt) +{ + struct pci_dev *pci_dev = cobalt->pci_dev->bus->self; + unsigned offset; + u32 link; + + offset = pci_find_capability(pci_dev, PCI_CAP_ID_EXP); + if (!offset) + return 0; + pci_read_config_dword(pci_dev, offset + PCI_EXP_LNKCAP, &link); + return (link & PCI_EXP_LNKCAP_MLW) >> 4; +} + +static void msi_config_show(struct cobalt *cobalt, struct pci_dev *pci_dev) +{ + u16 ctrl, data; + u32 adrs_l, adrs_h; + + pci_read_config_word(pci_dev, 0x52, &ctrl); + cobalt_info("MSI %s\n", ctrl & 1 ? "enable" : "disable"); + cobalt_info("MSI multiple message: Capable %u. Enable %u\n", + (1 << ((ctrl >> 1) & 7)), (1 << ((ctrl >> 4) & 7))); + if (ctrl & 0x80) + cobalt_info("MSI: 64-bit address capable\n"); + pci_read_config_dword(pci_dev, 0x54, &adrs_l); + pci_read_config_dword(pci_dev, 0x58, &adrs_h); + pci_read_config_word(pci_dev, 0x5c, &data); + if (ctrl & 0x80) + cobalt_info("MSI: Address 0x%08x%08x. Data 0x%04x\n", + adrs_h, adrs_l, data); + else + cobalt_info("MSI: Address 0x%08x. Data 0x%04x\n", + adrs_l, data); +} + +static void cobalt_pci_iounmap(struct cobalt *cobalt, struct pci_dev *pci_dev) +{ + if (cobalt->bar0) { + pci_iounmap(pci_dev, cobalt->bar0); + cobalt->bar0 = 0; + } + if (cobalt->bar1) { + pci_iounmap(pci_dev, cobalt->bar1); + cobalt->bar1 = 0; + } +} + +static void cobalt_free_msi(struct cobalt *cobalt, struct pci_dev *pci_dev) +{ + free_irq(pci_dev->irq, (void *)cobalt); + + if (cobalt->msi_enabled) + pci_disable_msi(pci_dev); +} + +static int cobalt_setup_pci(struct cobalt *cobalt, struct pci_dev *pci_dev, + const struct pci_device_id *pci_id) +{ + u32 ctrl; + int ret; + + cobalt_dbg(1, "enabling pci device\n"); + + ret = pci_enable_device(pci_dev); + if (ret) { + cobalt_err("can't enable device\n"); + return ret; + } + pci_set_master(pci_dev); + pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &cobalt->card_rev); + pci_read_config_word(pci_dev, PCI_DEVICE_ID, &cobalt->device_id); + + switch (cobalt->device_id) { + case PCI_DEVICE_ID_COBALT: + cobalt_info("PCI Express interface from Omnitek\n"); + break; + default: + cobalt_info("PCI Express interface provider is unknown!\n"); + break; + } + + if (pcie_link_get_lanes(cobalt) != 8) { + cobalt_err("PCI Express link width is not 8 lanes (%d)\n", + pcie_link_get_lanes(cobalt)); + if (pcie_bus_link_get_lanes(cobalt) < 8) + cobalt_err("The current slot only supports %d lanes, at least 8 are needed\n", + pcie_bus_link_get_lanes(cobalt)); + else + cobalt_err("The card is most likely not seated correctly in the PCIe slot\n"); + ret = -EIO; + goto err_disable; + } + + if (pci_set_dma_mask(pci_dev, DMA_BIT_MASK(64))) { + ret = pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32)); + if (ret) { + cobalt_err("no suitable DMA available\n"); + goto err_disable; + } + } + + ret = pci_request_regions(pci_dev, "cobalt"); + if (ret) { + cobalt_err("error requesting regions\n"); + goto err_disable; + } + + cobalt_pcie_status_show(cobalt); + + cobalt->bar0 = pci_iomap(pci_dev, 0, 0); + cobalt->bar1 = pci_iomap(pci_dev, 1, 0); + if (cobalt->bar1 == NULL) { + cobalt->bar1 = pci_iomap(pci_dev, 2, 0); + cobalt_info("64-bit BAR\n"); + } + if (!cobalt->bar0 || !cobalt->bar1) { + ret = -EIO; + goto err_release; + } + + /* Reset the video inputs before enabling any interrupts */ + ctrl = cobalt_read_bar1(cobalt, COBALT_SYS_CTRL_BASE); + cobalt_write_bar1(cobalt, COBALT_SYS_CTRL_BASE, ctrl & ~0xf00); + + /* Disable interrupts to prevent any spurious interrupts + from being generated. */ + cobalt_set_interrupt(cobalt, false); + + if (pci_enable_msi_range(pci_dev, 1, 1) < 1) { + cobalt_err("Could not enable MSI\n"); + cobalt->msi_enabled = false; + ret = -EIO; + goto err_release; + } + msi_config_show(cobalt, pci_dev); + cobalt->msi_enabled = true; + + /* Register IRQ */ + if (request_irq(pci_dev->irq, cobalt_irq_handler, IRQF_SHARED, + cobalt->v4l2_dev.name, (void *)cobalt)) { + cobalt_err("Failed to register irq %d\n", pci_dev->irq); + ret = -EIO; + goto err_msi; + } + + omni_sg_dma_init(cobalt); + return 0; + +err_msi: + pci_disable_msi(pci_dev); + +err_release: + cobalt_pci_iounmap(cobalt, pci_dev); + pci_release_regions(pci_dev); + +err_disable: + pci_disable_device(cobalt->pci_dev); + return ret; +} + +static int cobalt_hdl_info_get(struct cobalt *cobalt) +{ + int i; + + for (i = 0; i < COBALT_HDL_INFO_SIZE; i++) + cobalt->hdl_info[i] = + ioread8(cobalt->bar1 + COBALT_HDL_INFO_BASE + i); + cobalt->hdl_info[COBALT_HDL_INFO_SIZE - 1] = '\0'; + if (strstr(cobalt->hdl_info, COBALT_HDL_SEARCH_STR)) + return 0; + + return 1; +} + +static void cobalt_stream_struct_init(struct cobalt *cobalt) +{ + int i; + + for (i = 0; i < COBALT_NUM_STREAMS; i++) { + struct cobalt_stream *s = &cobalt->streams[i]; + + s->cobalt = cobalt; + s->flags = 0; + s->is_audio = false; + s->is_output = false; + s->is_dummy = true; + + /* The Memory DMA channels will always get a lower channel + * number than the FIFO DMA. Video input should map to the + * stream 0-3. The other can use stream struct from 4 and + * higher */ + if (i <= COBALT_HSMA_IN_NODE) { + s->dma_channel = i + cobalt->first_fifo_channel; + s->video_channel = i; + } else if (i >= COBALT_AUDIO_IN_STREAM && + i <= COBALT_AUDIO_IN_STREAM + 4) { + s->dma_channel = 6 + i - COBALT_AUDIO_IN_STREAM; + s->is_audio = true; + s->video_channel = i - COBALT_AUDIO_IN_STREAM; + } else if (i == COBALT_HSMA_OUT_NODE) { + s->dma_channel = 11; + s->is_output = true; + s->video_channel = 5; + } else if (i == COBALT_AUDIO_OUT_STREAM) { + s->dma_channel = 12; + s->is_audio = true; + s->is_output = true; + s->video_channel = 5; + } else { + /* FIXME: Memory DMA for debug purpose */ + s->dma_channel = i - COBALT_NUM_NODES; + } + cobalt_info("stream #%d -> dma channel #%d <- video channel %d\n", + i, s->dma_channel, s->video_channel); + } +} + +static int cobalt_subdevs_init(struct cobalt *cobalt) +{ + static struct adv76xx_platform_data adv7604_pdata = { + .disable_pwrdnb = 1, + .ain_sel = ADV7604_AIN7_8_9_NC_SYNC_3_1, + .bus_order = ADV7604_BUS_ORDER_BRG, + .blank_data = 1, + .op_656_range = 1, + .op_format_mode_sel = ADV7604_OP_FORMAT_MODE0, + .int1_config = ADV76XX_INT1_CONFIG_ACTIVE_HIGH, + .dr_str_data = ADV76XX_DR_STR_HIGH, + .dr_str_clk = ADV76XX_DR_STR_HIGH, + .dr_str_sync = ADV76XX_DR_STR_HIGH, + .hdmi_free_run_mode = 1, + .inv_vs_pol = 1, + .inv_hs_pol = 1, + }; + static struct i2c_board_info adv7604_info = { + .type = "adv7604", + .addr = 0x20, + .platform_data = &adv7604_pdata, + }; + + struct cobalt_stream *s = cobalt->streams; + int i; + + for (i = 0; i < COBALT_NUM_INPUTS; i++) { + struct v4l2_subdev_format sd_fmt = { + .pad = ADV7604_PAD_SOURCE, + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .format.code = MEDIA_BUS_FMT_YUYV8_1X16, + }; + struct v4l2_subdev_edid cobalt_edid = { + .pad = ADV76XX_PAD_HDMI_PORT_A, + .start_block = 0, + .blocks = 2, + .edid = edid, + }; + int err; + + s[i].pad_source = ADV7604_PAD_SOURCE; + s[i].i2c_adap = &cobalt->i2c_adap[i]; + if (s[i].i2c_adap->dev.parent == NULL) + continue; + cobalt_s_bit_sysctrl(cobalt, + COBALT_SYS_CTRL_NRESET_TO_HDMI_BIT(i), 1); + s[i].sd = v4l2_i2c_new_subdev_board(&cobalt->v4l2_dev, + s[i].i2c_adap, &adv7604_info, NULL); + if (!s[i].sd) { + if (cobalt_ignore_err) + continue; + return -ENODEV; + } + err = v4l2_subdev_call(s[i].sd, video, s_routing, + ADV76XX_PAD_HDMI_PORT_A, 0, 0); + if (err) + return err; + err = v4l2_subdev_call(s[i].sd, pad, set_edid, + &cobalt_edid); + if (err) + return err; + err = v4l2_subdev_call(s[i].sd, pad, set_fmt, NULL, + &sd_fmt); + if (err) + return err; + /* Reset channel video module */ + cobalt_s_bit_sysctrl(cobalt, + COBALT_SYS_CTRL_VIDEO_RX_RESETN_BIT(i), 0); + mdelay(2); + cobalt_s_bit_sysctrl(cobalt, + COBALT_SYS_CTRL_VIDEO_RX_RESETN_BIT(i), 1); + mdelay(1); + s[i].is_dummy = false; + cobalt->streams[i + COBALT_AUDIO_IN_STREAM].is_dummy = false; + } + return 0; +} + +static int cobalt_subdevs_hsma_init(struct cobalt *cobalt) +{ + static struct adv7842_platform_data adv7842_pdata = { + .disable_pwrdnb = 1, + .ain_sel = ADV7842_AIN1_2_3_NC_SYNC_1_2, + .bus_order = ADV7842_BUS_ORDER_RBG, + .op_format_mode_sel = ADV7842_OP_FORMAT_MODE0, + .blank_data = 1, + .op_656_range = 1, + .dr_str_data = 3, + .dr_str_clk = 3, + .dr_str_sync = 3, + .mode = ADV7842_MODE_HDMI, + .hdmi_free_run_enable = 1, + .vid_std_select = ADV7842_HDMI_COMP_VID_STD_HD_1250P, + .i2c_sdp_io = 0x4a, + .i2c_sdp = 0x48, + .i2c_cp = 0x22, + .i2c_vdp = 0x24, + .i2c_afe = 0x26, + .i2c_hdmi = 0x34, + .i2c_repeater = 0x32, + .i2c_edid = 0x36, + .i2c_infoframe = 0x3e, + .i2c_cec = 0x40, + .i2c_avlink = 0x42, + }; + static struct i2c_board_info adv7842_info = { + .type = "adv7842", + .addr = 0x20, + .platform_data = &adv7842_pdata, + }; + static struct v4l2_subdev_format sd_fmt = { + .pad = ADV7842_PAD_SOURCE, + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .format.code = MEDIA_BUS_FMT_YUYV8_1X16, + }; + static struct adv7511_platform_data adv7511_pdata = { + .i2c_edid = 0x7e >> 1, + .i2c_cec = 0x7c >> 1, + .cec_clk = 12000000, + }; + static struct i2c_board_info adv7511_info = { + .type = "adv7511", + .addr = 0x39, /* 0x39 or 0x3d */ + .platform_data = &adv7511_pdata, + }; + struct v4l2_subdev_edid cobalt_edid = { + .pad = ADV7842_EDID_PORT_A, + .start_block = 0, + .blocks = 2, + .edid = edid, + }; + struct cobalt_stream *s = &cobalt->streams[COBALT_HSMA_IN_NODE]; + + s->i2c_adap = &cobalt->i2c_adap[COBALT_NUM_ADAPTERS - 1]; + if (s->i2c_adap->dev.parent == NULL) + return 0; + cobalt_s_bit_sysctrl(cobalt, COBALT_SYS_CTRL_NRESET_TO_HDMI_BIT(4), 1); + + s->sd = v4l2_i2c_new_subdev_board(&cobalt->v4l2_dev, + s->i2c_adap, &adv7842_info, NULL); + if (s->sd) { + int err = v4l2_subdev_call(s->sd, pad, set_edid, &cobalt_edid); + + if (err) + return err; + err = v4l2_subdev_call(s->sd, pad, set_fmt, NULL, + &sd_fmt); + if (err) + return err; + cobalt->have_hsma_rx = true; + s->pad_source = ADV7842_PAD_SOURCE; + s->is_dummy = false; + cobalt->streams[4 + COBALT_AUDIO_IN_STREAM].is_dummy = false; + /* Reset channel video module */ + cobalt_s_bit_sysctrl(cobalt, + COBALT_SYS_CTRL_VIDEO_RX_RESETN_BIT(4), 0); + mdelay(2); + cobalt_s_bit_sysctrl(cobalt, + COBALT_SYS_CTRL_VIDEO_RX_RESETN_BIT(4), 1); + mdelay(1); + return err; + } + cobalt_s_bit_sysctrl(cobalt, COBALT_SYS_CTRL_NRESET_TO_HDMI_BIT(4), 0); + cobalt_s_bit_sysctrl(cobalt, COBALT_SYS_CTRL_PWRDN0_TO_HSMA_TX_BIT, 0); + s++; + s->i2c_adap = &cobalt->i2c_adap[COBALT_NUM_ADAPTERS - 1]; + s->sd = v4l2_i2c_new_subdev_board(&cobalt->v4l2_dev, + s->i2c_adap, &adv7511_info, NULL); + if (s->sd) { + /* A transmitter is hooked up, so we can set this bit */ + cobalt_s_bit_sysctrl(cobalt, + COBALT_SYS_CTRL_HSMA_TX_ENABLE_BIT, 1); + cobalt_s_bit_sysctrl(cobalt, + COBALT_SYS_CTRL_VIDEO_RX_RESETN_BIT(4), 0); + cobalt_s_bit_sysctrl(cobalt, + COBALT_SYS_CTRL_VIDEO_TX_RESETN_BIT, 1); + cobalt->have_hsma_tx = true; + v4l2_subdev_call(s->sd, core, s_power, 1); + v4l2_subdev_call(s->sd, video, s_stream, 1); + v4l2_subdev_call(s->sd, audio, s_stream, 1); + v4l2_ctrl_s_ctrl(v4l2_ctrl_find(s->sd->ctrl_handler, + V4L2_CID_DV_TX_MODE), V4L2_DV_TX_MODE_HDMI); + s->is_dummy = false; + cobalt->streams[COBALT_AUDIO_OUT_STREAM].is_dummy = false; + return 0; + } + return -ENODEV; +} + +static int cobalt_probe(struct pci_dev *pci_dev, + const struct pci_device_id *pci_id) +{ + struct cobalt *cobalt; + int retval = 0; + int i; + + /* FIXME - module parameter arrays constrain max instances */ + i = atomic_inc_return(&cobalt_instance) - 1; + + cobalt = kzalloc(sizeof(struct cobalt), GFP_ATOMIC); + if (cobalt == NULL) + return -ENOMEM; + cobalt->pci_dev = pci_dev; + cobalt->instance = i; + + cobalt->alloc_ctx = vb2_dma_sg_init_ctx(&pci_dev->dev); + if (IS_ERR(cobalt->alloc_ctx)) { + kfree(cobalt); + return -ENOMEM; + } + + retval = v4l2_device_register(&pci_dev->dev, &cobalt->v4l2_dev); + if (retval) { + pr_err("cobalt: v4l2_device_register of card %d failed\n", + cobalt->instance); + vb2_dma_sg_cleanup_ctx(cobalt->alloc_ctx); + kfree(cobalt); + return retval; + } + snprintf(cobalt->v4l2_dev.name, sizeof(cobalt->v4l2_dev.name), + "cobalt-%d", cobalt->instance); + cobalt->v4l2_dev.notify = cobalt_notify; + cobalt_info("Initializing card %d\n", cobalt->instance); + + cobalt->irq_work_queues = + create_singlethread_workqueue(cobalt->v4l2_dev.name); + if (cobalt->irq_work_queues == NULL) { + cobalt_err("Could not create workqueue\n"); + retval = -ENOMEM; + goto err; + } + + INIT_WORK(&cobalt->irq_work_queue, cobalt_irq_work_handler); + + /* PCI Device Setup */ + retval = cobalt_setup_pci(cobalt, pci_dev, pci_id); + if (retval != 0) + goto err_wq; + + /* Show HDL version info */ + if (cobalt_hdl_info_get(cobalt)) + cobalt_info("Not able to read the HDL info\n"); + else + cobalt_info("%s", cobalt->hdl_info); + + retval = cobalt_i2c_init(cobalt); + if (retval) + goto err_pci; + + cobalt_stream_struct_init(cobalt); + + retval = cobalt_subdevs_init(cobalt); + if (retval) + goto err_i2c; + + if (!(cobalt_read_bar1(cobalt, COBALT_SYS_STAT_BASE) & + COBALT_SYSSTAT_HSMA_PRSNTN_MSK)) { + retval = cobalt_subdevs_hsma_init(cobalt); + if (retval) + goto err_i2c; + } + + retval = v4l2_device_register_subdev_nodes(&cobalt->v4l2_dev); + if (retval) + goto err_i2c; + retval = cobalt_nodes_register(cobalt); + if (retval) { + cobalt_err("Error %d registering device nodes\n", retval); + goto err_i2c; + } + cobalt_set_interrupt(cobalt, true); + v4l2_device_call_all(&cobalt->v4l2_dev, 0, core, + interrupt_service_routine, 0, NULL); + + cobalt_info("Initialized cobalt card\n"); + + cobalt_flash_probe(cobalt); + + return 0; + +err_i2c: + cobalt_i2c_exit(cobalt); + cobalt_s_bit_sysctrl(cobalt, COBALT_SYS_CTRL_HSMA_TX_ENABLE_BIT, 0); +err_pci: + cobalt_free_msi(cobalt, pci_dev); + cobalt_pci_iounmap(cobalt, pci_dev); + pci_release_regions(cobalt->pci_dev); + pci_disable_device(cobalt->pci_dev); +err_wq: + destroy_workqueue(cobalt->irq_work_queues); +err: + if (retval == 0) + retval = -ENODEV; + cobalt_err("error %d on initialization\n", retval); + + v4l2_device_unregister(&cobalt->v4l2_dev); + vb2_dma_sg_cleanup_ctx(cobalt->alloc_ctx); + kfree(cobalt); + return retval; +} + +static void cobalt_remove(struct pci_dev *pci_dev) +{ + struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); + struct cobalt *cobalt = to_cobalt(v4l2_dev); + int i; + + cobalt_flash_remove(cobalt); + cobalt_set_interrupt(cobalt, false); + flush_workqueue(cobalt->irq_work_queues); + cobalt_nodes_unregister(cobalt); + for (i = 0; i < COBALT_NUM_ADAPTERS; i++) { + struct v4l2_subdev *sd = cobalt->streams[i].sd; + struct i2c_client *client; + + if (sd == NULL) + continue; + client = v4l2_get_subdevdata(sd); + v4l2_device_unregister_subdev(sd); + i2c_unregister_device(client); + } + cobalt_i2c_exit(cobalt); + cobalt_free_msi(cobalt, pci_dev); + cobalt_s_bit_sysctrl(cobalt, COBALT_SYS_CTRL_HSMA_TX_ENABLE_BIT, 0); + cobalt_pci_iounmap(cobalt, pci_dev); + pci_release_regions(cobalt->pci_dev); + pci_disable_device(cobalt->pci_dev); + destroy_workqueue(cobalt->irq_work_queues); + + cobalt_info("removed cobalt card\n"); + + v4l2_device_unregister(v4l2_dev); + vb2_dma_sg_cleanup_ctx(cobalt->alloc_ctx); + kfree(cobalt); +} + +/* define a pci_driver for card detection */ +static struct pci_driver cobalt_pci_driver = { + .name = "cobalt", + .id_table = cobalt_pci_tbl, + .probe = cobalt_probe, + .remove = cobalt_remove, +}; + +module_pci_driver(cobalt_pci_driver); diff --git a/drivers/media/pci/cobalt/cobalt-driver.h b/drivers/media/pci/cobalt/cobalt-driver.h new file mode 100644 index 000000000000..082bf8255759 --- /dev/null +++ b/drivers/media/pci/cobalt/cobalt-driver.h @@ -0,0 +1,377 @@ +/* + * cobalt driver internal defines and structures + * + * Derived from cx18-driver.h + * + * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef COBALT_DRIVER_H +#define COBALT_DRIVER_H + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "m00233_video_measure_memmap_package.h" +#include "m00235_fdma_packer_memmap_package.h" +#include "m00389_cvi_memmap_package.h" +#include "m00460_evcnt_memmap_package.h" +#include "m00473_freewheel_memmap_package.h" +#include "m00479_clk_loss_detector_memmap_package.h" +#include "m00514_syncgen_flow_evcnt_memmap_package.h" + +/* System device ID */ +#define PCI_DEVICE_ID_COBALT 0x2732 + +/* Number of cobalt device nodes. */ +#define COBALT_NUM_INPUTS 4 +#define COBALT_NUM_NODES 6 + +/* Number of cobalt device streams. */ +#define COBALT_NUM_STREAMS 12 + +#define COBALT_HSMA_IN_NODE 4 +#define COBALT_HSMA_OUT_NODE 5 + +/* Cobalt audio streams */ +#define COBALT_AUDIO_IN_STREAM 6 +#define COBALT_AUDIO_OUT_STREAM 11 + +/* DMA stuff */ +#define DMA_CHANNELS_MAX 16 + +/* i2c stuff */ +#define I2C_CLIENTS_MAX 16 +#define COBALT_NUM_ADAPTERS 5 + +#define COBALT_CLK 50000000 + +/* System status register */ +#define COBALT_SYSSTAT_DIP0_MSK (1 << 0) +#define COBALT_SYSSTAT_DIP1_MSK (1 << 1) +#define COBALT_SYSSTAT_HSMA_PRSNTN_MSK (1 << 2) +#define COBALT_SYSSTAT_FLASH_RDYBSYN_MSK (1 << 3) +#define COBALT_SYSSTAT_VI0_5V_MSK (1 << 4) +#define COBALT_SYSSTAT_VI0_INT1_MSK (1 << 5) +#define COBALT_SYSSTAT_VI0_INT2_MSK (1 << 6) +#define COBALT_SYSSTAT_VI0_LOST_DATA_MSK (1 << 7) +#define COBALT_SYSSTAT_VI1_5V_MSK (1 << 8) +#define COBALT_SYSSTAT_VI1_INT1_MSK (1 << 9) +#define COBALT_SYSSTAT_VI1_INT2_MSK (1 << 10) +#define COBALT_SYSSTAT_VI1_LOST_DATA_MSK (1 << 11) +#define COBALT_SYSSTAT_VI2_5V_MSK (1 << 12) +#define COBALT_SYSSTAT_VI2_INT1_MSK (1 << 13) +#define COBALT_SYSSTAT_VI2_INT2_MSK (1 << 14) +#define COBALT_SYSSTAT_VI2_LOST_DATA_MSK (1 << 15) +#define COBALT_SYSSTAT_VI3_5V_MSK (1 << 16) +#define COBALT_SYSSTAT_VI3_INT1_MSK (1 << 17) +#define COBALT_SYSSTAT_VI3_INT2_MSK (1 << 18) +#define COBALT_SYSSTAT_VI3_LOST_DATA_MSK (1 << 19) +#define COBALT_SYSSTAT_VIHSMA_5V_MSK (1 << 20) +#define COBALT_SYSSTAT_VIHSMA_INT1_MSK (1 << 21) +#define COBALT_SYSSTAT_VIHSMA_INT2_MSK (1 << 22) +#define COBALT_SYSSTAT_VIHSMA_LOST_DATA_MSK (1 << 23) +#define COBALT_SYSSTAT_VOHSMA_INT1_MSK (1 << 25) +#define COBALT_SYSSTAT_VOHSMA_PLL_LOCKED_MSK (1 << 26) +#define COBALT_SYSSTAT_VOHSMA_LOST_DATA_MSK (1 << 27) +#define COBALT_SYSSTAT_AUD_PLL_LOCKED_MSK (1 << 28) +#define COBALT_SYSSTAT_AUD_IN_LOST_DATA_MSK (1 << 29) +#define COBALT_SYSSTAT_AUD_OUT_LOST_DATA_MSK (1 << 30) +#define COBALT_SYSSTAT_PCIE_SMBCLK_MSK (1 << 31) + +/* Cobalt memory map */ +#define COBALT_I2C_0_BASE 0x0 +#define COBALT_I2C_1_BASE 0x080 +#define COBALT_I2C_2_BASE 0x100 +#define COBALT_I2C_3_BASE 0x180 +#define COBALT_I2C_HSMA_BASE 0x200 + +#define COBALT_SYS_CTRL_BASE 0x400 +#define COBALT_SYS_CTRL_HSMA_TX_ENABLE_BIT 1 +#define COBALT_SYS_CTRL_VIDEO_RX_RESETN_BIT(n) (4 + 4 * (n)) +#define COBALT_SYS_CTRL_NRESET_TO_HDMI_BIT(n) (5 + 4 * (n)) +#define COBALT_SYS_CTRL_HPD_TO_CONNECTOR_BIT(n) (6 + 4 * (n)) +#define COBALT_SYS_CTRL_AUDIO_IPP_RESETN_BIT(n) (7 + 4 * (n)) +#define COBALT_SYS_CTRL_PWRDN0_TO_HSMA_TX_BIT 24 +#define COBALT_SYS_CTRL_VIDEO_TX_RESETN_BIT 25 +#define COBALT_SYS_CTRL_AUDIO_OPP_RESETN_BIT 27 + +#define COBALT_SYS_STAT_BASE 0x500 +#define COBALT_SYS_STAT_MASK (COBALT_SYS_STAT_BASE + 0x08) +#define COBALT_SYS_STAT_EDGE (COBALT_SYS_STAT_BASE + 0x0c) + +#define COBALT_HDL_INFO_BASE 0x4800 +#define COBALT_HDL_INFO_SIZE 0x200 + +#define COBALT_VID_BASE 0x10000 +#define COBALT_VID_SIZE 0x1000 + +#define COBALT_CVI(cobalt, c) \ + (cobalt->bar1 + COBALT_VID_BASE + (c) * COBALT_VID_SIZE) +#define COBALT_CVI_VMR(cobalt, c) \ + (cobalt->bar1 + COBALT_VID_BASE + (c) * COBALT_VID_SIZE + 0x100) +#define COBALT_CVI_EVCNT(cobalt, c) \ + (cobalt->bar1 + COBALT_VID_BASE + (c) * COBALT_VID_SIZE + 0x200) +#define COBALT_CVI_FREEWHEEL(cobalt, c) \ + (cobalt->bar1 + COBALT_VID_BASE + (c) * COBALT_VID_SIZE + 0x300) +#define COBALT_CVI_CLK_LOSS(cobalt, c) \ + (cobalt->bar1 + COBALT_VID_BASE + (c) * COBALT_VID_SIZE + 0x400) +#define COBALT_CVI_PACKER(cobalt, c) \ + (cobalt->bar1 + COBALT_VID_BASE + (c) * COBALT_VID_SIZE + 0x500) + +#define COBALT_TX_BASE(cobalt) (cobalt->bar1 + COBALT_VID_BASE + 0x5000) + +#define DMA_INTERRUPT_STATUS_REG 0x08 + +#define COBALT_HDL_SEARCH_STR "** HDL version info **" + +/* Cobalt CPU bus interface */ +#define COBALT_BUS_BAR1_BASE 0x600 +#define COBALT_BUS_SRAM_BASE 0x0 +#define COBALT_BUS_CPLD_BASE 0x00600000 +#define COBALT_BUS_FLASH_BASE 0x08000000 + +/* FDMA to PCIe packing */ +#define COBALT_BYTES_PER_PIXEL_YUYV 2 +#define COBALT_BYTES_PER_PIXEL_RGB24 3 +#define COBALT_BYTES_PER_PIXEL_RGB32 4 + +/* debugging */ +extern int cobalt_debug; +extern int cobalt_ignore_err; + +#define cobalt_err(fmt, arg...) v4l2_err(&cobalt->v4l2_dev, fmt, ## arg) +#define cobalt_warn(fmt, arg...) v4l2_warn(&cobalt->v4l2_dev, fmt, ## arg) +#define cobalt_info(fmt, arg...) v4l2_info(&cobalt->v4l2_dev, fmt, ## arg) +#define cobalt_dbg(level, fmt, arg...) \ + v4l2_dbg(level, cobalt_debug, &cobalt->v4l2_dev, fmt, ## arg) + +struct cobalt; +struct cobalt_i2c_regs; + +/* Per I2C bus private algo callback data */ +struct cobalt_i2c_data { + struct cobalt *cobalt; + volatile struct cobalt_i2c_regs __iomem *regs; +}; + +struct pci_consistent_buffer { + void *virt; + dma_addr_t bus; + size_t bytes; +}; + +struct sg_dma_desc_info { + void *virt; + dma_addr_t bus; + unsigned size; + void *last_desc_virt; + struct device *dev; +}; + +#define COBALT_MAX_WIDTH 1920 +#define COBALT_MAX_HEIGHT 1200 +#define COBALT_MAX_BPP 3 +#define COBALT_MAX_FRAMESZ \ + (COBALT_MAX_WIDTH * COBALT_MAX_HEIGHT * COBALT_MAX_BPP) + +#define NR_BUFS VIDEO_MAX_FRAME + +#define COBALT_STREAM_FL_DMA_IRQ 0 +#define COBALT_STREAM_FL_ADV_IRQ 1 + +struct cobalt_buffer { + struct vb2_buffer vb; + struct list_head list; +}; + +static inline struct cobalt_buffer *to_cobalt_buffer(struct vb2_buffer *vb2) +{ + return container_of(vb2, struct cobalt_buffer, vb); +} + +struct cobalt_stream { + struct video_device vdev; + struct vb2_queue q; + struct list_head bufs; + struct i2c_adapter *i2c_adap; + struct v4l2_subdev *sd; + struct mutex lock; + spinlock_t irqlock; + struct v4l2_dv_timings timings; + u32 input; + u32 pad_source; + u32 width, height, bpp; + u32 stride; + u32 pixfmt; + u32 sequence; + u32 colorspace; + u32 ycbcr_enc; + u32 quantization; + + u8 dma_channel; + int video_channel; + struct sg_dma_desc_info dma_desc_info[NR_BUFS]; + unsigned long flags; + bool unstable_frame; + bool enable_cvi; + bool enable_freewheel; + unsigned skip_first_frames; + bool is_output; + bool is_audio; + bool is_dummy; + + struct cobalt *cobalt; + struct snd_cobalt_card *alsa; +}; + +struct snd_cobalt_card; + +/* Struct to hold info about cobalt cards */ +struct cobalt { + int instance; + struct pci_dev *pci_dev; + struct v4l2_device v4l2_dev; + void *alloc_ctx; + + void __iomem *bar0, *bar1; + + u8 card_rev; + u16 device_id; + + /* device nodes */ + struct cobalt_stream streams[DMA_CHANNELS_MAX]; + struct i2c_adapter i2c_adap[COBALT_NUM_ADAPTERS]; + struct cobalt_i2c_data i2c_data[COBALT_NUM_ADAPTERS]; + bool have_hsma_rx; + bool have_hsma_tx; + + /* irq */ + struct workqueue_struct *irq_work_queues; + struct work_struct irq_work_queue; /* work entry */ + /* irq counters */ + u32 irq_adv1; + u32 irq_adv2; + u32 irq_advout; + u32 irq_dma_tot; + u32 irq_dma[COBALT_NUM_STREAMS]; + u32 irq_none; + u32 irq_full_fifo; + + bool msi_enabled; + + /* omnitek dma */ + int dma_channels; + int first_fifo_channel; + bool pci_32_bit; + + char hdl_info[COBALT_HDL_INFO_SIZE]; + + /* NOR flash */ + struct mtd_info *mtd; +}; + +static inline struct cobalt *to_cobalt(struct v4l2_device *v4l2_dev) +{ + return container_of(v4l2_dev, struct cobalt, v4l2_dev); +} + +static inline void cobalt_write_bar0(struct cobalt *cobalt, u32 reg, u32 val) +{ + iowrite32(val, cobalt->bar0 + reg); +} + +static inline u32 cobalt_read_bar0(struct cobalt *cobalt, u32 reg) +{ + return ioread32(cobalt->bar0 + reg); +} + +static inline void cobalt_write_bar1(struct cobalt *cobalt, u32 reg, u32 val) +{ + iowrite32(val, cobalt->bar1 + reg); +} + +static inline u32 cobalt_read_bar1(struct cobalt *cobalt, u32 reg) +{ + return ioread32(cobalt->bar1 + reg); +} + +static inline u32 cobalt_g_sysctrl(struct cobalt *cobalt) +{ + return cobalt_read_bar1(cobalt, COBALT_SYS_CTRL_BASE); +} + +static inline void cobalt_s_bit_sysctrl(struct cobalt *cobalt, + int bit, int val) +{ + u32 ctrl = cobalt_read_bar1(cobalt, COBALT_SYS_CTRL_BASE); + + cobalt_write_bar1(cobalt, COBALT_SYS_CTRL_BASE, + (ctrl & ~(1UL << bit)) | (val << bit)); +} + +static inline u32 cobalt_g_sysstat(struct cobalt *cobalt) +{ + return cobalt_read_bar1(cobalt, COBALT_SYS_STAT_BASE); +} + +#define ADRS_REG (cobalt->bar1 + COBALT_BUS_BAR1_BASE + 0) +#define LOWER_DATA (cobalt->bar1 + COBALT_BUS_BAR1_BASE + 4) +#define UPPER_DATA (cobalt->bar1 + COBALT_BUS_BAR1_BASE + 6) + +static inline u32 cobalt_bus_read32(struct cobalt *cobalt, u32 bus_adrs) +{ + iowrite32(bus_adrs, ADRS_REG); + return ioread32(LOWER_DATA); +} + +static inline void cobalt_bus_write16(struct cobalt *cobalt, + u32 bus_adrs, u16 data) +{ + iowrite32(bus_adrs, ADRS_REG); + if (bus_adrs & 2) + iowrite16(data, UPPER_DATA); + else + iowrite16(data, LOWER_DATA); +} + +static inline void cobalt_bus_write32(struct cobalt *cobalt, + u32 bus_adrs, u16 data) +{ + iowrite32(bus_adrs, ADRS_REG); + if (bus_adrs & 2) + iowrite32(data, UPPER_DATA); + else + iowrite32(data, LOWER_DATA); +} + +/*==============Prototypes==================*/ + +void cobalt_pcie_status_show(struct cobalt *cobalt); + +#endif diff --git a/drivers/media/pci/cobalt/cobalt-flash.c b/drivers/media/pci/cobalt/cobalt-flash.c new file mode 100644 index 000000000000..129f48ffe8a9 --- /dev/null +++ b/drivers/media/pci/cobalt/cobalt-flash.c @@ -0,0 +1,132 @@ +/* + * Cobalt NOR flash functions + * + * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include + +#include "cobalt-driver.h" + +#define ADRS(offset) (COBALT_BUS_FLASH_BASE + offset) + +static struct map_info cobalt_flash_map = { + .name = "cobalt-flash", + .bankwidth = 2, /* 16 bits */ + .size = 0x4000000, /* 64MB */ + .phys = 0, /* offset */ +}; + +static map_word flash_read16(struct map_info *map, unsigned long offset) +{ + struct cobalt *cobalt = map->virt; + map_word r; + + r.x[0] = cobalt_bus_read32(cobalt, ADRS(offset)); + if (offset & 0x2) + r.x[0] >>= 16; + else + r.x[0] &= 0x0000ffff; + + return r; +} + +static void flash_write16(struct map_info *map, const map_word datum, + unsigned long offset) +{ + struct cobalt *cobalt = map->virt; + u16 data = (u16)datum.x[0]; + + cobalt_bus_write16(cobalt, ADRS(offset), data); +} + +static void flash_copy_from(struct map_info *map, void *to, + unsigned long from, ssize_t len) +{ + struct cobalt *cobalt = map->virt; + u32 src = from; + u8 *dest = to; + u32 data; + + while (len) { + data = cobalt_bus_read32(cobalt, ADRS(src)); + do { + *dest = data >> (8 * (src & 3)); + src++; + dest++; + len--; + } while (len && (src % 4)); + } +} + +static void flash_copy_to(struct map_info *map, unsigned long to, + const void *from, ssize_t len) +{ + struct cobalt *cobalt = map->virt; + const u8 *src = from; + u32 dest = to; + + cobalt_info("%s: offset 0x%x: length %zu\n", __func__, dest, len); + while (len) { + u16 data = 0xffff; + + do { + data = *src << (8 * (dest & 1)); + src++; + dest++; + len--; + } while (len && (dest % 2)); + + cobalt_bus_write16(cobalt, ADRS(dest - 2), data); + } +} + +int cobalt_flash_probe(struct cobalt *cobalt) +{ + struct map_info *map = &cobalt_flash_map; + struct mtd_info *mtd; + + BUG_ON(!map_bankwidth_supported(map->bankwidth)); + map->virt = cobalt; + map->read = flash_read16; + map->write = flash_write16; + map->copy_from = flash_copy_from; + map->copy_to = flash_copy_to; + + mtd = do_map_probe("cfi_probe", map); + cobalt->mtd = mtd; + if (!mtd) { + cobalt_err("Probe CFI flash failed!\n"); + return -1; + } + + mtd->owner = THIS_MODULE; + mtd->dev.parent = &cobalt->pci_dev->dev; + mtd_device_register(mtd, NULL, 0); + return 0; +} + +void cobalt_flash_remove(struct cobalt *cobalt) +{ + if (cobalt->mtd) { + mtd_device_unregister(cobalt->mtd); + map_destroy(cobalt->mtd); + } +} diff --git a/drivers/media/pci/cobalt/cobalt-flash.h b/drivers/media/pci/cobalt/cobalt-flash.h new file mode 100644 index 000000000000..8077daea51cd --- /dev/null +++ b/drivers/media/pci/cobalt/cobalt-flash.h @@ -0,0 +1,29 @@ +/* + * Cobalt NOR flash functions + * + * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef COBALT_FLASH_H +#define COBALT_FLASH_H + +#include "cobalt-driver.h" + +int cobalt_flash_probe(struct cobalt *cobalt); +void cobalt_flash_remove(struct cobalt *cobalt); + +#endif diff --git a/drivers/media/pci/cobalt/cobalt-i2c.c b/drivers/media/pci/cobalt/cobalt-i2c.c new file mode 100644 index 000000000000..57b330f4f94b --- /dev/null +++ b/drivers/media/pci/cobalt/cobalt-i2c.c @@ -0,0 +1,396 @@ +/* + * cobalt I2C functions + * + * Derived from cx18-i2c.c + * + * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "cobalt-driver.h" +#include "cobalt-i2c.h" + +struct cobalt_i2c_regs { + /* Clock prescaler register lo-byte */ + u8 prerlo; + u8 dummy0[3]; + /* Clock prescaler register high-byte */ + u8 prerhi; + u8 dummy1[3]; + /* Control register */ + u8 ctr; + u8 dummy2[3]; + /* Transmit/Receive register */ + u8 txr_rxr; + u8 dummy3[3]; + /* Command and Status register */ + u8 cr_sr; + u8 dummy4[3]; +}; + +/* CTR[7:0] - Control register */ + +/* I2C Core enable bit */ +#define M00018_CTR_BITMAP_EN_MSK (1 << 7) + +/* I2C Core interrupt enable bit */ +#define M00018_CTR_BITMAP_IEN_MSK (1 << 6) + +/* CR[7:0] - Command register */ + +/* I2C start condition */ +#define M00018_CR_BITMAP_STA_MSK (1 << 7) + +/* I2C stop condition */ +#define M00018_CR_BITMAP_STO_MSK (1 << 6) + +/* I2C read from slave */ +#define M00018_CR_BITMAP_RD_MSK (1 << 5) + +/* I2C write to slave */ +#define M00018_CR_BITMAP_WR_MSK (1 << 4) + +/* I2C ack */ +#define M00018_CR_BITMAP_ACK_MSK (1 << 3) + +/* I2C Interrupt ack */ +#define M00018_CR_BITMAP_IACK_MSK (1 << 0) + +/* SR[7:0] - Status register */ + +/* Receive acknowledge from slave */ +#define M00018_SR_BITMAP_RXACK_MSK (1 << 7) + +/* Busy, I2C bus busy (as defined by start / stop bits) */ +#define M00018_SR_BITMAP_BUSY_MSK (1 << 6) + +/* Arbitration lost - core lost arbitration */ +#define M00018_SR_BITMAP_AL_MSK (1 << 5) + +/* Transfer in progress */ +#define M00018_SR_BITMAP_TIP_MSK (1 << 1) + +/* Interrupt flag */ +#define M00018_SR_BITMAP_IF_MSK (1 << 0) + +/* Frequency, in Hz */ +#define I2C_FREQUENCY 400000 +#define ALT_CPU_FREQ 83333333 + +static volatile struct cobalt_i2c_regs __iomem * +cobalt_i2c_regs(struct cobalt *cobalt, unsigned idx) +{ + switch (idx) { + case 0: + default: + return (volatile struct cobalt_i2c_regs __iomem *) + (cobalt->bar1 + COBALT_I2C_0_BASE); + case 1: + return (volatile struct cobalt_i2c_regs __iomem *) + (cobalt->bar1 + COBALT_I2C_1_BASE); + case 2: + return (volatile struct cobalt_i2c_regs __iomem *) + (cobalt->bar1 + COBALT_I2C_2_BASE); + case 3: + return (volatile struct cobalt_i2c_regs __iomem *) + (cobalt->bar1 + COBALT_I2C_3_BASE); + case 4: + return (volatile struct cobalt_i2c_regs __iomem *) + (cobalt->bar1 + COBALT_I2C_HSMA_BASE); + } +} + +/* Do low-level i2c byte transfer. + * Returns -1 in case of an error or 0 otherwise. + */ +static int cobalt_tx_bytes(volatile struct cobalt_i2c_regs __iomem *regs, + struct i2c_adapter *adap, bool start, bool stop, + u8 *data, u16 len) +{ + unsigned long start_time; + int status; + int cmd; + int i; + + for (i = 0; i < len; i++) { + /* Setup data */ + regs->txr_rxr = data[i]; + + /* Setup command */ + if (i == 0 && start != 0) { + /* Write + Start */ + cmd = M00018_CR_BITMAP_WR_MSK | + M00018_CR_BITMAP_STA_MSK; + } else if (i == len - 1 && stop != 0) { + /* Write + Stop */ + cmd = M00018_CR_BITMAP_WR_MSK | + M00018_CR_BITMAP_STO_MSK; + } else { + /* Write only */ + cmd = M00018_CR_BITMAP_WR_MSK; + } + + /* Execute command */ + regs->cr_sr = cmd; + + /* Wait for transfer to complete (TIP = 0) */ + start_time = jiffies; + status = regs->cr_sr; + while (status & M00018_SR_BITMAP_TIP_MSK) { + if (time_after(jiffies, start_time + adap->timeout)) + return -ETIMEDOUT; + cond_resched(); + status = regs->cr_sr; + } + + /* Verify ACK */ + if (status & M00018_SR_BITMAP_RXACK_MSK) { + /* NO ACK! */ + return -EIO; + } + + /* Verify arbitration */ + if (status & M00018_SR_BITMAP_AL_MSK) { + /* Arbitration lost! */ + return -EIO; + } + } + return 0; +} + +/* Do low-level i2c byte read. + * Returns -1 in case of an error or 0 otherwise. + */ +static int cobalt_rx_bytes(volatile struct cobalt_i2c_regs __iomem *regs, + struct i2c_adapter *adap, bool start, bool stop, + u8 *data, u16 len) +{ + unsigned long start_time; + int status; + int cmd; + int i; + + for (i = 0; i < len; i++) { + /* Setup command */ + if (i == 0 && start != 0) { + /* Read + Start */ + cmd = M00018_CR_BITMAP_RD_MSK | + M00018_CR_BITMAP_STA_MSK; + } else if (i == len - 1 && stop != 0) { + /* Read + Stop */ + cmd = M00018_CR_BITMAP_RD_MSK | + M00018_CR_BITMAP_STO_MSK; + } else { + /* Read only */ + cmd = M00018_CR_BITMAP_RD_MSK; + } + + /* Last byte to read, no ACK */ + if (i == len - 1) + cmd |= M00018_CR_BITMAP_ACK_MSK; + + /* Execute command */ + regs->cr_sr = cmd; + + /* Wait for transfer to complete (TIP = 0) */ + start_time = jiffies; + status = regs->cr_sr; + while (status & M00018_SR_BITMAP_TIP_MSK) { + if (time_after(jiffies, start_time + adap->timeout)) + return -ETIMEDOUT; + cond_resched(); + status = regs->cr_sr; + } + + /* Verify arbitration */ + if (status & M00018_SR_BITMAP_AL_MSK) { + /* Arbitration lost! */ + return -EIO; + } + + /* Store data */ + data[i] = regs->txr_rxr; + } + return 0; +} + +/* Generate stop condition on i2c bus. + * The m00018 stop isn't doing the right thing (wrong timing). + * So instead send a start condition, 8 zeroes and a stop condition. + */ +static int cobalt_stop(volatile struct cobalt_i2c_regs __iomem *regs, + struct i2c_adapter *adap) +{ + u8 data = 0; + + return cobalt_tx_bytes(regs, adap, true, true, &data, 1); +} + +static int cobalt_xfer(struct i2c_adapter *adap, + struct i2c_msg msgs[], int num) +{ + struct cobalt_i2c_data *data = adap->algo_data; + volatile struct cobalt_i2c_regs __iomem *regs = data->regs; + struct i2c_msg *pmsg; + unsigned short flags; + int ret = 0; + int i, j; + + for (i = 0; i < num; i++) { + int stop = (i == num - 1); + + pmsg = &msgs[i]; + flags = pmsg->flags; + + if (!(pmsg->flags & I2C_M_NOSTART)) { + u8 addr = pmsg->addr << 1; + + if (flags & I2C_M_RD) + addr |= 1; + if (flags & I2C_M_REV_DIR_ADDR) + addr ^= 1; + for (j = 0; j < adap->retries; j++) { + ret = cobalt_tx_bytes(regs, adap, true, false, + &addr, 1); + if (!ret) + break; + cobalt_stop(regs, adap); + } + if (ret < 0) + return ret; + ret = 0; + } + if (pmsg->flags & I2C_M_RD) { + /* read bytes into buffer */ + ret = cobalt_rx_bytes(regs, adap, false, stop, + pmsg->buf, pmsg->len); + if (ret < 0) + goto bailout; + } else { + /* write bytes from buffer */ + ret = cobalt_tx_bytes(regs, adap, false, stop, + pmsg->buf, pmsg->len); + if (ret < 0) + goto bailout; + } + } + ret = i; + +bailout: + if (ret < 0) + cobalt_stop(regs, adap); + return ret; +} + +static u32 cobalt_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +/* template for i2c-bit-algo */ +static struct i2c_adapter cobalt_i2c_adap_template = { + .name = "cobalt i2c driver", + .algo = NULL, /* set by i2c-algo-bit */ + .algo_data = NULL, /* filled from template */ + .owner = THIS_MODULE, +}; + +static const struct i2c_algorithm cobalt_algo = { + .master_xfer = cobalt_xfer, + .functionality = cobalt_func, +}; + +/* init + register i2c algo-bit adapter */ +int cobalt_i2c_init(struct cobalt *cobalt) +{ + int i, err; + int status; + int prescale; + unsigned long start_time; + + cobalt_dbg(1, "i2c init\n"); + + /* Define I2C clock prescaler */ + prescale = ((ALT_CPU_FREQ) / (5 * I2C_FREQUENCY)) - 1; + + for (i = 0; i < COBALT_NUM_ADAPTERS; i++) { + volatile struct cobalt_i2c_regs __iomem *regs = + cobalt_i2c_regs(cobalt, i); + struct i2c_adapter *adap = &cobalt->i2c_adap[i]; + + /* Disable I2C */ + regs->cr_sr = M00018_CTR_BITMAP_EN_MSK; + regs->ctr = 0; + regs->cr_sr = 0; + + start_time = jiffies; + do { + if (time_after(jiffies, start_time + HZ)) { + if (cobalt_ignore_err) { + adap->dev.parent = NULL; + return 0; + } + return -ETIMEDOUT; + } + status = regs->cr_sr; + } while (status & M00018_SR_BITMAP_TIP_MSK); + + /* Disable I2C */ + regs->ctr = 0; + regs->cr_sr = 0; + + /* Calculate i2c prescaler */ + regs->prerlo = prescale & 0xff; + regs->prerhi = (prescale >> 8) & 0xff; + /* Enable I2C, interrupts disabled */ + regs->ctr = M00018_CTR_BITMAP_EN_MSK; + /* Setup algorithm for adapter */ + cobalt->i2c_data[i].cobalt = cobalt; + cobalt->i2c_data[i].regs = regs; + *adap = cobalt_i2c_adap_template; + adap->algo = &cobalt_algo; + adap->algo_data = &cobalt->i2c_data[i]; + adap->retries = 3; + sprintf(adap->name + strlen(adap->name), + " #%d-%d", cobalt->instance, i); + i2c_set_adapdata(adap, &cobalt->v4l2_dev); + adap->dev.parent = &cobalt->pci_dev->dev; + err = i2c_add_adapter(adap); + if (err) { + if (cobalt_ignore_err) { + adap->dev.parent = NULL; + return 0; + } + while (i--) + i2c_del_adapter(&cobalt->i2c_adap[i]); + return err; + } + cobalt_info("registered bus %s\n", adap->name); + } + return 0; +} + +void cobalt_i2c_exit(struct cobalt *cobalt) +{ + int i; + + cobalt_dbg(1, "i2c exit\n"); + + for (i = 0; i < COBALT_NUM_ADAPTERS; i++) { + cobalt_err("unregistered bus %s\n", cobalt->i2c_adap[i].name); + i2c_del_adapter(&cobalt->i2c_adap[i]); + } +} diff --git a/drivers/media/pci/cobalt/cobalt-i2c.h b/drivers/media/pci/cobalt/cobalt-i2c.h new file mode 100644 index 000000000000..a4c1cfaacf95 --- /dev/null +++ b/drivers/media/pci/cobalt/cobalt-i2c.h @@ -0,0 +1,25 @@ +/* + * cobalt I2C functions + * + * Derived from cx18-i2c.h + * + * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* init + register i2c algo-bit adapter */ +int cobalt_i2c_init(struct cobalt *cobalt); +void cobalt_i2c_exit(struct cobalt *cobalt); diff --git a/drivers/media/pci/cobalt/cobalt-irq.c b/drivers/media/pci/cobalt/cobalt-irq.c new file mode 100644 index 000000000000..e18f49e6f0e3 --- /dev/null +++ b/drivers/media/pci/cobalt/cobalt-irq.c @@ -0,0 +1,254 @@ +/* + * cobalt interrupt handling + * + * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include + +#include "cobalt-driver.h" +#include "cobalt-irq.h" +#include "cobalt-omnitek.h" + +static void cobalt_dma_stream_queue_handler(struct cobalt_stream *s) +{ + struct cobalt *cobalt = s->cobalt; + int rx = s->video_channel; + volatile struct m00473_freewheel_regmap __iomem *fw = + COBALT_CVI_FREEWHEEL(s->cobalt, rx); + volatile struct m00233_video_measure_regmap __iomem *vmr = + COBALT_CVI_VMR(s->cobalt, rx); + volatile struct m00389_cvi_regmap __iomem *cvi = + COBALT_CVI(s->cobalt, rx); + volatile struct m00479_clk_loss_detector_regmap __iomem *clkloss = + COBALT_CVI_CLK_LOSS(s->cobalt, rx); + struct cobalt_buffer *cb; + bool skip = false; + + spin_lock(&s->irqlock); + + if (list_empty(&s->bufs)) { + pr_err("no buffers!\n"); + spin_unlock(&s->irqlock); + return; + } + + /* Give the fresh filled up buffer to the user. + * Note that the interrupt is only sent if the DMA can continue + * with a new buffer, so it is always safe to return this buffer + * to userspace. */ + cb = list_first_entry(&s->bufs, struct cobalt_buffer, list); + list_del(&cb->list); + spin_unlock(&s->irqlock); + + if (s->is_audio || s->is_output) + goto done; + + if (s->unstable_frame) { + uint32_t stat = vmr->irq_status; + + vmr->irq_status = stat; + if (!(vmr->status & M00233_STATUS_BITMAP_INIT_DONE_MSK)) { + cobalt_dbg(1, "!init_done\n"); + if (s->enable_freewheel) + goto restart_fw; + goto done; + } + + if (clkloss->status & M00479_STATUS_BITMAP_CLOCK_MISSING_MSK) { + clkloss->ctrl = 0; + clkloss->ctrl = M00479_CTRL_BITMAP_ENABLE_MSK; + cobalt_dbg(1, "no clock\n"); + if (s->enable_freewheel) + goto restart_fw; + goto done; + } + if ((stat & (M00233_IRQ_STATUS_BITMAP_VACTIVE_AREA_MSK | + M00233_IRQ_STATUS_BITMAP_HACTIVE_AREA_MSK)) || + vmr->vactive_area != s->timings.bt.height || + vmr->hactive_area != s->timings.bt.width) { + cobalt_dbg(1, "unstable\n"); + if (s->enable_freewheel) + goto restart_fw; + goto done; + } + if (!s->enable_cvi) { + s->enable_cvi = true; + cvi->control = M00389_CONTROL_BITMAP_ENABLE_MSK; + goto done; + } + if (!(cvi->status & M00389_STATUS_BITMAP_LOCK_MSK)) { + cobalt_dbg(1, "cvi no lock\n"); + if (s->enable_freewheel) + goto restart_fw; + goto done; + } + if (!s->enable_freewheel) { + cobalt_dbg(1, "stable\n"); + s->enable_freewheel = true; + fw->ctrl = 0; + goto done; + } + cobalt_dbg(1, "enabled fw\n"); + vmr->control = M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK | + M00233_CONTROL_BITMAP_ENABLE_INTERRUPT_MSK; + fw->ctrl = M00473_CTRL_BITMAP_ENABLE_MSK; + s->enable_freewheel = false; + s->unstable_frame = false; + s->skip_first_frames = 2; + skip = true; + goto done; + } + if (fw->status & M00473_STATUS_BITMAP_FREEWHEEL_MODE_MSK) { +restart_fw: + cobalt_dbg(1, "lost lock\n"); + vmr->control = M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK; + fw->ctrl = M00473_CTRL_BITMAP_ENABLE_MSK | + M00473_CTRL_BITMAP_FORCE_FREEWHEEL_MODE_MSK; + cvi->control = 0; + s->unstable_frame = true; + s->enable_freewheel = false; + s->enable_cvi = false; + } +done: + if (s->skip_first_frames) { + skip = true; + s->skip_first_frames--; + } + v4l2_get_timestamp(&cb->vb.v4l2_buf.timestamp); + /* TODO: the sequence number should be read from the FPGA so we + also know about dropped frames. */ + cb->vb.v4l2_buf.sequence = s->sequence++; + vb2_buffer_done(&cb->vb, (skip || s->unstable_frame) ? + VB2_BUF_STATE_QUEUED : VB2_BUF_STATE_DONE); +} + +irqreturn_t cobalt_irq_handler(int irq, void *dev_id) +{ + struct cobalt *cobalt = (struct cobalt *)dev_id; + u32 dma_interrupt = + cobalt_read_bar0(cobalt, DMA_INTERRUPT_STATUS_REG) & 0xffff; + u32 mask = cobalt_read_bar1(cobalt, COBALT_SYS_STAT_MASK); + u32 edge = cobalt_read_bar1(cobalt, COBALT_SYS_STAT_EDGE); + int i; + + /* Clear DMA interrupt */ + cobalt_write_bar0(cobalt, DMA_INTERRUPT_STATUS_REG, dma_interrupt); + cobalt_write_bar1(cobalt, COBALT_SYS_STAT_MASK, mask & ~edge); + cobalt_write_bar1(cobalt, COBALT_SYS_STAT_EDGE, edge); + + for (i = 0; i < COBALT_NUM_STREAMS; i++) { + struct cobalt_stream *s = &cobalt->streams[i]; + unsigned dma_fifo_mask = + COBALT_SYSSTAT_VI0_LOST_DATA_MSK << (4 * s->video_channel); + + if (dma_interrupt & (1 << s->dma_channel)) { + cobalt->irq_dma[i]++; + /* Give fresh buffer to user and chain newly + * queued buffers */ + cobalt_dma_stream_queue_handler(s); + if (!s->is_audio) { + edge &= ~dma_fifo_mask; + cobalt_write_bar1(cobalt, COBALT_SYS_STAT_MASK, + mask & ~edge); + } + } + if (s->is_audio) + continue; + if (edge & (0x20 << (4 * s->video_channel))) + set_bit(COBALT_STREAM_FL_ADV_IRQ, &s->flags); + if ((edge & mask & dma_fifo_mask) && vb2_is_streaming(&s->q)) { + cobalt_info("full rx FIFO %d\n", i); + cobalt->irq_full_fifo++; + } + } + + queue_work(cobalt->irq_work_queues, &cobalt->irq_work_queue); + + if (edge & mask & (COBALT_SYSSTAT_VI0_INT1_MSK | + COBALT_SYSSTAT_VI1_INT1_MSK | + COBALT_SYSSTAT_VI2_INT1_MSK | + COBALT_SYSSTAT_VI3_INT1_MSK | + COBALT_SYSSTAT_VIHSMA_INT1_MSK | + COBALT_SYSSTAT_VOHSMA_INT1_MSK)) + cobalt->irq_adv1++; + if (edge & mask & (COBALT_SYSSTAT_VI0_INT2_MSK | + COBALT_SYSSTAT_VI1_INT2_MSK | + COBALT_SYSSTAT_VI2_INT2_MSK | + COBALT_SYSSTAT_VI3_INT2_MSK | + COBALT_SYSSTAT_VIHSMA_INT2_MSK)) + cobalt->irq_adv2++; + if (edge & mask & COBALT_SYSSTAT_VOHSMA_INT1_MSK) + cobalt->irq_advout++; + if (dma_interrupt) + cobalt->irq_dma_tot++; + if (!(edge & mask) && !dma_interrupt) + cobalt->irq_none++; + dma_interrupt = cobalt_read_bar0(cobalt, DMA_INTERRUPT_STATUS_REG); + + return IRQ_HANDLED; +} + +void cobalt_irq_work_handler(struct work_struct *work) +{ + struct cobalt *cobalt = + container_of(work, struct cobalt, irq_work_queue); + int i; + + for (i = 0; i < COBALT_NUM_NODES; i++) { + struct cobalt_stream *s = &cobalt->streams[i]; + + if (test_and_clear_bit(COBALT_STREAM_FL_ADV_IRQ, &s->flags)) { + u32 mask; + + v4l2_subdev_call(cobalt->streams[i].sd, core, + interrupt_service_routine, 0, NULL); + mask = cobalt_read_bar1(cobalt, COBALT_SYS_STAT_MASK); + cobalt_write_bar1(cobalt, COBALT_SYS_STAT_MASK, + mask | (0x20 << (4 * s->video_channel))); + } + } +} + +void cobalt_irq_log_status(struct cobalt *cobalt) +{ + u32 mask; + int i; + + cobalt_info("irq: adv1=%u adv2=%u advout=%u none=%u full=%u\n", + cobalt->irq_adv1, cobalt->irq_adv2, cobalt->irq_advout, + cobalt->irq_none, cobalt->irq_full_fifo); + cobalt_info("irq: dma_tot=%u (", cobalt->irq_dma_tot); + for (i = 0; i < COBALT_NUM_STREAMS; i++) + pr_cont("%s%u", i ? "/" : "", cobalt->irq_dma[i]); + pr_cont(")\n"); + cobalt->irq_dma_tot = cobalt->irq_adv1 = cobalt->irq_adv2 = 0; + cobalt->irq_advout = cobalt->irq_none = cobalt->irq_full_fifo = 0; + memset(cobalt->irq_dma, 0, sizeof(cobalt->irq_dma)); + + mask = cobalt_read_bar1(cobalt, COBALT_SYS_STAT_MASK); + cobalt_write_bar1(cobalt, COBALT_SYS_STAT_MASK, + mask | + COBALT_SYSSTAT_VI0_LOST_DATA_MSK | + COBALT_SYSSTAT_VI1_LOST_DATA_MSK | + COBALT_SYSSTAT_VI2_LOST_DATA_MSK | + COBALT_SYSSTAT_VI3_LOST_DATA_MSK | + COBALT_SYSSTAT_VIHSMA_LOST_DATA_MSK | + COBALT_SYSSTAT_VOHSMA_LOST_DATA_MSK | + COBALT_SYSSTAT_AUD_IN_LOST_DATA_MSK | + COBALT_SYSSTAT_AUD_OUT_LOST_DATA_MSK); +} diff --git a/drivers/media/pci/cobalt/cobalt-irq.h b/drivers/media/pci/cobalt/cobalt-irq.h new file mode 100644 index 000000000000..5119484a24d9 --- /dev/null +++ b/drivers/media/pci/cobalt/cobalt-irq.h @@ -0,0 +1,25 @@ +/* + * cobalt interrupt handling + * + * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include + +irqreturn_t cobalt_irq_handler(int irq, void *dev_id); +void cobalt_irq_work_handler(struct work_struct *work); +void cobalt_irq_log_status(struct cobalt *cobalt); diff --git a/drivers/media/pci/cobalt/cobalt-omnitek.c b/drivers/media/pci/cobalt/cobalt-omnitek.c new file mode 100644 index 000000000000..560445846235 --- /dev/null +++ b/drivers/media/pci/cobalt/cobalt-omnitek.c @@ -0,0 +1,341 @@ +/* + * Omnitek Scatter-Gather DMA Controller + * + * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include + +#include "cobalt-driver.h" +#include "cobalt-omnitek.h" + +/* descriptor */ +#define END_OF_CHAIN (1 << 1) +#define INTERRUPT_ENABLE (1 << 2) +#define WRITE_TO_PCI (1 << 3) +#define READ_FROM_PCI (0 << 3) +#define DESCRIPTOR_FLAG_MSK (END_OF_CHAIN | INTERRUPT_ENABLE | WRITE_TO_PCI) +#define NEXT_ADRS_MSK 0xffffffe0 + +/* control/status register */ +#define ENABLE (1 << 0) +#define START (1 << 1) +#define ABORT (1 << 2) +#define DONE (1 << 4) +#define SG_INTERRUPT (1 << 5) +#define EVENT_INTERRUPT (1 << 6) +#define SCATTER_GATHER_MODE (1 << 8) +#define DISABLE_VIDEO_RESYNC (1 << 9) +#define EVENT_INTERRUPT_ENABLE (1 << 10) +#define DIRECTIONAL_MSK (3 << 16) +#define INPUT_ONLY (0 << 16) +#define OUTPUT_ONLY (1 << 16) +#define BIDIRECTIONAL (2 << 16) +#define DMA_TYPE_MEMORY (0 << 18) +#define DMA_TYPE_FIFO (1 << 18) + +#define BASE (cobalt->bar0) +#define CAPABILITY_HEADER (BASE) +#define CAPABILITY_REGISTER (BASE + 0x04) +#define PCI_64BIT (1 << 8) +#define LOCAL_64BIT (1 << 9) +#define INTERRUPT_STATUS (BASE + 0x08) +#define PCI(c) (BASE + 0x40 + ((c) * 0x40)) +#define SIZE(c) (BASE + 0x58 + ((c) * 0x40)) +#define DESCRIPTOR(c) (BASE + 0x50 + ((c) * 0x40)) +#define CS_REG(c) (BASE + 0x60 + ((c) * 0x40)) +#define BYTES_TRANSFERRED(c) (BASE + 0x64 + ((c) * 0x40)) + + +static char *get_dma_direction(u32 status) +{ + switch (status & DIRECTIONAL_MSK) { + case INPUT_ONLY: return "Input"; + case OUTPUT_ONLY: return "Output"; + case BIDIRECTIONAL: return "Bidirectional"; + } + return ""; +} + +static void show_dma_capability(struct cobalt *cobalt) +{ + u32 header = ioread32(CAPABILITY_HEADER); + u32 capa = ioread32(CAPABILITY_REGISTER); + u32 i; + + cobalt_info("Omnitek DMA capability: ID 0x%02x Version 0x%02x Next 0x%x Size 0x%x\n", + header & 0xff, (header >> 8) & 0xff, + (header >> 16) & 0xffff, (capa >> 24) & 0xff); + + switch ((capa >> 8) & 0x3) { + case 0: + cobalt_info("Omnitek DMA: 32 bits PCIe and Local\n"); + break; + case 1: + cobalt_info("Omnitek DMA: 64 bits PCIe, 32 bits Local\n"); + break; + case 3: + cobalt_info("Omnitek DMA: 64 bits PCIe and Local\n"); + break; + } + + for (i = 0; i < (capa & 0xf); i++) { + u32 status = ioread32(CS_REG(i)); + + cobalt_info("Omnitek DMA channel #%d: %s %s\n", i, + status & DMA_TYPE_FIFO ? "FIFO" : "MEMORY", + get_dma_direction(status)); + } +} + +void omni_sg_dma_start(struct cobalt_stream *s, struct sg_dma_desc_info *desc) +{ + struct cobalt *cobalt = s->cobalt; + + iowrite32((u32)(desc->bus >> 32), DESCRIPTOR(s->dma_channel) + 4); + iowrite32((u32)desc->bus & NEXT_ADRS_MSK, DESCRIPTOR(s->dma_channel)); + iowrite32(ENABLE | SCATTER_GATHER_MODE | START, CS_REG(s->dma_channel)); +} + +bool is_dma_done(struct cobalt_stream *s) +{ + struct cobalt *cobalt = s->cobalt; + + if (ioread32(CS_REG(s->dma_channel)) & DONE) + return true; + + return false; +} + +void omni_sg_dma_abort_channel(struct cobalt_stream *s) +{ + struct cobalt *cobalt = s->cobalt; + + if (is_dma_done(s) == false) + iowrite32(ABORT, CS_REG(s->dma_channel)); +} + +int omni_sg_dma_init(struct cobalt *cobalt) +{ + u32 capa = ioread32(CAPABILITY_REGISTER); + int i; + + cobalt->first_fifo_channel = 0; + cobalt->dma_channels = capa & 0xf; + if (capa & PCI_64BIT) + cobalt->pci_32_bit = false; + else + cobalt->pci_32_bit = true; + + for (i = 0; i < cobalt->dma_channels; i++) { + u32 status = ioread32(CS_REG(i)); + u32 ctrl = ioread32(CS_REG(i)); + + if (!(ctrl & DONE)) + iowrite32(ABORT, CS_REG(i)); + + if (!(status & DMA_TYPE_FIFO)) + cobalt->first_fifo_channel++; + } + show_dma_capability(cobalt); + return 0; +} + +int descriptor_list_create(struct cobalt *cobalt, + struct scatterlist *scatter_list, bool to_pci, unsigned sglen, + unsigned size, unsigned width, unsigned stride, + struct sg_dma_desc_info *desc) +{ + struct sg_dma_descriptor *d = (struct sg_dma_descriptor *)desc->virt; + dma_addr_t next = desc->bus; + unsigned offset = 0; + unsigned copy_bytes = width; + unsigned copied = 0; + bool first = true; + + /* Must be 4-byte aligned */ + WARN_ON(sg_dma_address(scatter_list) & 3); + WARN_ON(size & 3); + WARN_ON(next & 3); + WARN_ON(stride & 3); + WARN_ON(stride < width); + if (width >= stride) + copy_bytes = stride = size; + + while (size) { + dma_addr_t addr = sg_dma_address(scatter_list) + offset; + unsigned bytes; + + if (addr == 0) + return -EFAULT; + if (cobalt->pci_32_bit) { + WARN_ON((u64)addr >> 32); + if ((u64)addr >> 32) + return -EFAULT; + } + + /* PCIe address */ + d->pci_l = addr & 0xffffffff; + /* If dma_addr_t is 32 bits, then addr >> 32 is actually the + equivalent of addr >> 0 in gcc. So must cast to u64. */ + d->pci_h = (u64)addr >> 32; + + /* Sync to start of streaming frame */ + d->local = 0; + d->reserved0 = 0; + + /* Transfer bytes */ + bytes = min(sg_dma_len(scatter_list) - offset, + copy_bytes - copied); + + if (first) { + if (to_pci) + d->local = 0x11111111; + first = false; + if (sglen == 1) { + /* Make sure there are always at least two + * descriptors */ + d->bytes = (bytes / 2) & ~3; + d->reserved1 = 0; + size -= d->bytes; + copied += d->bytes; + offset += d->bytes; + addr += d->bytes; + next += sizeof(struct sg_dma_descriptor); + d->next_h = (u32)(next >> 32); + d->next_l = (u32)next | + (to_pci ? WRITE_TO_PCI : 0); + bytes -= d->bytes; + d++; + /* PCIe address */ + d->pci_l = addr & 0xffffffff; + /* If dma_addr_t is 32 bits, then addr >> 32 + * is actually the equivalent of addr >> 0 in + * gcc. So must cast to u64. */ + d->pci_h = (u64)addr >> 32; + + /* Sync to start of streaming frame */ + d->local = 0; + d->reserved0 = 0; + } + } + + d->bytes = bytes; + d->reserved1 = 0; + size -= bytes; + copied += bytes; + offset += bytes; + + if (copied == copy_bytes) { + while (copied < stride) { + bytes = min(sg_dma_len(scatter_list) - offset, + stride - copied); + copied += bytes; + offset += bytes; + size -= bytes; + if (sg_dma_len(scatter_list) == offset) { + offset = 0; + scatter_list = sg_next(scatter_list); + } + } + copied = 0; + } else { + offset = 0; + scatter_list = sg_next(scatter_list); + } + + /* Next descriptor + control bits */ + next += sizeof(struct sg_dma_descriptor); + if (size == 0) { + /* Loopback to the first descriptor */ + d->next_h = (u32)(desc->bus >> 32); + d->next_l = (u32)desc->bus | + (to_pci ? WRITE_TO_PCI : 0) | INTERRUPT_ENABLE; + if (!to_pci) + d->local = 0x22222222; + desc->last_desc_virt = d; + } else { + d->next_h = (u32)(next >> 32); + d->next_l = (u32)next | (to_pci ? WRITE_TO_PCI : 0); + } + d++; + } + return 0; +} + +void descriptor_list_chain(struct sg_dma_desc_info *this, + struct sg_dma_desc_info *next) +{ + struct sg_dma_descriptor *d = this->last_desc_virt; + u32 direction = d->next_l & WRITE_TO_PCI; + + if (next == NULL) { + d->next_h = 0; + d->next_l = direction | INTERRUPT_ENABLE | END_OF_CHAIN; + } else { + d->next_h = (u32)(next->bus >> 32); + d->next_l = (u32)next->bus | direction | INTERRUPT_ENABLE; + } +} + +void *descriptor_list_allocate(struct sg_dma_desc_info *desc, size_t bytes) +{ + desc->size = bytes; + desc->virt = dma_alloc_coherent(desc->dev, bytes, + &desc->bus, GFP_KERNEL); + return desc->virt; +} + +void descriptor_list_free(struct sg_dma_desc_info *desc) +{ + if (desc->virt) + dma_free_coherent(desc->dev, desc->size, + desc->virt, desc->bus); + desc->virt = NULL; +} + +void descriptor_list_interrupt_enable(struct sg_dma_desc_info *desc) +{ + struct sg_dma_descriptor *d = desc->last_desc_virt; + + d->next_l |= INTERRUPT_ENABLE; +} + +void descriptor_list_interrupt_disable(struct sg_dma_desc_info *desc) +{ + struct sg_dma_descriptor *d = desc->last_desc_virt; + + d->next_l &= ~INTERRUPT_ENABLE; +} + +void descriptor_list_loopback(struct sg_dma_desc_info *desc) +{ + struct sg_dma_descriptor *d = desc->last_desc_virt; + + d->next_h = (u32)(desc->bus >> 32); + d->next_l = (u32)desc->bus | (d->next_l & DESCRIPTOR_FLAG_MSK); +} + +void descriptor_list_end_of_chain(struct sg_dma_desc_info *desc) +{ + struct sg_dma_descriptor *d = desc->last_desc_virt; + + d->next_l |= END_OF_CHAIN; +} diff --git a/drivers/media/pci/cobalt/cobalt-omnitek.h b/drivers/media/pci/cobalt/cobalt-omnitek.h new file mode 100644 index 000000000000..e5c6d032c6f2 --- /dev/null +++ b/drivers/media/pci/cobalt/cobalt-omnitek.h @@ -0,0 +1,62 @@ +/* + * Omnitek Scatter-Gather DMA Controller + * + * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef COBALT_OMNITEK_H +#define COBALT_OMNITEK_H + +#include +#include "cobalt-driver.h" + +struct sg_dma_descriptor { + u32 pci_l; + u32 pci_h; + + u32 local; + u32 reserved0; + + u32 next_l; + u32 next_h; + + u32 bytes; + u32 reserved1; +}; + +int omni_sg_dma_init(struct cobalt *cobalt); +void omni_sg_dma_abort_channel(struct cobalt_stream *s); +void omni_sg_dma_start(struct cobalt_stream *s, struct sg_dma_desc_info *desc); +bool is_dma_done(struct cobalt_stream *s); + +int descriptor_list_create(struct cobalt *cobalt, + struct scatterlist *scatter_list, bool to_pci, unsigned sglen, + unsigned size, unsigned width, unsigned stride, + struct sg_dma_desc_info *desc); + +void descriptor_list_chain(struct sg_dma_desc_info *this, + struct sg_dma_desc_info *next); +void descriptor_list_loopback(struct sg_dma_desc_info *desc); +void descriptor_list_end_of_chain(struct sg_dma_desc_info *desc); + +void *descriptor_list_allocate(struct sg_dma_desc_info *desc, size_t bytes); +void descriptor_list_free(struct sg_dma_desc_info *desc); + +void descriptor_list_interrupt_enable(struct sg_dma_desc_info *desc); +void descriptor_list_interrupt_disable(struct sg_dma_desc_info *desc); + +#endif diff --git a/drivers/media/pci/cobalt/cobalt-v4l2.c b/drivers/media/pci/cobalt/cobalt-v4l2.c new file mode 100644 index 000000000000..bf80f11d94d8 --- /dev/null +++ b/drivers/media/pci/cobalt/cobalt-v4l2.c @@ -0,0 +1,1260 @@ +/* + * cobalt V4L2 API + * + * Derived from ivtv-ioctl.c and cx18-fileops.c + * + * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "cobalt-alsa.h" +#include "cobalt-cpld.h" +#include "cobalt-driver.h" +#include "cobalt-v4l2.h" +#include "cobalt-irq.h" +#include "cobalt-omnitek.h" + +static const struct v4l2_dv_timings cea1080p60 = V4L2_DV_BT_CEA_1920X1080P60; + +/* vb2 DMA streaming ops */ + +static int cobalt_queue_setup(struct vb2_queue *q, + const struct v4l2_format *fmt, + unsigned int *num_buffers, unsigned int *num_planes, + unsigned int sizes[], void *alloc_ctxs[]) +{ + struct cobalt_stream *s = q->drv_priv; + unsigned size = s->stride * s->height; + + if (*num_buffers < 3) + *num_buffers = 3; + if (*num_buffers > NR_BUFS) + *num_buffers = NR_BUFS; + *num_planes = 1; + if (fmt) { + if (fmt->fmt.pix.sizeimage < size) + return -EINVAL; + size = fmt->fmt.pix.sizeimage; + } + sizes[0] = size; + alloc_ctxs[0] = s->cobalt->alloc_ctx; + return 0; +} + +static int cobalt_buf_init(struct vb2_buffer *vb) +{ + struct cobalt_stream *s = vb->vb2_queue->drv_priv; + struct cobalt *cobalt = s->cobalt; + const size_t max_pages_per_line = + (COBALT_MAX_WIDTH * COBALT_MAX_BPP) / PAGE_SIZE + 2; + const size_t bytes = + COBALT_MAX_HEIGHT * max_pages_per_line * 0x20; + const size_t audio_bytes = ((1920 * 4) / PAGE_SIZE + 1) * 0x20; + struct sg_dma_desc_info *desc = &s->dma_desc_info[vb->v4l2_buf.index]; + struct sg_table *sg_desc = vb2_dma_sg_plane_desc(vb, 0); + unsigned size; + int ret; + + size = s->stride * s->height; + if (vb2_plane_size(vb, 0) < size) { + cobalt_info("data will not fit into plane (%lu < %u)\n", + vb2_plane_size(vb, 0), size); + return -EINVAL; + } + + if (desc->virt == NULL) { + desc->dev = &cobalt->pci_dev->dev; + descriptor_list_allocate(desc, + s->is_audio ? audio_bytes : bytes); + if (desc->virt == NULL) + return -ENOMEM; + } + ret = descriptor_list_create(cobalt, sg_desc->sgl, + !s->is_output, sg_desc->nents, size, + s->width * s->bpp, s->stride, desc); + if (ret) + descriptor_list_free(desc); + return ret; +} + +static void cobalt_buf_cleanup(struct vb2_buffer *vb) +{ + struct cobalt_stream *s = vb->vb2_queue->drv_priv; + struct sg_dma_desc_info *desc = &s->dma_desc_info[vb->v4l2_buf.index]; + + descriptor_list_free(desc); +} + +static int cobalt_buf_prepare(struct vb2_buffer *vb) +{ + struct cobalt_stream *s = vb->vb2_queue->drv_priv; + + vb2_set_plane_payload(vb, 0, s->stride * s->height); + vb->v4l2_buf.field = V4L2_FIELD_NONE; + return 0; +} + +static void chain_all_buffers(struct cobalt_stream *s) +{ + struct sg_dma_desc_info *desc[NR_BUFS]; + struct cobalt_buffer *cb; + struct list_head *p; + int i = 0; + + list_for_each(p, &s->bufs) { + cb = list_entry(p, struct cobalt_buffer, list); + desc[i] = &s->dma_desc_info[cb->vb.v4l2_buf.index]; + if (i > 0) + descriptor_list_chain(desc[i-1], desc[i]); + i++; + } +} + +static void cobalt_buf_queue(struct vb2_buffer *vb) +{ + struct vb2_queue *q = vb->vb2_queue; + struct cobalt_stream *s = q->drv_priv; + struct cobalt_buffer *cb = to_cobalt_buffer(vb); + struct sg_dma_desc_info *desc = &s->dma_desc_info[vb->v4l2_buf.index]; + unsigned long flags; + + /* Prepare new buffer */ + descriptor_list_loopback(desc); + descriptor_list_interrupt_disable(desc); + + spin_lock_irqsave(&s->irqlock, flags); + list_add_tail(&cb->list, &s->bufs); + chain_all_buffers(s); + spin_unlock_irqrestore(&s->irqlock, flags); +} + +static void cobalt_enable_output(struct cobalt_stream *s) +{ + struct cobalt *cobalt = s->cobalt; + struct v4l2_bt_timings *bt = &s->timings.bt; + volatile struct m00514_syncgen_flow_evcnt_regmap __iomem *vo = + COBALT_TX_BASE(cobalt); + unsigned fmt = s->pixfmt != V4L2_PIX_FMT_BGR32 ? + M00514_CONTROL_BITMAP_FORMAT_16_BPP_MSK : 0; + struct v4l2_subdev_format sd_fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + + if (!cobalt_cpld_set_freq(cobalt, bt->pixelclock)) { + cobalt_err("pixelclock out of range\n"); + return; + } + + sd_fmt.format.colorspace = s->colorspace; + sd_fmt.format.ycbcr_enc = s->ycbcr_enc; + sd_fmt.format.quantization = s->quantization; + sd_fmt.format.width = bt->width; + sd_fmt.format.height = bt->height; + + /* Set up FDMA packer */ + switch (s->pixfmt) { + case V4L2_PIX_FMT_YUYV: + sd_fmt.format.code = MEDIA_BUS_FMT_UYVY8_1X16; + break; + case V4L2_PIX_FMT_BGR32: + sd_fmt.format.code = MEDIA_BUS_FMT_RGB888_1X24; + break; + } + v4l2_subdev_call(s->sd, pad, set_fmt, NULL, &sd_fmt); + + vo->control = 0; + /* 1080p60 */ + vo->sync_generator_h_sync_length = bt->hsync; + vo->sync_generator_h_backporch_length = bt->hbackporch; + vo->sync_generator_h_active_length = bt->width; + vo->sync_generator_h_frontporch_length = bt->hfrontporch; + vo->sync_generator_v_sync_length = bt->vsync; + vo->sync_generator_v_backporch_length = bt->vbackporch; + vo->sync_generator_v_active_length = bt->height; + vo->sync_generator_v_frontporch_length = bt->vfrontporch; + vo->error_color = 0x9900c1; + + vo->control = M00514_CONTROL_BITMAP_SYNC_GENERATOR_LOAD_PARAM_MSK | fmt; + vo->control = M00514_CONTROL_BITMAP_EVCNT_CLEAR_MSK | fmt; + vo->control = M00514_CONTROL_BITMAP_SYNC_GENERATOR_ENABLE_MSK | + M00514_CONTROL_BITMAP_FLOW_CTRL_OUTPUT_ENABLE_MSK | + fmt; +} + +static void cobalt_enable_input(struct cobalt_stream *s) +{ + struct cobalt *cobalt = s->cobalt; + int ch = (int)s->video_channel; + volatile struct m00235_fdma_packer_regmap __iomem *packer; + struct v4l2_subdev_format sd_fmt_yuyv = { + .pad = s->pad_source, + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .format.code = MEDIA_BUS_FMT_YUYV8_1X16, + }; + struct v4l2_subdev_format sd_fmt_rgb = { + .pad = s->pad_source, + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .format.code = MEDIA_BUS_FMT_RGB888_1X24, + }; + + cobalt_dbg(1, "video_channel %d (%s, %s)\n", + s->video_channel, + s->input == 0 ? "hdmi" : "generator", + "YUYV"); + + packer = COBALT_CVI_PACKER(cobalt, ch); + + /* Set up FDMA packer */ + switch (s->pixfmt) { + case V4L2_PIX_FMT_YUYV: + packer->control = M00235_CONTROL_BITMAP_ENABLE_MSK | + (1 << M00235_CONTROL_BITMAP_PACK_FORMAT_OFST); + v4l2_subdev_call(s->sd, pad, set_fmt, NULL, + &sd_fmt_yuyv); + break; + case V4L2_PIX_FMT_RGB24: + packer->control = M00235_CONTROL_BITMAP_ENABLE_MSK | + (2 << M00235_CONTROL_BITMAP_PACK_FORMAT_OFST); + v4l2_subdev_call(s->sd, pad, set_fmt, NULL, + &sd_fmt_rgb); + break; + case V4L2_PIX_FMT_BGR32: + packer->control = M00235_CONTROL_BITMAP_ENABLE_MSK | + M00235_CONTROL_BITMAP_ENDIAN_FORMAT_MSK | + (3 << M00235_CONTROL_BITMAP_PACK_FORMAT_OFST); + v4l2_subdev_call(s->sd, pad, set_fmt, NULL, + &sd_fmt_rgb); + break; + } +} + +static void cobalt_dma_start_streaming(struct cobalt_stream *s) +{ + struct cobalt *cobalt = s->cobalt; + int rx = s->video_channel; + volatile struct m00460_evcnt_regmap __iomem *evcnt = + COBALT_CVI_EVCNT(cobalt, rx); + struct cobalt_buffer *cb; + unsigned long flags; + + spin_lock_irqsave(&s->irqlock, flags); + if (!s->is_output) { + evcnt->control = M00460_CONTROL_BITMAP_CLEAR_MSK; + evcnt->control = M00460_CONTROL_BITMAP_ENABLE_MSK; + } else { + volatile struct m00514_syncgen_flow_evcnt_regmap __iomem *vo = + COBALT_TX_BASE(cobalt); + u32 ctrl = vo->control; + + ctrl &= ~(M00514_CONTROL_BITMAP_EVCNT_ENABLE_MSK | + M00514_CONTROL_BITMAP_EVCNT_CLEAR_MSK); + vo->control = ctrl | M00514_CONTROL_BITMAP_EVCNT_CLEAR_MSK; + vo->control = ctrl | M00514_CONTROL_BITMAP_EVCNT_ENABLE_MSK; + } + cb = list_first_entry(&s->bufs, struct cobalt_buffer, list); + omni_sg_dma_start(s, &s->dma_desc_info[cb->vb.v4l2_buf.index]); + spin_unlock_irqrestore(&s->irqlock, flags); +} + +static int cobalt_start_streaming(struct vb2_queue *q, unsigned int count) +{ + struct cobalt_stream *s = q->drv_priv; + struct cobalt *cobalt = s->cobalt; + volatile struct m00233_video_measure_regmap __iomem *vmr; + volatile struct m00473_freewheel_regmap __iomem *fw; + volatile struct m00479_clk_loss_detector_regmap __iomem *clkloss; + int rx = s->video_channel; + volatile struct m00389_cvi_regmap __iomem *cvi = + COBALT_CVI(cobalt, rx); + volatile struct m00460_evcnt_regmap __iomem *evcnt = + COBALT_CVI_EVCNT(cobalt, rx); + struct v4l2_bt_timings *bt = &s->timings.bt; + u64 tot_size; + + if (s->is_audio) + goto done; + if (s->is_output) { + s->unstable_frame = false; + cobalt_enable_output(s); + goto done; + } + + cobalt_enable_input(s); + + fw = COBALT_CVI_FREEWHEEL(cobalt, rx); + vmr = COBALT_CVI_VMR(cobalt, rx); + clkloss = COBALT_CVI_CLK_LOSS(cobalt, rx); + + evcnt->control = M00460_CONTROL_BITMAP_CLEAR_MSK; + evcnt->control = M00460_CONTROL_BITMAP_ENABLE_MSK; + cvi->frame_width = bt->width; + cvi->frame_height = bt->height; + tot_size = V4L2_DV_BT_FRAME_WIDTH(bt) * V4L2_DV_BT_FRAME_HEIGHT(bt); + vmr->hsync_timeout_val = + ((u64)V4L2_DV_BT_FRAME_WIDTH(bt) * COBALT_CLK * 4) / + bt->pixelclock; + vmr->control = M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK; + clkloss->ref_clk_cnt_val = fw->clk_freq / 1000000; + /* The lower bound for the clock frequency is 0.5% lower as is + * allowed by the spec */ + clkloss->test_clk_cnt_val = + (((u64)bt->pixelclock * 995) / 1000) / 1000000; + /* will be enabled after the first frame has been received */ + fw->active_length = bt->width * bt->height; + fw->total_length = ((u64)fw->clk_freq * tot_size) / bt->pixelclock; + vmr->irq_triggers = M00233_IRQ_TRIGGERS_BITMAP_VACTIVE_AREA_MSK | + M00233_IRQ_TRIGGERS_BITMAP_HACTIVE_AREA_MSK; + cvi->control = 0; + vmr->control = M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK; + + fw->output_color = 0xff; + clkloss->ctrl = M00479_CTRL_BITMAP_ENABLE_MSK; + fw->ctrl = M00473_CTRL_BITMAP_ENABLE_MSK | + M00473_CTRL_BITMAP_FORCE_FREEWHEEL_MODE_MSK; + s->unstable_frame = true; + s->enable_freewheel = false; + s->enable_cvi = false; + s->skip_first_frames = 0; + +done: + s->sequence = 0; + cobalt_dma_start_streaming(s); + return 0; +} + +static void cobalt_dma_stop_streaming(struct cobalt_stream *s) +{ + struct cobalt *cobalt = s->cobalt; + struct sg_dma_desc_info *desc; + struct cobalt_buffer *cb; + struct list_head *p; + unsigned long flags; + int timeout_msec = 100; + int rx = s->video_channel; + volatile struct m00460_evcnt_regmap __iomem *evcnt = + COBALT_CVI_EVCNT(cobalt, rx); + + if (!s->is_output) { + evcnt->control = 0; + } else if (!s->is_audio) { + volatile struct m00514_syncgen_flow_evcnt_regmap __iomem *vo = + COBALT_TX_BASE(cobalt); + + vo->control = M00514_CONTROL_BITMAP_EVCNT_CLEAR_MSK; + vo->control = 0; + } + + /* Try to stop the DMA engine gracefully */ + spin_lock_irqsave(&s->irqlock, flags); + list_for_each(p, &s->bufs) { + cb = list_entry(p, struct cobalt_buffer, list); + desc = &s->dma_desc_info[cb->vb.v4l2_buf.index]; + /* Stop DMA after this descriptor chain */ + descriptor_list_end_of_chain(desc); + } + spin_unlock_irqrestore(&s->irqlock, flags); + + /* Wait 100 milisecond for DMA to finish, abort on timeout. */ + if (!wait_event_timeout(s->q.done_wq, is_dma_done(s), + msecs_to_jiffies(timeout_msec))) { + omni_sg_dma_abort_channel(s); + pr_warn("aborted\n"); + } + cobalt_write_bar0(cobalt, DMA_INTERRUPT_STATUS_REG, + 1 << s->dma_channel); +} + +static void cobalt_stop_streaming(struct vb2_queue *q) +{ + struct cobalt_stream *s = q->drv_priv; + struct cobalt *cobalt = s->cobalt; + int rx = s->video_channel; + volatile struct m00233_video_measure_regmap __iomem *vmr; + volatile struct m00473_freewheel_regmap __iomem *fw; + volatile struct m00479_clk_loss_detector_regmap __iomem *clkloss; + struct cobalt_buffer *cb; + struct list_head *p, *safe; + unsigned long flags; + + cobalt_dma_stop_streaming(s); + + /* Return all buffers to user space */ + spin_lock_irqsave(&s->irqlock, flags); + list_for_each_safe(p, safe, &s->bufs) { + cb = list_entry(p, struct cobalt_buffer, list); + list_del(&cb->list); + vb2_buffer_done(&cb->vb, VB2_BUF_STATE_ERROR); + } + spin_unlock_irqrestore(&s->irqlock, flags); + + if (s->is_audio || s->is_output) + return; + + fw = COBALT_CVI_FREEWHEEL(cobalt, rx); + vmr = COBALT_CVI_VMR(cobalt, rx); + clkloss = COBALT_CVI_CLK_LOSS(cobalt, rx); + vmr->control = 0; + vmr->control = M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK; + fw->ctrl = 0; + clkloss->ctrl = 0; +} + +static const struct vb2_ops cobalt_qops = { + .queue_setup = cobalt_queue_setup, + .buf_init = cobalt_buf_init, + .buf_cleanup = cobalt_buf_cleanup, + .buf_prepare = cobalt_buf_prepare, + .buf_queue = cobalt_buf_queue, + .start_streaming = cobalt_start_streaming, + .stop_streaming = cobalt_stop_streaming, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, +}; + +/* V4L2 ioctls */ + +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int cobalt_cobaltc(struct cobalt *cobalt, unsigned int cmd, void *arg) +{ + struct v4l2_dbg_register *regs = arg; + void __iomem *adrs = cobalt->bar1 + regs->reg; + + cobalt_info("cobalt_cobaltc: adrs = %p\n", adrs); + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + regs->size = 4; + if (cmd == VIDIOC_DBG_S_REGISTER) + iowrite32(regs->val, adrs); + else + regs->val = ioread32(adrs); + return 0; +} + +static int cobalt_g_register(struct file *file, void *priv_fh, + struct v4l2_dbg_register *reg) +{ + struct cobalt_stream *s = video_drvdata(file); + struct cobalt *cobalt = s->cobalt; + + return cobalt_cobaltc(cobalt, VIDIOC_DBG_G_REGISTER, reg); +} + +static int cobalt_s_register(struct file *file, void *priv_fh, + const struct v4l2_dbg_register *reg) +{ + struct cobalt_stream *s = video_drvdata(file); + struct cobalt *cobalt = s->cobalt; + + return cobalt_cobaltc(cobalt, VIDIOC_DBG_S_REGISTER, + (struct v4l2_dbg_register *)reg); +} +#endif + +static int cobalt_querycap(struct file *file, void *priv_fh, + struct v4l2_capability *vcap) +{ + struct cobalt_stream *s = video_drvdata(file); + struct cobalt *cobalt = s->cobalt; + + strlcpy(vcap->driver, "cobalt", sizeof(vcap->driver)); + strlcpy(vcap->card, "cobalt", sizeof(vcap->card)); + snprintf(vcap->bus_info, sizeof(vcap->bus_info), + "PCIe:%s", pci_name(cobalt->pci_dev)); + vcap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_READWRITE; + if (s->is_output) + vcap->device_caps |= V4L2_CAP_VIDEO_OUTPUT; + else + vcap->device_caps |= V4L2_CAP_VIDEO_CAPTURE; + vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS | + V4L2_CAP_VIDEO_CAPTURE; + if (cobalt->have_hsma_tx) + vcap->capabilities |= V4L2_CAP_VIDEO_OUTPUT; + return 0; +} + +static void cobalt_video_input_status_show(struct cobalt_stream *s) +{ + volatile struct m00389_cvi_regmap __iomem *cvi; + volatile struct m00233_video_measure_regmap __iomem *vmr; + volatile struct m00473_freewheel_regmap __iomem *fw; + volatile struct m00479_clk_loss_detector_regmap __iomem *clkloss; + volatile struct m00235_fdma_packer_regmap __iomem *packer; + int rx = s->video_channel; + struct cobalt *cobalt = s->cobalt; + + cvi = COBALT_CVI(cobalt, rx); + vmr = COBALT_CVI_VMR(cobalt, rx); + fw = COBALT_CVI_FREEWHEEL(cobalt, rx); + clkloss = COBALT_CVI_CLK_LOSS(cobalt, rx); + packer = COBALT_CVI_PACKER(cobalt, rx); + cobalt_info("rx%d: cvi resolution: %dx%d\n", rx, + cvi->frame_width, cvi->frame_height); + cobalt_info("rx%d: cvi control: %s%s%s\n", rx, + (cvi->control & M00389_CONTROL_BITMAP_ENABLE_MSK) ? + "enable " : "disable ", + (cvi->control & M00389_CONTROL_BITMAP_HSYNC_POLARITY_LOW_MSK) ? + "HSync- " : "HSync+ ", + (cvi->control & M00389_CONTROL_BITMAP_VSYNC_POLARITY_LOW_MSK) ? + "VSync- " : "VSync+ "); + cobalt_info("rx%d: cvi status: %s%s\n", rx, + (cvi->status & M00389_STATUS_BITMAP_LOCK_MSK) ? + "lock " : "no-lock ", + (cvi->status & M00389_STATUS_BITMAP_ERROR_MSK) ? + "error " : "no-error "); + + cobalt_info("rx%d: Measurements: %s%s%s%s%s%s%s\n", rx, + (vmr->control & M00233_CONTROL_BITMAP_HSYNC_POLARITY_LOW_MSK) ? + "HSync- " : "HSync+ ", + (vmr->control & M00233_CONTROL_BITMAP_VSYNC_POLARITY_LOW_MSK) ? + "VSync- " : "VSync+ ", + (vmr->control & M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK) ? + "enabled " : "disabled ", + (vmr->control & M00233_CONTROL_BITMAP_ENABLE_INTERRUPT_MSK) ? + "irq-enabled " : "irq-disabled ", + (vmr->control & M00233_CONTROL_BITMAP_UPDATE_ON_HSYNC_MSK) ? + "update-on-hsync " : "", + (vmr->status & M00233_STATUS_BITMAP_HSYNC_TIMEOUT_MSK) ? + "hsync-timeout " : "", + (vmr->status & M00233_STATUS_BITMAP_INIT_DONE_MSK) ? + "init-done" : ""); + cobalt_info("rx%d: irq_status: 0x%02x irq_triggers: 0x%02x\n", rx, + vmr->irq_status & 0xff, vmr->irq_triggers & 0xff); + cobalt_info("rx%d: vsync: %d\n", rx, vmr->vsync_time); + cobalt_info("rx%d: vbp: %d\n", rx, vmr->vback_porch); + cobalt_info("rx%d: vact: %d\n", rx, vmr->vactive_area); + cobalt_info("rx%d: vfb: %d\n", rx, vmr->vfront_porch); + cobalt_info("rx%d: hsync: %d\n", rx, vmr->hsync_time); + cobalt_info("rx%d: hbp: %d\n", rx, vmr->hback_porch); + cobalt_info("rx%d: hact: %d\n", rx, vmr->hactive_area); + cobalt_info("rx%d: hfb: %d\n", rx, vmr->hfront_porch); + cobalt_info("rx%d: Freewheeling: %s%s%s\n", rx, + (fw->ctrl & M00473_CTRL_BITMAP_ENABLE_MSK) ? + "enabled " : "disabled ", + (fw->ctrl & M00473_CTRL_BITMAP_FORCE_FREEWHEEL_MODE_MSK) ? + "forced " : "", + (fw->status & M00473_STATUS_BITMAP_FREEWHEEL_MODE_MSK) ? + "freewheeling " : "video-passthrough "); + vmr->irq_status = 0xff; + cobalt_info("rx%d: Clock Loss Detection: %s%s\n", rx, + (clkloss->ctrl & M00479_CTRL_BITMAP_ENABLE_MSK) ? + "enabled " : "disabled ", + (clkloss->status & M00479_STATUS_BITMAP_CLOCK_MISSING_MSK) ? + "clock-missing " : "found-clock "); + cobalt_info("rx%d: Packer: %x\n", rx, packer->control); +} + +static int cobalt_log_status(struct file *file, void *priv_fh) +{ + struct cobalt_stream *s = video_drvdata(file); + struct cobalt *cobalt = s->cobalt; + volatile struct m00514_syncgen_flow_evcnt_regmap __iomem *vo = + COBALT_TX_BASE(cobalt); + u8 stat; + + cobalt_info("%s", cobalt->hdl_info); + cobalt_info("sysctrl: %08x, sysstat: %08x\n", + cobalt_g_sysctrl(cobalt), + cobalt_g_sysstat(cobalt)); + cobalt_info("dma channel: %d, video channel: %d\n", + s->dma_channel, s->video_channel); + cobalt_pcie_status_show(cobalt); + cobalt_cpld_status(cobalt); + cobalt_irq_log_status(cobalt); + v4l2_subdev_call(s->sd, core, log_status); + if (!s->is_output) { + cobalt_video_input_status_show(s); + return 0; + } + + stat = vo->rd_status; + + cobalt_info("tx: status: %s%s\n", + (stat & M00514_RD_STATUS_BITMAP_FLOW_CTRL_NO_DATA_ERROR_MSK) ? + "no_data " : "", + (stat & M00514_RD_STATUS_BITMAP_READY_BUFFER_FULL_MSK) ? + "ready_buffer_full " : ""); + cobalt_info("tx: evcnt: %d\n", vo->rd_evcnt_count); + return 0; +} + +static int cobalt_enum_dv_timings(struct file *file, void *priv_fh, + struct v4l2_enum_dv_timings *timings) +{ + struct cobalt_stream *s = video_drvdata(file); + + if (s->input == 1) { + if (timings->index) + return -EINVAL; + memset(timings->reserved, 0, sizeof(timings->reserved)); + timings->timings = cea1080p60; + return 0; + } + timings->pad = 0; + return v4l2_subdev_call(s->sd, + pad, enum_dv_timings, timings); +} + +static int cobalt_s_dv_timings(struct file *file, void *priv_fh, + struct v4l2_dv_timings *timings) +{ + struct cobalt_stream *s = video_drvdata(file); + int err; + + if (vb2_is_busy(&s->q)) + return -EBUSY; + + if (s->input == 1) { + *timings = cea1080p60; + return 0; + } + err = v4l2_subdev_call(s->sd, + video, s_dv_timings, timings); + if (!err) { + s->timings = *timings; + s->width = timings->bt.width; + s->height = timings->bt.height; + s->stride = timings->bt.width * s->bpp; + } + return err; +} + +static int cobalt_g_dv_timings(struct file *file, void *priv_fh, + struct v4l2_dv_timings *timings) +{ + struct cobalt_stream *s = video_drvdata(file); + + if (s->input == 1) { + *timings = cea1080p60; + return 0; + } + return v4l2_subdev_call(s->sd, + video, g_dv_timings, timings); +} + +static int cobalt_query_dv_timings(struct file *file, void *priv_fh, + struct v4l2_dv_timings *timings) +{ + struct cobalt_stream *s = video_drvdata(file); + + if (s->input == 1) { + *timings = cea1080p60; + return 0; + } + return v4l2_subdev_call(s->sd, + video, query_dv_timings, timings); +} + +static int cobalt_dv_timings_cap(struct file *file, void *priv_fh, + struct v4l2_dv_timings_cap *cap) +{ + struct cobalt_stream *s = video_drvdata(file); + + cap->pad = 0; + return v4l2_subdev_call(s->sd, + pad, dv_timings_cap, cap); +} + +static int cobalt_enum_fmt_vid_cap(struct file *file, void *priv_fh, + struct v4l2_fmtdesc *f) +{ + switch (f->index) { + case 0: + strlcpy(f->description, "YUV 4:2:2", sizeof(f->description)); + f->pixelformat = V4L2_PIX_FMT_YUYV; + break; + case 1: + strlcpy(f->description, "RGB24", sizeof(f->description)); + f->pixelformat = V4L2_PIX_FMT_RGB24; + break; + case 2: + strlcpy(f->description, "RGB32", sizeof(f->description)); + f->pixelformat = V4L2_PIX_FMT_BGR32; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int cobalt_g_fmt_vid_cap(struct file *file, void *priv_fh, + struct v4l2_format *f) +{ + struct cobalt_stream *s = video_drvdata(file); + struct v4l2_pix_format *pix = &f->fmt.pix; + struct v4l2_subdev_format sd_fmt; + + pix->width = s->width; + pix->height = s->height; + pix->bytesperline = s->stride; + pix->field = V4L2_FIELD_NONE; + + if (s->input == 1) { + pix->colorspace = V4L2_COLORSPACE_SRGB; + } else { + sd_fmt.pad = s->pad_source; + sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; + v4l2_subdev_call(s->sd, pad, get_fmt, NULL, &sd_fmt); + v4l2_fill_pix_format(pix, &sd_fmt.format); + pix->colorspace = sd_fmt.format.colorspace; + pix->ycbcr_enc = sd_fmt.format.ycbcr_enc; + pix->quantization = sd_fmt.format.quantization; + } + + pix->pixelformat = s->pixfmt; + pix->sizeimage = pix->bytesperline * pix->height; + + return 0; +} + +static int cobalt_try_fmt_vid_cap(struct file *file, void *priv_fh, + struct v4l2_format *f) +{ + struct cobalt_stream *s = video_drvdata(file); + struct v4l2_pix_format *pix = &f->fmt.pix; + struct v4l2_subdev_format sd_fmt; + + /* Check for min (QCIF) and max (Full HD) size */ + if ((pix->width < 176) || (pix->height < 144)) { + pix->width = 176; + pix->height = 144; + } + + if ((pix->width > 1920) || (pix->height > 1080)) { + pix->width = 1920; + pix->height = 1080; + } + + /* Make width multiple of 4 */ + pix->width &= ~0x3; + + /* Make height multiple of 2 */ + pix->height &= ~0x1; + + if (s->input == 1) { + /* Generator => fixed format only */ + pix->width = 1920; + pix->height = 1080; + pix->colorspace = V4L2_COLORSPACE_SRGB; + } else { + sd_fmt.pad = s->pad_source; + sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; + v4l2_subdev_call(s->sd, pad, get_fmt, NULL, &sd_fmt); + v4l2_fill_pix_format(pix, &sd_fmt.format); + pix->colorspace = sd_fmt.format.colorspace; + pix->ycbcr_enc = sd_fmt.format.ycbcr_enc; + pix->quantization = sd_fmt.format.quantization; + } + + switch (pix->pixelformat) { + case V4L2_PIX_FMT_YUYV: + default: + pix->bytesperline = max(pix->bytesperline & ~0x3, + pix->width * COBALT_BYTES_PER_PIXEL_YUYV); + pix->pixelformat = V4L2_PIX_FMT_YUYV; + break; + case V4L2_PIX_FMT_RGB24: + pix->bytesperline = max(pix->bytesperline & ~0x3, + pix->width * COBALT_BYTES_PER_PIXEL_RGB24); + break; + case V4L2_PIX_FMT_BGR32: + pix->bytesperline = max(pix->bytesperline & ~0x3, + pix->width * COBALT_BYTES_PER_PIXEL_RGB32); + break; + } + + pix->sizeimage = pix->bytesperline * pix->height; + pix->field = V4L2_FIELD_NONE; + pix->priv = 0; + + return 0; +} + +static int cobalt_s_fmt_vid_cap(struct file *file, void *priv_fh, + struct v4l2_format *f) +{ + struct cobalt_stream *s = video_drvdata(file); + struct v4l2_pix_format *pix = &f->fmt.pix; + + if (vb2_is_busy(&s->q)) + return -EBUSY; + + if (cobalt_try_fmt_vid_cap(file, priv_fh, f)) + return -EINVAL; + + s->width = pix->width; + s->height = pix->height; + s->stride = pix->bytesperline; + switch (pix->pixelformat) { + case V4L2_PIX_FMT_YUYV: + s->bpp = COBALT_BYTES_PER_PIXEL_YUYV; + break; + case V4L2_PIX_FMT_RGB24: + s->bpp = COBALT_BYTES_PER_PIXEL_RGB24; + break; + case V4L2_PIX_FMT_BGR32: + s->bpp = COBALT_BYTES_PER_PIXEL_RGB32; + break; + default: + return -EINVAL; + } + s->pixfmt = pix->pixelformat; + cobalt_enable_input(s); + + return 0; +} + +static int cobalt_try_fmt_vid_out(struct file *file, void *priv_fh, + struct v4l2_format *f) +{ + struct v4l2_pix_format *pix = &f->fmt.pix; + + /* Check for min (QCIF) and max (Full HD) size */ + if ((pix->width < 176) || (pix->height < 144)) { + pix->width = 176; + pix->height = 144; + } + + if ((pix->width > 1920) || (pix->height > 1080)) { + pix->width = 1920; + pix->height = 1080; + } + + /* Make width multiple of 4 */ + pix->width &= ~0x3; + + /* Make height multiple of 2 */ + pix->height &= ~0x1; + + switch (pix->pixelformat) { + case V4L2_PIX_FMT_YUYV: + default: + pix->bytesperline = max(pix->bytesperline & ~0x3, + pix->width * COBALT_BYTES_PER_PIXEL_YUYV); + pix->pixelformat = V4L2_PIX_FMT_YUYV; + break; + case V4L2_PIX_FMT_BGR32: + pix->bytesperline = max(pix->bytesperline & ~0x3, + pix->width * COBALT_BYTES_PER_PIXEL_RGB32); + break; + } + + pix->sizeimage = pix->bytesperline * pix->height; + pix->field = V4L2_FIELD_NONE; + + return 0; +} + +static int cobalt_g_fmt_vid_out(struct file *file, void *priv_fh, + struct v4l2_format *f) +{ + struct cobalt_stream *s = video_drvdata(file); + struct v4l2_pix_format *pix = &f->fmt.pix; + + pix->width = s->width; + pix->height = s->height; + pix->bytesperline = s->stride; + pix->field = V4L2_FIELD_NONE; + pix->pixelformat = s->pixfmt; + pix->colorspace = s->colorspace; + pix->ycbcr_enc = s->ycbcr_enc; + pix->quantization = s->quantization; + pix->sizeimage = pix->bytesperline * pix->height; + + return 0; +} + +static int cobalt_enum_fmt_vid_out(struct file *file, void *priv_fh, + struct v4l2_fmtdesc *f) +{ + switch (f->index) { + case 0: + strlcpy(f->description, "YUV 4:2:2", sizeof(f->description)); + f->pixelformat = V4L2_PIX_FMT_YUYV; + break; + case 1: + strlcpy(f->description, "RGB32", sizeof(f->description)); + f->pixelformat = V4L2_PIX_FMT_BGR32; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int cobalt_s_fmt_vid_out(struct file *file, void *priv_fh, + struct v4l2_format *f) +{ + struct cobalt_stream *s = video_drvdata(file); + struct v4l2_pix_format *pix = &f->fmt.pix; + struct v4l2_subdev_format sd_fmt = { 0 }; + + if (cobalt_try_fmt_vid_out(file, priv_fh, f)) + return -EINVAL; + + if (vb2_is_busy(&s->q) && (pix->pixelformat != s->pixfmt || + pix->width != s->width || pix->height != s->height || + pix->bytesperline != s->stride)) + return -EBUSY; + + switch (pix->pixelformat) { + case V4L2_PIX_FMT_YUYV: + s->bpp = COBALT_BYTES_PER_PIXEL_YUYV; + break; + case V4L2_PIX_FMT_BGR32: + s->bpp = COBALT_BYTES_PER_PIXEL_RGB32; + break; + default: + return -EINVAL; + } + s->width = pix->width; + s->height = pix->height; + s->stride = pix->bytesperline; + s->pixfmt = pix->pixelformat; + s->colorspace = pix->colorspace; + s->ycbcr_enc = pix->ycbcr_enc; + s->quantization = pix->quantization; + sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; + v4l2_subdev_call(s->sd, pad, get_fmt, NULL, &sd_fmt); + sd_fmt.format.colorspace = pix->colorspace; + sd_fmt.format.ycbcr_enc = pix->ycbcr_enc; + sd_fmt.format.quantization = pix->quantization; + v4l2_subdev_call(s->sd, pad, set_fmt, NULL, &sd_fmt); + return 0; +} + +static int cobalt_enum_input(struct file *file, void *priv_fh, + struct v4l2_input *inp) +{ + struct cobalt_stream *s = video_drvdata(file); + + if (inp->index > 1) + return -EINVAL; + if (inp->index == 0) + snprintf(inp->name, sizeof(inp->name), + "HDMI-%d", s->video_channel); + else + snprintf(inp->name, sizeof(inp->name), + "Generator-%d", s->video_channel); + inp->type = V4L2_INPUT_TYPE_CAMERA; + inp->capabilities = V4L2_IN_CAP_DV_TIMINGS; + if (inp->index == 1) + return 0; + return v4l2_subdev_call(s->sd, + video, g_input_status, &inp->status); +} + +static int cobalt_g_input(struct file *file, void *priv_fh, unsigned int *i) +{ + struct cobalt_stream *s = video_drvdata(file); + + *i = s->input; + return 0; +} + +static int cobalt_s_input(struct file *file, void *priv_fh, unsigned int i) +{ + struct cobalt_stream *s = video_drvdata(file); + + if (i >= 2) + return -EINVAL; + if (vb2_is_busy(&s->q)) + return -EBUSY; + s->input = i; + + cobalt_enable_input(s); + + if (s->input == 1) /* Test Pattern Generator */ + return 0; + + return v4l2_subdev_call(s->sd, video, s_routing, + ADV76XX_PAD_HDMI_PORT_A, 0, 0); +} + +static int cobalt_enum_output(struct file *file, void *priv_fh, + struct v4l2_output *out) +{ + if (out->index) + return -EINVAL; + snprintf(out->name, sizeof(out->name), "HDMI-%d", out->index); + out->type = V4L2_OUTPUT_TYPE_ANALOG; + out->capabilities = V4L2_OUT_CAP_DV_TIMINGS; + return 0; +} + +static int cobalt_g_output(struct file *file, void *priv_fh, unsigned int *i) +{ + *i = 0; + return 0; +} + +static int cobalt_s_output(struct file *file, void *priv_fh, unsigned int i) +{ + return i ? -EINVAL : 0; +} + +static int cobalt_g_edid(struct file *file, void *fh, struct v4l2_edid *edid) +{ + struct cobalt_stream *s = video_drvdata(file); + u32 pad = edid->pad; + int ret; + + if (edid->pad >= (s->is_output ? 1 : 2)) + return -EINVAL; + edid->pad = 0; + ret = v4l2_subdev_call(s->sd, pad, get_edid, edid); + edid->pad = pad; + return ret; +} + +static int cobalt_s_edid(struct file *file, void *fh, struct v4l2_edid *edid) +{ + struct cobalt_stream *s = video_drvdata(file); + u32 pad = edid->pad; + int ret; + + if (edid->pad >= 2) + return -EINVAL; + edid->pad = 0; + ret = v4l2_subdev_call(s->sd, pad, set_edid, edid); + edid->pad = pad; + return ret; +} + +static int cobalt_subscribe_event(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub) +{ + switch (sub->type) { + case V4L2_EVENT_SOURCE_CHANGE: + return v4l2_event_subscribe(fh, sub, 4, NULL); + } + return v4l2_ctrl_subscribe_event(fh, sub); +} + +static int cobalt_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a) +{ + if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + a->parm.capture.timeperframe.numerator = 1; + a->parm.capture.timeperframe.denominator = 60; + a->parm.capture.readbuffers = 3; + return 0; +} + +static const struct v4l2_ioctl_ops cobalt_ioctl_ops = { + .vidioc_querycap = cobalt_querycap, + .vidioc_g_parm = cobalt_g_parm, + .vidioc_log_status = cobalt_log_status, + .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, + .vidioc_enum_input = cobalt_enum_input, + .vidioc_g_input = cobalt_g_input, + .vidioc_s_input = cobalt_s_input, + .vidioc_enum_fmt_vid_cap = cobalt_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = cobalt_g_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = cobalt_s_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = cobalt_try_fmt_vid_cap, + .vidioc_enum_output = cobalt_enum_output, + .vidioc_g_output = cobalt_g_output, + .vidioc_s_output = cobalt_s_output, + .vidioc_enum_fmt_vid_out = cobalt_enum_fmt_vid_out, + .vidioc_g_fmt_vid_out = cobalt_g_fmt_vid_out, + .vidioc_s_fmt_vid_out = cobalt_s_fmt_vid_out, + .vidioc_try_fmt_vid_out = cobalt_try_fmt_vid_out, + .vidioc_s_dv_timings = cobalt_s_dv_timings, + .vidioc_g_dv_timings = cobalt_g_dv_timings, + .vidioc_query_dv_timings = cobalt_query_dv_timings, + .vidioc_enum_dv_timings = cobalt_enum_dv_timings, + .vidioc_dv_timings_cap = cobalt_dv_timings_cap, + .vidioc_g_edid = cobalt_g_edid, + .vidioc_s_edid = cobalt_s_edid, + .vidioc_subscribe_event = cobalt_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_create_bufs = vb2_ioctl_create_bufs, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_qbuf = vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, + .vidioc_expbuf = vb2_ioctl_expbuf, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .vidioc_g_register = cobalt_g_register, + .vidioc_s_register = cobalt_s_register, +#endif +}; + +static const struct v4l2_ioctl_ops cobalt_ioctl_empty_ops = { +#ifdef CONFIG_VIDEO_ADV_DEBUG + .vidioc_g_register = cobalt_g_register, + .vidioc_s_register = cobalt_s_register, +#endif +}; + +/* Register device nodes */ + +static const struct v4l2_file_operations cobalt_fops = { + .owner = THIS_MODULE, + .open = v4l2_fh_open, + .unlocked_ioctl = video_ioctl2, + .release = vb2_fop_release, + .poll = vb2_fop_poll, + .mmap = vb2_fop_mmap, + .read = vb2_fop_read, +}; + +static const struct v4l2_file_operations cobalt_out_fops = { + .owner = THIS_MODULE, + .open = v4l2_fh_open, + .unlocked_ioctl = video_ioctl2, + .release = vb2_fop_release, + .poll = vb2_fop_poll, + .mmap = vb2_fop_mmap, + .write = vb2_fop_write, +}; + +static const struct v4l2_file_operations cobalt_empty_fops = { + .owner = THIS_MODULE, + .open = v4l2_fh_open, + .unlocked_ioctl = video_ioctl2, + .release = v4l2_fh_release, +}; + +static int cobalt_node_register(struct cobalt *cobalt, int node) +{ + static const struct v4l2_dv_timings dv1080p60 = + V4L2_DV_BT_CEA_1920X1080P60; + struct cobalt_stream *s = cobalt->streams + node; + struct video_device *vdev = &s->vdev; + struct vb2_queue *q = &s->q; + int ret; + + mutex_init(&s->lock); + spin_lock_init(&s->irqlock); + + snprintf(vdev->name, sizeof(vdev->name), + "%s-%d", cobalt->v4l2_dev.name, node); + s->width = 1920; + /* Audio frames are just 4 lines of 1920 bytes */ + s->height = s->is_audio ? 4 : 1080; + + if (s->is_audio) { + s->bpp = 1; + s->pixfmt = V4L2_PIX_FMT_GREY; + } else if (s->is_output) { + s->bpp = COBALT_BYTES_PER_PIXEL_RGB32; + s->pixfmt = V4L2_PIX_FMT_BGR32; + } else { + s->bpp = COBALT_BYTES_PER_PIXEL_YUYV; + s->pixfmt = V4L2_PIX_FMT_YUYV; + } + s->colorspace = V4L2_COLORSPACE_SRGB; + s->stride = s->width * s->bpp; + + if (!s->is_audio) { + if (s->is_dummy) + cobalt_warn("Setting up dummy video node %d\n", node); + vdev->v4l2_dev = &cobalt->v4l2_dev; + if (s->is_dummy) + vdev->fops = &cobalt_empty_fops; + else + vdev->fops = s->is_output ? &cobalt_out_fops : + &cobalt_fops; + vdev->release = video_device_release_empty; + vdev->vfl_dir = s->is_output ? VFL_DIR_TX : VFL_DIR_RX; + vdev->lock = &s->lock; + if (s->sd) + vdev->ctrl_handler = s->sd->ctrl_handler; + s->timings = dv1080p60; + v4l2_subdev_call(s->sd, video, s_dv_timings, &s->timings); + if (!s->is_output && s->sd) + cobalt_enable_input(s); + vdev->ioctl_ops = s->is_dummy ? &cobalt_ioctl_empty_ops : + &cobalt_ioctl_ops; + } + + INIT_LIST_HEAD(&s->bufs); + q->type = s->is_output ? V4L2_BUF_TYPE_VIDEO_OUTPUT : + V4L2_BUF_TYPE_VIDEO_CAPTURE; + q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; + q->io_modes |= s->is_output ? VB2_WRITE : VB2_READ; + q->drv_priv = s; + q->buf_struct_size = sizeof(struct cobalt_buffer); + q->ops = &cobalt_qops; + q->mem_ops = &vb2_dma_sg_memops; + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + q->min_buffers_needed = 2; + q->lock = &s->lock; + vdev->queue = q; + + video_set_drvdata(vdev, s); + ret = vb2_queue_init(q); + if (!s->is_audio && ret == 0) + ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); + else if (!s->is_dummy) + ret = cobalt_alsa_init(s); + + if (ret < 0) { + if (!s->is_audio) + cobalt_err("couldn't register v4l2 device node %d\n", + node); + return ret; + } + cobalt_info("registered node %d\n", node); + return 0; +} + +/* Initialize v4l2 variables and register v4l2 devices */ +int cobalt_nodes_register(struct cobalt *cobalt) +{ + int node, ret; + + /* Setup V4L2 Devices */ + for (node = 0; node < COBALT_NUM_STREAMS; node++) { + ret = cobalt_node_register(cobalt, node); + if (ret) + return ret; + } + return 0; +} + +/* Unregister v4l2 devices */ +void cobalt_nodes_unregister(struct cobalt *cobalt) +{ + int node; + + /* Teardown all streams */ + for (node = 0; node < COBALT_NUM_STREAMS; node++) { + struct cobalt_stream *s = cobalt->streams + node; + struct video_device *vdev = &s->vdev; + + if (!s->is_audio) + video_unregister_device(vdev); + else if (!s->is_dummy) + cobalt_alsa_exit(s); + } +} diff --git a/drivers/media/pci/cobalt/cobalt-v4l2.h b/drivers/media/pci/cobalt/cobalt-v4l2.h new file mode 100644 index 000000000000..62be553cd8e2 --- /dev/null +++ b/drivers/media/pci/cobalt/cobalt-v4l2.h @@ -0,0 +1,22 @@ +/* + * cobalt V4L2 API + * + * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +int cobalt_nodes_register(struct cobalt *cobalt); +void cobalt_nodes_unregister(struct cobalt *cobalt); diff --git a/drivers/media/pci/cobalt/m00233_video_measure_memmap_package.h b/drivers/media/pci/cobalt/m00233_video_measure_memmap_package.h new file mode 100644 index 000000000000..9bc9ef1fd3a8 --- /dev/null +++ b/drivers/media/pci/cobalt/m00233_video_measure_memmap_package.h @@ -0,0 +1,115 @@ +/* + * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef M00233_VIDEO_MEASURE_MEMMAP_PACKAGE_H +#define M00233_VIDEO_MEASURE_MEMMAP_PACKAGE_H + +/******************************************************************* + * Register Block + * M00233_VIDEO_MEASURE_MEMMAP_PACKAGE_VHD_REGMAP + *******************************************************************/ +struct m00233_video_measure_regmap { + uint32_t irq_status; /* Reg 0x0000 */ + /* The vertical counter starts on rising edge of vsync */ + uint32_t vsync_time; /* Reg 0x0004 */ + uint32_t vback_porch; /* Reg 0x0008 */ + uint32_t vactive_area; /* Reg 0x000c */ + uint32_t vfront_porch; /* Reg 0x0010 */ + /* The horizontal counter starts on rising edge of hsync. */ + uint32_t hsync_time; /* Reg 0x0014 */ + uint32_t hback_porch; /* Reg 0x0018 */ + uint32_t hactive_area; /* Reg 0x001c */ + uint32_t hfront_porch; /* Reg 0x0020 */ + uint32_t control; /* Reg 0x0024, Default=0x0 */ + uint32_t irq_triggers; /* Reg 0x0028, Default=0xff */ + /* Value is given in number of register bus clock periods between */ + /* falling and rising edge of hsync. Must be non-zero. */ + uint32_t hsync_timeout_val; /* Reg 0x002c, Default=0x1fff */ + uint32_t status; /* Reg 0x0030 */ +}; + +#define M00233_VIDEO_MEASURE_REG_IRQ_STATUS_OFST 0 +#define M00233_VIDEO_MEASURE_REG_VSYNC_TIME_OFST 4 +#define M00233_VIDEO_MEASURE_REG_VBACK_PORCH_OFST 8 +#define M00233_VIDEO_MEASURE_REG_VACTIVE_AREA_OFST 12 +#define M00233_VIDEO_MEASURE_REG_VFRONT_PORCH_OFST 16 +#define M00233_VIDEO_MEASURE_REG_HSYNC_TIME_OFST 20 +#define M00233_VIDEO_MEASURE_REG_HBACK_PORCH_OFST 24 +#define M00233_VIDEO_MEASURE_REG_HACTIVE_AREA_OFST 28 +#define M00233_VIDEO_MEASURE_REG_HFRONT_PORCH_OFST 32 +#define M00233_VIDEO_MEASURE_REG_CONTROL_OFST 36 +#define M00233_VIDEO_MEASURE_REG_IRQ_TRIGGERS_OFST 40 +#define M00233_VIDEO_MEASURE_REG_HSYNC_TIMEOUT_VAL_OFST 44 +#define M00233_VIDEO_MEASURE_REG_STATUS_OFST 48 + +/******************************************************************* + * Bit Mask for register + * M00233_VIDEO_MEASURE_MEMMAP_PACKAGE_VHD_BITMAP + *******************************************************************/ +/* irq_status [7:0] */ +#define M00233_IRQ_STATUS_BITMAP_VSYNC_TIME_OFST (0) +#define M00233_IRQ_STATUS_BITMAP_VSYNC_TIME_MSK (0x1 << M00233_IRQ_STATUS_BITMAP_VSYNC_TIME_OFST) +#define M00233_IRQ_STATUS_BITMAP_VBACK_PORCH_OFST (1) +#define M00233_IRQ_STATUS_BITMAP_VBACK_PORCH_MSK (0x1 << M00233_IRQ_STATUS_BITMAP_VBACK_PORCH_OFST) +#define M00233_IRQ_STATUS_BITMAP_VACTIVE_AREA_OFST (2) +#define M00233_IRQ_STATUS_BITMAP_VACTIVE_AREA_MSK (0x1 << M00233_IRQ_STATUS_BITMAP_VACTIVE_AREA_OFST) +#define M00233_IRQ_STATUS_BITMAP_VFRONT_PORCH_OFST (3) +#define M00233_IRQ_STATUS_BITMAP_VFRONT_PORCH_MSK (0x1 << M00233_IRQ_STATUS_BITMAP_VFRONT_PORCH_OFST) +#define M00233_IRQ_STATUS_BITMAP_HSYNC_TIME_OFST (4) +#define M00233_IRQ_STATUS_BITMAP_HSYNC_TIME_MSK (0x1 << M00233_IRQ_STATUS_BITMAP_HSYNC_TIME_OFST) +#define M00233_IRQ_STATUS_BITMAP_HBACK_PORCH_OFST (5) +#define M00233_IRQ_STATUS_BITMAP_HBACK_PORCH_MSK (0x1 << M00233_IRQ_STATUS_BITMAP_HBACK_PORCH_OFST) +#define M00233_IRQ_STATUS_BITMAP_HACTIVE_AREA_OFST (6) +#define M00233_IRQ_STATUS_BITMAP_HACTIVE_AREA_MSK (0x1 << M00233_IRQ_STATUS_BITMAP_HACTIVE_AREA_OFST) +#define M00233_IRQ_STATUS_BITMAP_HFRONT_PORCH_OFST (7) +#define M00233_IRQ_STATUS_BITMAP_HFRONT_PORCH_MSK (0x1 << M00233_IRQ_STATUS_BITMAP_HFRONT_PORCH_OFST) +/* control [4:0] */ +#define M00233_CONTROL_BITMAP_HSYNC_POLARITY_LOW_OFST (0) +#define M00233_CONTROL_BITMAP_HSYNC_POLARITY_LOW_MSK (0x1 << M00233_CONTROL_BITMAP_HSYNC_POLARITY_LOW_OFST) +#define M00233_CONTROL_BITMAP_VSYNC_POLARITY_LOW_OFST (1) +#define M00233_CONTROL_BITMAP_VSYNC_POLARITY_LOW_MSK (0x1 << M00233_CONTROL_BITMAP_VSYNC_POLARITY_LOW_OFST) +#define M00233_CONTROL_BITMAP_ENABLE_MEASURE_OFST (2) +#define M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK (0x1 << M00233_CONTROL_BITMAP_ENABLE_MEASURE_OFST) +#define M00233_CONTROL_BITMAP_ENABLE_INTERRUPT_OFST (3) +#define M00233_CONTROL_BITMAP_ENABLE_INTERRUPT_MSK (0x1 << M00233_CONTROL_BITMAP_ENABLE_INTERRUPT_OFST) +#define M00233_CONTROL_BITMAP_UPDATE_ON_HSYNC_OFST (4) +#define M00233_CONTROL_BITMAP_UPDATE_ON_HSYNC_MSK (0x1 << M00233_CONTROL_BITMAP_UPDATE_ON_HSYNC_OFST) +/* irq_triggers [7:0] */ +#define M00233_IRQ_TRIGGERS_BITMAP_VSYNC_TIME_OFST (0) +#define M00233_IRQ_TRIGGERS_BITMAP_VSYNC_TIME_MSK (0x1 << M00233_IRQ_TRIGGERS_BITMAP_VSYNC_TIME_OFST) +#define M00233_IRQ_TRIGGERS_BITMAP_VBACK_PORCH_OFST (1) +#define M00233_IRQ_TRIGGERS_BITMAP_VBACK_PORCH_MSK (0x1 << M00233_IRQ_TRIGGERS_BITMAP_VBACK_PORCH_OFST) +#define M00233_IRQ_TRIGGERS_BITMAP_VACTIVE_AREA_OFST (2) +#define M00233_IRQ_TRIGGERS_BITMAP_VACTIVE_AREA_MSK (0x1 << M00233_IRQ_TRIGGERS_BITMAP_VACTIVE_AREA_OFST) +#define M00233_IRQ_TRIGGERS_BITMAP_VFRONT_PORCH_OFST (3) +#define M00233_IRQ_TRIGGERS_BITMAP_VFRONT_PORCH_MSK (0x1 << M00233_IRQ_TRIGGERS_BITMAP_VFRONT_PORCH_OFST) +#define M00233_IRQ_TRIGGERS_BITMAP_HSYNC_TIME_OFST (4) +#define M00233_IRQ_TRIGGERS_BITMAP_HSYNC_TIME_MSK (0x1 << M00233_IRQ_TRIGGERS_BITMAP_HSYNC_TIME_OFST) +#define M00233_IRQ_TRIGGERS_BITMAP_HBACK_PORCH_OFST (5) +#define M00233_IRQ_TRIGGERS_BITMAP_HBACK_PORCH_MSK (0x1 << M00233_IRQ_TRIGGERS_BITMAP_HBACK_PORCH_OFST) +#define M00233_IRQ_TRIGGERS_BITMAP_HACTIVE_AREA_OFST (6) +#define M00233_IRQ_TRIGGERS_BITMAP_HACTIVE_AREA_MSK (0x1 << M00233_IRQ_TRIGGERS_BITMAP_HACTIVE_AREA_OFST) +#define M00233_IRQ_TRIGGERS_BITMAP_HFRONT_PORCH_OFST (7) +#define M00233_IRQ_TRIGGERS_BITMAP_HFRONT_PORCH_MSK (0x1 << M00233_IRQ_TRIGGERS_BITMAP_HFRONT_PORCH_OFST) +/* status [1:0] */ +#define M00233_STATUS_BITMAP_HSYNC_TIMEOUT_OFST (0) +#define M00233_STATUS_BITMAP_HSYNC_TIMEOUT_MSK (0x1 << M00233_STATUS_BITMAP_HSYNC_TIMEOUT_OFST) +#define M00233_STATUS_BITMAP_INIT_DONE_OFST (1) +#define M00233_STATUS_BITMAP_INIT_DONE_MSK (0x1 << M00233_STATUS_BITMAP_INIT_DONE_OFST) + +#endif /*M00233_VIDEO_MEASURE_MEMMAP_PACKAGE_H*/ diff --git a/drivers/media/pci/cobalt/m00235_fdma_packer_memmap_package.h b/drivers/media/pci/cobalt/m00235_fdma_packer_memmap_package.h new file mode 100644 index 000000000000..a480529f561e --- /dev/null +++ b/drivers/media/pci/cobalt/m00235_fdma_packer_memmap_package.h @@ -0,0 +1,44 @@ +/* + * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef M00235_FDMA_PACKER_MEMMAP_PACKAGE_H +#define M00235_FDMA_PACKER_MEMMAP_PACKAGE_H + +/******************************************************************* + * Register Block + * M00235_FDMA_PACKER_MEMMAP_PACKAGE_VHD_REGMAP + *******************************************************************/ +struct m00235_fdma_packer_regmap { + uint32_t control; /* Reg 0x0000, Default=0x0 */ +}; + +#define M00235_FDMA_PACKER_REG_CONTROL_OFST 0 + +/******************************************************************* + * Bit Mask for register + * M00235_FDMA_PACKER_MEMMAP_PACKAGE_VHD_BITMAP + *******************************************************************/ +/* control [3:0] */ +#define M00235_CONTROL_BITMAP_ENABLE_OFST (0) +#define M00235_CONTROL_BITMAP_ENABLE_MSK (0x1 << M00235_CONTROL_BITMAP_ENABLE_OFST) +#define M00235_CONTROL_BITMAP_PACK_FORMAT_OFST (1) +#define M00235_CONTROL_BITMAP_PACK_FORMAT_MSK (0x3 << M00235_CONTROL_BITMAP_PACK_FORMAT_OFST) +#define M00235_CONTROL_BITMAP_ENDIAN_FORMAT_OFST (3) +#define M00235_CONTROL_BITMAP_ENDIAN_FORMAT_MSK (0x1 << M00235_CONTROL_BITMAP_ENDIAN_FORMAT_OFST) + +#endif /*M00235_FDMA_PACKER_MEMMAP_PACKAGE_H*/ diff --git a/drivers/media/pci/cobalt/m00389_cvi_memmap_package.h b/drivers/media/pci/cobalt/m00389_cvi_memmap_package.h new file mode 100644 index 000000000000..602419e589d3 --- /dev/null +++ b/drivers/media/pci/cobalt/m00389_cvi_memmap_package.h @@ -0,0 +1,59 @@ +/* + * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef M00389_CVI_MEMMAP_PACKAGE_H +#define M00389_CVI_MEMMAP_PACKAGE_H + +/******************************************************************* + * Register Block + * M00389_CVI_MEMMAP_PACKAGE_VHD_REGMAP + *******************************************************************/ +struct m00389_cvi_regmap { + uint32_t control; /* Reg 0x0000, Default=0x0 */ + uint32_t frame_width; /* Reg 0x0004, Default=0x10 */ + uint32_t frame_height; /* Reg 0x0008, Default=0xc */ + uint32_t freewheel_period; /* Reg 0x000c, Default=0x0 */ + uint32_t error_color; /* Reg 0x0010, Default=0x0 */ + uint32_t status; /* Reg 0x0014 */ +}; + +#define M00389_CVI_REG_CONTROL_OFST 0 +#define M00389_CVI_REG_FRAME_WIDTH_OFST 4 +#define M00389_CVI_REG_FRAME_HEIGHT_OFST 8 +#define M00389_CVI_REG_FREEWHEEL_PERIOD_OFST 12 +#define M00389_CVI_REG_ERROR_COLOR_OFST 16 +#define M00389_CVI_REG_STATUS_OFST 20 + +/******************************************************************* + * Bit Mask for register + * M00389_CVI_MEMMAP_PACKAGE_VHD_BITMAP + *******************************************************************/ +/* control [2:0] */ +#define M00389_CONTROL_BITMAP_ENABLE_OFST (0) +#define M00389_CONTROL_BITMAP_ENABLE_MSK (0x1 << M00389_CONTROL_BITMAP_ENABLE_OFST) +#define M00389_CONTROL_BITMAP_HSYNC_POLARITY_LOW_OFST (1) +#define M00389_CONTROL_BITMAP_HSYNC_POLARITY_LOW_MSK (0x1 << M00389_CONTROL_BITMAP_HSYNC_POLARITY_LOW_OFST) +#define M00389_CONTROL_BITMAP_VSYNC_POLARITY_LOW_OFST (2) +#define M00389_CONTROL_BITMAP_VSYNC_POLARITY_LOW_MSK (0x1 << M00389_CONTROL_BITMAP_VSYNC_POLARITY_LOW_OFST) +/* status [1:0] */ +#define M00389_STATUS_BITMAP_LOCK_OFST (0) +#define M00389_STATUS_BITMAP_LOCK_MSK (0x1 << M00389_STATUS_BITMAP_LOCK_OFST) +#define M00389_STATUS_BITMAP_ERROR_OFST (1) +#define M00389_STATUS_BITMAP_ERROR_MSK (0x1 << M00389_STATUS_BITMAP_ERROR_OFST) + +#endif /*M00389_CVI_MEMMAP_PACKAGE_H*/ diff --git a/drivers/media/pci/cobalt/m00460_evcnt_memmap_package.h b/drivers/media/pci/cobalt/m00460_evcnt_memmap_package.h new file mode 100644 index 000000000000..95471c995067 --- /dev/null +++ b/drivers/media/pci/cobalt/m00460_evcnt_memmap_package.h @@ -0,0 +1,44 @@ +/* + * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef M00460_EVCNT_MEMMAP_PACKAGE_H +#define M00460_EVCNT_MEMMAP_PACKAGE_H + +/******************************************************************* + * Register Block + * M00460_EVCNT_MEMMAP_PACKAGE_VHD_REGMAP + *******************************************************************/ +struct m00460_evcnt_regmap { + uint32_t control; /* Reg 0x0000, Default=0x0 */ + uint32_t count; /* Reg 0x0004 */ +}; + +#define M00460_EVCNT_REG_CONTROL_OFST 0 +#define M00460_EVCNT_REG_COUNT_OFST 4 + +/******************************************************************* + * Bit Mask for register + * M00460_EVCNT_MEMMAP_PACKAGE_VHD_BITMAP + *******************************************************************/ +/* control [1:0] */ +#define M00460_CONTROL_BITMAP_ENABLE_OFST (0) +#define M00460_CONTROL_BITMAP_ENABLE_MSK (0x1 << M00460_CONTROL_BITMAP_ENABLE_OFST) +#define M00460_CONTROL_BITMAP_CLEAR_OFST (1) +#define M00460_CONTROL_BITMAP_CLEAR_MSK (0x1 << M00460_CONTROL_BITMAP_CLEAR_OFST) + +#endif /*M00460_EVCNT_MEMMAP_PACKAGE_H*/ diff --git a/drivers/media/pci/cobalt/m00473_freewheel_memmap_package.h b/drivers/media/pci/cobalt/m00473_freewheel_memmap_package.h new file mode 100644 index 000000000000..384a3e156301 --- /dev/null +++ b/drivers/media/pci/cobalt/m00473_freewheel_memmap_package.h @@ -0,0 +1,57 @@ +/* + * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef M00473_FREEWHEEL_MEMMAP_PACKAGE_H +#define M00473_FREEWHEEL_MEMMAP_PACKAGE_H + +/******************************************************************* + * Register Block + * M00473_FREEWHEEL_MEMMAP_PACKAGE_VHD_REGMAP + *******************************************************************/ +struct m00473_freewheel_regmap { + uint32_t ctrl; /* Reg 0x0000, Default=0x0 */ + uint32_t status; /* Reg 0x0004 */ + uint32_t active_length; /* Reg 0x0008, Default=0x1fa400 */ + uint32_t total_length; /* Reg 0x000c, Default=0x31151b */ + uint32_t data_width; /* Reg 0x0010 */ + uint32_t output_color; /* Reg 0x0014, Default=0xffff */ + uint32_t clk_freq; /* Reg 0x0018 */ +}; + +#define M00473_FREEWHEEL_REG_CTRL_OFST 0 +#define M00473_FREEWHEEL_REG_STATUS_OFST 4 +#define M00473_FREEWHEEL_REG_ACTIVE_LENGTH_OFST 8 +#define M00473_FREEWHEEL_REG_TOTAL_LENGTH_OFST 12 +#define M00473_FREEWHEEL_REG_DATA_WIDTH_OFST 16 +#define M00473_FREEWHEEL_REG_OUTPUT_COLOR_OFST 20 +#define M00473_FREEWHEEL_REG_CLK_FREQ_OFST 24 + +/******************************************************************* + * Bit Mask for register + * M00473_FREEWHEEL_MEMMAP_PACKAGE_VHD_BITMAP + *******************************************************************/ +/* ctrl [1:0] */ +#define M00473_CTRL_BITMAP_ENABLE_OFST (0) +#define M00473_CTRL_BITMAP_ENABLE_MSK (0x1 << M00473_CTRL_BITMAP_ENABLE_OFST) +#define M00473_CTRL_BITMAP_FORCE_FREEWHEEL_MODE_OFST (1) +#define M00473_CTRL_BITMAP_FORCE_FREEWHEEL_MODE_MSK (0x1 << M00473_CTRL_BITMAP_FORCE_FREEWHEEL_MODE_OFST) +/* status [0:0] */ +#define M00473_STATUS_BITMAP_FREEWHEEL_MODE_OFST (0) +#define M00473_STATUS_BITMAP_FREEWHEEL_MODE_MSK (0x1 << M00473_STATUS_BITMAP_FREEWHEEL_MODE_OFST) + +#endif /*M00473_FREEWHEEL_MEMMAP_PACKAGE_H*/ diff --git a/drivers/media/pci/cobalt/m00479_clk_loss_detector_memmap_package.h b/drivers/media/pci/cobalt/m00479_clk_loss_detector_memmap_package.h new file mode 100644 index 000000000000..2a029026bf82 --- /dev/null +++ b/drivers/media/pci/cobalt/m00479_clk_loss_detector_memmap_package.h @@ -0,0 +1,53 @@ +/* + * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef M00479_CLK_LOSS_DETECTOR_MEMMAP_PACKAGE_H +#define M00479_CLK_LOSS_DETECTOR_MEMMAP_PACKAGE_H + +/******************************************************************* + * Register Block + * M00479_CLK_LOSS_DETECTOR_MEMMAP_PACKAGE_VHD_REGMAP + *******************************************************************/ +struct m00479_clk_loss_detector_regmap { + /* Control module */ + uint32_t ctrl; /* Reg 0x0000, Default=0x0 */ + uint32_t status; /* Reg 0x0004 */ + /* Number of ref clk cycles before checking the clock under test */ + uint32_t ref_clk_cnt_val; /* Reg 0x0008, Default=0xc4 */ + /* Number of test clk cycles required in the ref_clk_cnt_val period + * to ensure that the test clock is performing as expected */ + uint32_t test_clk_cnt_val; /* Reg 0x000c, Default=0xa */ +}; + +#define M00479_CLK_LOSS_DETECTOR_REG_CTRL_OFST 0 +#define M00479_CLK_LOSS_DETECTOR_REG_STATUS_OFST 4 +#define M00479_CLK_LOSS_DETECTOR_REG_REF_CLK_CNT_VAL_OFST 8 +#define M00479_CLK_LOSS_DETECTOR_REG_TEST_CLK_CNT_VAL_OFST 12 + +/******************************************************************* + * Bit Mask for register + * M00479_CLK_LOSS_DETECTOR_MEMMAP_PACKAGE_VHD_BITMAP + *******************************************************************/ +/* ctrl [0:0] */ +#define M00479_CTRL_BITMAP_ENABLE_OFST (0) +#define M00479_CTRL_BITMAP_ENABLE_MSK (0x1 << M00479_CTRL_BITMAP_ENABLE_OFST) +/* status [0:0] */ +#define M00479_STATUS_BITMAP_CLOCK_MISSING_OFST (0) +#define M00479_STATUS_BITMAP_CLOCK_MISSING_MSK (0x1 << M00479_STATUS_BITMAP_CLOCK_MISSING_OFST) + +#endif /*M00479_CLK_LOSS_DETECTOR_MEMMAP_PACKAGE_H*/ diff --git a/drivers/media/pci/cobalt/m00514_syncgen_flow_evcnt_memmap_package.h b/drivers/media/pci/cobalt/m00514_syncgen_flow_evcnt_memmap_package.h new file mode 100644 index 000000000000..bdef2df5d689 --- /dev/null +++ b/drivers/media/pci/cobalt/m00514_syncgen_flow_evcnt_memmap_package.h @@ -0,0 +1,88 @@ +/* + * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. + * All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef M00514_SYNCGEN_FLOW_EVCNT_MEMMAP_PACKAGE_H +#define M00514_SYNCGEN_FLOW_EVCNT_MEMMAP_PACKAGE_H + +/******************************************************************* + * Register Block + * M00514_SYNCGEN_FLOW_EVCNT_MEMMAP_PACKAGE_VHD_REGMAP + *******************************************************************/ +struct m00514_syncgen_flow_evcnt_regmap { + uint32_t control; /* Reg 0x0000, Default=0x0 */ + uint32_t sync_generator_h_sync_length; /* Reg 0x0004, Default=0x0 */ + uint32_t sync_generator_h_backporch_length; /* Reg 0x0008, Default=0x0 */ + uint32_t sync_generator_h_active_length; /* Reg 0x000c, Default=0x0 */ + uint32_t sync_generator_h_frontporch_length; /* Reg 0x0010, Default=0x0 */ + uint32_t sync_generator_v_sync_length; /* Reg 0x0014, Default=0x0 */ + uint32_t sync_generator_v_backporch_length; /* Reg 0x0018, Default=0x0 */ + uint32_t sync_generator_v_active_length; /* Reg 0x001c, Default=0x0 */ + uint32_t sync_generator_v_frontporch_length; /* Reg 0x0020, Default=0x0 */ + uint32_t error_color; /* Reg 0x0024, Default=0x0 */ + uint32_t rd_status; /* Reg 0x0028 */ + uint32_t rd_evcnt_count; /* Reg 0x002c */ +}; + +#define M00514_SYNCGEN_FLOW_EVCNT_REG_CONTROL_OFST 0 +#define M00514_SYNCGEN_FLOW_EVCNT_REG_SYNC_GENERATOR_H_SYNC_LENGTH_OFST 4 +#define M00514_SYNCGEN_FLOW_EVCNT_REG_SYNC_GENERATOR_H_BACKPORCH_LENGTH_OFST 8 +#define M00514_SYNCGEN_FLOW_EVCNT_REG_SYNC_GENERATOR_H_ACTIVE_LENGTH_OFST 12 +#define M00514_SYNCGEN_FLOW_EVCNT_REG_SYNC_GENERATOR_H_FRONTPORCH_LENGTH_OFST 16 +#define M00514_SYNCGEN_FLOW_EVCNT_REG_SYNC_GENERATOR_V_SYNC_LENGTH_OFST 20 +#define M00514_SYNCGEN_FLOW_EVCNT_REG_SYNC_GENERATOR_V_BACKPORCH_LENGTH_OFST 24 +#define M00514_SYNCGEN_FLOW_EVCNT_REG_SYNC_GENERATOR_V_ACTIVE_LENGTH_OFST 28 +#define M00514_SYNCGEN_FLOW_EVCNT_REG_SYNC_GENERATOR_V_FRONTPORCH_LENGTH_OFST 32 +#define M00514_SYNCGEN_FLOW_EVCNT_REG_ERROR_COLOR_OFST 36 +#define M00514_SYNCGEN_FLOW_EVCNT_REG_RD_STATUS_OFST 40 +#define M00514_SYNCGEN_FLOW_EVCNT_REG_RD_EVCNT_COUNT_OFST 44 + +/******************************************************************* + * Bit Mask for register + * M00514_SYNCGEN_FLOW_EVCNT_MEMMAP_PACKAGE_VHD_BITMAP + *******************************************************************/ +/* control [7:0] */ +#define M00514_CONTROL_BITMAP_SYNC_GENERATOR_LOAD_PARAM_OFST (0) +#define M00514_CONTROL_BITMAP_SYNC_GENERATOR_LOAD_PARAM_MSK (0x1 << M00514_CONTROL_BITMAP_SYNC_GENERATOR_LOAD_PARAM_OFST) +#define M00514_CONTROL_BITMAP_SYNC_GENERATOR_ENABLE_OFST (1) +#define M00514_CONTROL_BITMAP_SYNC_GENERATOR_ENABLE_MSK (0x1 << M00514_CONTROL_BITMAP_SYNC_GENERATOR_ENABLE_OFST) +#define M00514_CONTROL_BITMAP_FLOW_CTRL_OUTPUT_ENABLE_OFST (2) +#define M00514_CONTROL_BITMAP_FLOW_CTRL_OUTPUT_ENABLE_MSK (0x1 << M00514_CONTROL_BITMAP_FLOW_CTRL_OUTPUT_ENABLE_OFST) +#define M00514_CONTROL_BITMAP_HSYNC_POLARITY_LOW_OFST (3) +#define M00514_CONTROL_BITMAP_HSYNC_POLARITY_LOW_MSK (0x1 << M00514_CONTROL_BITMAP_HSYNC_POLARITY_LOW_OFST) +#define M00514_CONTROL_BITMAP_VSYNC_POLARITY_LOW_OFST (4) +#define M00514_CONTROL_BITMAP_VSYNC_POLARITY_LOW_MSK (0x1 << M00514_CONTROL_BITMAP_VSYNC_POLARITY_LOW_OFST) +#define M00514_CONTROL_BITMAP_EVCNT_ENABLE_OFST (5) +#define M00514_CONTROL_BITMAP_EVCNT_ENABLE_MSK (0x1 << M00514_CONTROL_BITMAP_EVCNT_ENABLE_OFST) +#define M00514_CONTROL_BITMAP_EVCNT_CLEAR_OFST (6) +#define M00514_CONTROL_BITMAP_EVCNT_CLEAR_MSK (0x1 << M00514_CONTROL_BITMAP_EVCNT_CLEAR_OFST) +#define M00514_CONTROL_BITMAP_FORMAT_16_BPP_OFST (7) +#define M00514_CONTROL_BITMAP_FORMAT_16_BPP_MSK (0x1 << M00514_CONTROL_BITMAP_FORMAT_16_BPP_OFST) +/* error_color [23:0] */ +#define M00514_ERROR_COLOR_BITMAP_BLUE_OFST (0) +#define M00514_ERROR_COLOR_BITMAP_BLUE_MSK (0xff << M00514_ERROR_COLOR_BITMAP_BLUE_OFST) +#define M00514_ERROR_COLOR_BITMAP_GREEN_OFST (8) +#define M00514_ERROR_COLOR_BITMAP_GREEN_MSK (0xff << M00514_ERROR_COLOR_BITMAP_GREEN_OFST) +#define M00514_ERROR_COLOR_BITMAP_RED_OFST (16) +#define M00514_ERROR_COLOR_BITMAP_RED_MSK (0xff << M00514_ERROR_COLOR_BITMAP_RED_OFST) +/* rd_status [1:0] */ +#define M00514_RD_STATUS_BITMAP_FLOW_CTRL_NO_DATA_ERROR_OFST (0) +#define M00514_RD_STATUS_BITMAP_FLOW_CTRL_NO_DATA_ERROR_MSK (0x1 << M00514_RD_STATUS_BITMAP_FLOW_CTRL_NO_DATA_ERROR_OFST) +#define M00514_RD_STATUS_BITMAP_READY_BUFFER_FULL_OFST (1) +#define M00514_RD_STATUS_BITMAP_READY_BUFFER_FULL_MSK (0x1 << M00514_RD_STATUS_BITMAP_READY_BUFFER_FULL_OFST) + +#endif /*M00514_SYNCGEN_FLOW_EVCNT_MEMMAP_PACKAGE_H*/ -- cgit v1.2.3-59-g8ed1b From e4d131d392073e498d23bb0e52198258c3637116 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 14 May 2015 05:39:17 -0300 Subject: [media] rtl2832_sdr: cleanup some set_bit() calls This code works fine but static checkers complain. The test_bit() function takes the bit number and not a mask. Then the other issue is that we were using USB_STATE_URB_BUF which is BIT(0) instead of URB_BUF. Also we were open coding that instead of using the test/clear/set_bit() functions. Signed-off-by: Dan Carpenter Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/rtl2832_sdr.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/rtl2832_sdr.c b/drivers/media/dvb-frontends/rtl2832_sdr.c index c501bcd680b5..7edb885ae9c8 100644 --- a/drivers/media/dvb-frontends/rtl2832_sdr.c +++ b/drivers/media/dvb-frontends/rtl2832_sdr.c @@ -112,8 +112,8 @@ struct rtl2832_sdr_frame_buf { }; struct rtl2832_sdr_dev { -#define POWER_ON (1 << 1) -#define URB_BUF (1 << 2) +#define POWER_ON 0 /* BIT(0) */ +#define URB_BUF 1 /* BIT(1) */ unsigned long flags; struct platform_device *pdev; @@ -356,7 +356,7 @@ static int rtl2832_sdr_free_stream_bufs(struct rtl2832_sdr_dev *dev) { struct platform_device *pdev = dev->pdev; - if (dev->flags & USB_STATE_URB_BUF) { + if (test_bit(URB_BUF, &dev->flags)) { while (dev->buf_num) { dev->buf_num--; dev_dbg(&pdev->dev, "free buf=%d\n", dev->buf_num); @@ -365,7 +365,7 @@ static int rtl2832_sdr_free_stream_bufs(struct rtl2832_sdr_dev *dev) dev->dma_addr[dev->buf_num]); } } - dev->flags &= ~USB_STATE_URB_BUF; + clear_bit(URB_BUF, &dev->flags); return 0; } @@ -394,7 +394,7 @@ static int rtl2832_sdr_alloc_stream_bufs(struct rtl2832_sdr_dev *dev) dev_dbg(&pdev->dev, "alloc buf=%d %p (dma %llu)\n", dev->buf_num, dev->buf_list[dev->buf_num], (long long)dev->dma_addr[dev->buf_num]); - dev->flags |= USB_STATE_URB_BUF; + set_bit(URB_BUF, &dev->flags); } return 0; -- cgit v1.2.3-59-g8ed1b From 0e3a71c3749fa451505a67a61d61e142a96ceb23 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 21 Apr 2015 21:18:45 -0300 Subject: [media] e4000: revise synthesizer calculation Update synthesizer calculation to model I prefer nowadays. It is mostly just renaming some variables to ones I think are most standard. Also add 'schematic' of synthesizer following my current understanding. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/e4000.c | 44 +++++++++++++++++++++++++++------------ drivers/media/tuners/e4000_priv.h | 4 ++-- 2 files changed, 33 insertions(+), 15 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/e4000.c b/drivers/media/tuners/e4000.c index 510239f80c0d..cda8bcf164de 100644 --- a/drivers/media/tuners/e4000.c +++ b/drivers/media/tuners/e4000.c @@ -115,8 +115,8 @@ static int e4000_set_params(struct dvb_frontend *fe) { struct e4000 *s = fe->tuner_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int ret, i, sigma_delta; - unsigned int pll_n, pll_f; + int ret, i; + unsigned int div_n, k, k_cw, div_out; u64 f_vco; u8 buf[5], i_data[4], q_data[4]; @@ -129,7 +129,21 @@ static int e4000_set_params(struct dvb_frontend *fe) if (ret) goto err; - /* PLL */ + /* + * Fractional-N synthesizer + * + * +----------------------------+ + * v | + * Fref +----+ +-------+ +------+ +---+ + * ------> | PD | --> | VCO | ------> | /N.F | <-- | K | + * +----+ +-------+ +------+ +---+ + * | + * | + * v + * +-------+ Fout + * | /Rout | ------> + * +-------+ + */ for (i = 0; i < ARRAY_SIZE(e4000_pll_lut); i++) { if (c->frequency <= e4000_pll_lut[i].freq) break; @@ -140,18 +154,22 @@ static int e4000_set_params(struct dvb_frontend *fe) goto err; } - f_vco = 1ull * c->frequency * e4000_pll_lut[i].mul; - pll_n = div_u64_rem(f_vco, s->clock, &pll_f); - sigma_delta = div_u64(0x10000ULL * pll_f, s->clock); - buf[0] = pll_n; - buf[1] = (sigma_delta >> 0) & 0xff; - buf[2] = (sigma_delta >> 8) & 0xff; - buf[3] = 0x00; - buf[4] = e4000_pll_lut[i].div; + #define F_REF s->clock + div_out = e4000_pll_lut[i].div_out; + f_vco = (u64) c->frequency * div_out; + /* calculate PLL integer and fractional control word */ + div_n = div_u64_rem(f_vco, F_REF, &k); + k_cw = div_u64((u64) k * 0x10000, F_REF); - dev_dbg(&s->client->dev, "f_vco=%llu pll div=%d sigma_delta=%04x\n", - f_vco, buf[0], sigma_delta); + dev_dbg(&s->client->dev, + "frequency=%u f_vco=%llu F_REF=%u div_n=%u k=%u k_cw=%04x div_out=%u\n", + c->frequency, f_vco, F_REF, div_n, k, k_cw, div_out); + buf[0] = div_n; + buf[1] = (k_cw >> 0) & 0xff; + buf[2] = (k_cw >> 8) & 0xff; + buf[3] = 0x00; + buf[4] = e4000_pll_lut[i].div_out_reg; ret = regmap_bulk_write(s->regmap, 0x09, buf, 5); if (ret) goto err; diff --git a/drivers/media/tuners/e4000_priv.h b/drivers/media/tuners/e4000_priv.h index cb0070483e65..6214fc05bf70 100644 --- a/drivers/media/tuners/e4000_priv.h +++ b/drivers/media/tuners/e4000_priv.h @@ -49,8 +49,8 @@ struct e4000 { struct e4000_pll { u32 freq; - u8 div; - u8 mul; + u8 div_out_reg; + u8 div_out; }; static const struct e4000_pll e4000_pll_lut[] = { -- cgit v1.2.3-59-g8ed1b From f8b9b871f832a618f71be17fe7d90034e0862862 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 21 Apr 2015 17:13:39 -0300 Subject: [media] e4000: various small changes * Rename device state from 's' to 'dev'. * Move single include to driver private header. * Change error handling type of each function to one I tend use nowadays. * Remove dummy register write from init. Even Windows driver does this multiple times remove it as I have never seen any I2C errors. * Define I2C client pointer for each function and use it. * Do not clean tuner ops during driver remove - not needed. * Disable sysfs device bind / unbind. We are not allowed manually bind / unbind device from the driver currently. * Rename some other variables. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/e4000.c | 358 +++++++++++++++++++------------------- drivers/media/tuners/e4000.h | 1 - drivers/media/tuners/e4000_priv.h | 5 +- 3 files changed, 178 insertions(+), 186 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/e4000.c b/drivers/media/tuners/e4000.c index cda8bcf164de..57bdca44a5bd 100644 --- a/drivers/media/tuners/e4000.c +++ b/drivers/media/tuners/e4000.c @@ -19,113 +19,112 @@ */ #include "e4000_priv.h" -#include static int e4000_init(struct dvb_frontend *fe) { - struct e4000 *s = fe->tuner_priv; + struct e4000_dev *dev = fe->tuner_priv; + struct i2c_client *client = dev->client; int ret; - dev_dbg(&s->client->dev, "\n"); - - /* dummy I2C to ensure I2C wakes up */ - ret = regmap_write(s->regmap, 0x02, 0x40); + dev_dbg(&client->dev, "\n"); /* reset */ - ret = regmap_write(s->regmap, 0x00, 0x01); + ret = regmap_write(dev->regmap, 0x00, 0x01); if (ret) goto err; /* disable output clock */ - ret = regmap_write(s->regmap, 0x06, 0x00); + ret = regmap_write(dev->regmap, 0x06, 0x00); if (ret) goto err; - ret = regmap_write(s->regmap, 0x7a, 0x96); + ret = regmap_write(dev->regmap, 0x7a, 0x96); if (ret) goto err; /* configure gains */ - ret = regmap_bulk_write(s->regmap, 0x7e, "\x01\xfe", 2); + ret = regmap_bulk_write(dev->regmap, 0x7e, "\x01\xfe", 2); if (ret) goto err; - ret = regmap_write(s->regmap, 0x82, 0x00); + ret = regmap_write(dev->regmap, 0x82, 0x00); if (ret) goto err; - ret = regmap_write(s->regmap, 0x24, 0x05); + ret = regmap_write(dev->regmap, 0x24, 0x05); if (ret) goto err; - ret = regmap_bulk_write(s->regmap, 0x87, "\x20\x01", 2); + ret = regmap_bulk_write(dev->regmap, 0x87, "\x20\x01", 2); if (ret) goto err; - ret = regmap_bulk_write(s->regmap, 0x9f, "\x7f\x07", 2); + ret = regmap_bulk_write(dev->regmap, 0x9f, "\x7f\x07", 2); if (ret) goto err; /* DC offset control */ - ret = regmap_write(s->regmap, 0x2d, 0x1f); + ret = regmap_write(dev->regmap, 0x2d, 0x1f); if (ret) goto err; - ret = regmap_bulk_write(s->regmap, 0x70, "\x01\x01", 2); + ret = regmap_bulk_write(dev->regmap, 0x70, "\x01\x01", 2); if (ret) goto err; /* gain control */ - ret = regmap_write(s->regmap, 0x1a, 0x17); + ret = regmap_write(dev->regmap, 0x1a, 0x17); if (ret) goto err; - ret = regmap_write(s->regmap, 0x1f, 0x1a); + ret = regmap_write(dev->regmap, 0x1f, 0x1a); if (ret) goto err; - s->active = true; -err: - if (ret) - dev_dbg(&s->client->dev, "failed=%d\n", ret); + dev->active = true; + return 0; +err: + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int e4000_sleep(struct dvb_frontend *fe) { - struct e4000 *s = fe->tuner_priv; + struct e4000_dev *dev = fe->tuner_priv; + struct i2c_client *client = dev->client; int ret; - dev_dbg(&s->client->dev, "\n"); + dev_dbg(&client->dev, "\n"); - s->active = false; + dev->active = false; - ret = regmap_write(s->regmap, 0x00, 0x00); + ret = regmap_write(dev->regmap, 0x00, 0x00); if (ret) goto err; -err: - if (ret) - dev_dbg(&s->client->dev, "failed=%d\n", ret); + return 0; +err: + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int e4000_set_params(struct dvb_frontend *fe) { - struct e4000 *s = fe->tuner_priv; + struct e4000_dev *dev = fe->tuner_priv; + struct i2c_client *client = dev->client; struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, i; unsigned int div_n, k, k_cw, div_out; u64 f_vco; u8 buf[5], i_data[4], q_data[4]; - dev_dbg(&s->client->dev, - "delivery_system=%d frequency=%u bandwidth_hz=%u\n", - c->delivery_system, c->frequency, c->bandwidth_hz); + dev_dbg(&client->dev, + "delivery_system=%d frequency=%u bandwidth_hz=%u\n", + c->delivery_system, c->frequency, c->bandwidth_hz); /* gain control manual */ - ret = regmap_write(s->regmap, 0x1a, 0x00); + ret = regmap_write(dev->regmap, 0x1a, 0x00); if (ret) goto err; @@ -148,20 +147,19 @@ static int e4000_set_params(struct dvb_frontend *fe) if (c->frequency <= e4000_pll_lut[i].freq) break; } - if (i == ARRAY_SIZE(e4000_pll_lut)) { ret = -EINVAL; goto err; } - #define F_REF s->clock + #define F_REF dev->clk div_out = e4000_pll_lut[i].div_out; f_vco = (u64) c->frequency * div_out; /* calculate PLL integer and fractional control word */ div_n = div_u64_rem(f_vco, F_REF, &k); k_cw = div_u64((u64) k * 0x10000, F_REF); - dev_dbg(&s->client->dev, + dev_dbg(&client->dev, "frequency=%u f_vco=%llu F_REF=%u div_n=%u k=%u k_cw=%04x div_out=%u\n", c->frequency, f_vco, F_REF, div_n, k, k_cw, div_out); @@ -170,7 +168,7 @@ static int e4000_set_params(struct dvb_frontend *fe) buf[2] = (k_cw >> 8) & 0xff; buf[3] = 0x00; buf[4] = e4000_pll_lut[i].div_out_reg; - ret = regmap_bulk_write(s->regmap, 0x09, buf, 5); + ret = regmap_bulk_write(dev->regmap, 0x09, buf, 5); if (ret) goto err; @@ -179,13 +177,12 @@ static int e4000_set_params(struct dvb_frontend *fe) if (c->frequency <= e400_lna_filter_lut[i].freq) break; } - if (i == ARRAY_SIZE(e400_lna_filter_lut)) { ret = -EINVAL; goto err; } - ret = regmap_write(s->regmap, 0x10, e400_lna_filter_lut[i].val); + ret = regmap_write(dev->regmap, 0x10, e400_lna_filter_lut[i].val); if (ret) goto err; @@ -194,7 +191,6 @@ static int e4000_set_params(struct dvb_frontend *fe) if (c->bandwidth_hz <= e4000_if_filter_lut[i].freq) break; } - if (i == ARRAY_SIZE(e4000_if_filter_lut)) { ret = -EINVAL; goto err; @@ -203,7 +199,7 @@ static int e4000_set_params(struct dvb_frontend *fe) buf[0] = e4000_if_filter_lut[i].reg11_val; buf[1] = e4000_if_filter_lut[i].reg12_val; - ret = regmap_bulk_write(s->regmap, 0x11, buf, 2); + ret = regmap_bulk_write(dev->regmap, 0x11, buf, 2); if (ret) goto err; @@ -212,39 +208,38 @@ static int e4000_set_params(struct dvb_frontend *fe) if (c->frequency <= e4000_band_lut[i].freq) break; } - if (i == ARRAY_SIZE(e4000_band_lut)) { ret = -EINVAL; goto err; } - ret = regmap_write(s->regmap, 0x07, e4000_band_lut[i].reg07_val); + ret = regmap_write(dev->regmap, 0x07, e4000_band_lut[i].reg07_val); if (ret) goto err; - ret = regmap_write(s->regmap, 0x78, e4000_band_lut[i].reg78_val); + ret = regmap_write(dev->regmap, 0x78, e4000_band_lut[i].reg78_val); if (ret) goto err; /* DC offset */ for (i = 0; i < 4; i++) { if (i == 0) - ret = regmap_bulk_write(s->regmap, 0x15, "\x00\x7e\x24", 3); + ret = regmap_bulk_write(dev->regmap, 0x15, "\x00\x7e\x24", 3); else if (i == 1) - ret = regmap_bulk_write(s->regmap, 0x15, "\x00\x7f", 2); + ret = regmap_bulk_write(dev->regmap, 0x15, "\x00\x7f", 2); else if (i == 2) - ret = regmap_bulk_write(s->regmap, 0x15, "\x01", 1); + ret = regmap_bulk_write(dev->regmap, 0x15, "\x01", 1); else - ret = regmap_bulk_write(s->regmap, 0x16, "\x7e", 1); + ret = regmap_bulk_write(dev->regmap, 0x16, "\x7e", 1); if (ret) goto err; - ret = regmap_write(s->regmap, 0x29, 0x01); + ret = regmap_write(dev->regmap, 0x29, 0x01); if (ret) goto err; - ret = regmap_bulk_read(s->regmap, 0x2a, buf, 3); + ret = regmap_bulk_read(dev->regmap, 0x2a, buf, 3); if (ret) goto err; @@ -255,30 +250,31 @@ static int e4000_set_params(struct dvb_frontend *fe) swap(q_data[2], q_data[3]); swap(i_data[2], i_data[3]); - ret = regmap_bulk_write(s->regmap, 0x50, q_data, 4); + ret = regmap_bulk_write(dev->regmap, 0x50, q_data, 4); if (ret) goto err; - ret = regmap_bulk_write(s->regmap, 0x60, i_data, 4); + ret = regmap_bulk_write(dev->regmap, 0x60, i_data, 4); if (ret) goto err; /* gain control auto */ - ret = regmap_write(s->regmap, 0x1a, 0x17); + ret = regmap_write(dev->regmap, 0x1a, 0x17); if (ret) goto err; -err: - if (ret) - dev_dbg(&s->client->dev, "failed=%d\n", ret); + return 0; +err: + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int e4000_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) { - struct e4000 *s = fe->tuner_priv; + struct e4000_dev *dev = fe->tuner_priv; + struct i2c_client *client = dev->client; - dev_dbg(&s->client->dev, "\n"); + dev_dbg(&client->dev, "\n"); *frequency = 0; /* Zero-IF */ @@ -288,141 +284,146 @@ static int e4000_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) #if IS_ENABLED(CONFIG_VIDEO_V4L2) static int e4000_set_lna_gain(struct dvb_frontend *fe) { - struct e4000 *s = fe->tuner_priv; + struct e4000_dev *dev = fe->tuner_priv; + struct i2c_client *client = dev->client; int ret; u8 u8tmp; - dev_dbg(&s->client->dev, "lna auto=%d->%d val=%d->%d\n", - s->lna_gain_auto->cur.val, s->lna_gain_auto->val, - s->lna_gain->cur.val, s->lna_gain->val); + dev_dbg(&client->dev, "lna auto=%d->%d val=%d->%d\n", + dev->lna_gain_auto->cur.val, dev->lna_gain_auto->val, + dev->lna_gain->cur.val, dev->lna_gain->val); - if (s->lna_gain_auto->val && s->if_gain_auto->cur.val) + if (dev->lna_gain_auto->val && dev->if_gain_auto->cur.val) u8tmp = 0x17; - else if (s->lna_gain_auto->val) + else if (dev->lna_gain_auto->val) u8tmp = 0x19; - else if (s->if_gain_auto->cur.val) + else if (dev->if_gain_auto->cur.val) u8tmp = 0x16; else u8tmp = 0x10; - ret = regmap_write(s->regmap, 0x1a, u8tmp); + ret = regmap_write(dev->regmap, 0x1a, u8tmp); if (ret) goto err; - if (s->lna_gain_auto->val == false) { - ret = regmap_write(s->regmap, 0x14, s->lna_gain->val); + if (dev->lna_gain_auto->val == false) { + ret = regmap_write(dev->regmap, 0x14, dev->lna_gain->val); if (ret) goto err; } -err: - if (ret) - dev_dbg(&s->client->dev, "failed=%d\n", ret); + return 0; +err: + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int e4000_set_mixer_gain(struct dvb_frontend *fe) { - struct e4000 *s = fe->tuner_priv; + struct e4000_dev *dev = fe->tuner_priv; + struct i2c_client *client = dev->client; int ret; u8 u8tmp; - dev_dbg(&s->client->dev, "mixer auto=%d->%d val=%d->%d\n", - s->mixer_gain_auto->cur.val, s->mixer_gain_auto->val, - s->mixer_gain->cur.val, s->mixer_gain->val); + dev_dbg(&client->dev, "mixer auto=%d->%d val=%d->%d\n", + dev->mixer_gain_auto->cur.val, dev->mixer_gain_auto->val, + dev->mixer_gain->cur.val, dev->mixer_gain->val); - if (s->mixer_gain_auto->val) + if (dev->mixer_gain_auto->val) u8tmp = 0x15; else u8tmp = 0x14; - ret = regmap_write(s->regmap, 0x20, u8tmp); + ret = regmap_write(dev->regmap, 0x20, u8tmp); if (ret) goto err; - if (s->mixer_gain_auto->val == false) { - ret = regmap_write(s->regmap, 0x15, s->mixer_gain->val); + if (dev->mixer_gain_auto->val == false) { + ret = regmap_write(dev->regmap, 0x15, dev->mixer_gain->val); if (ret) goto err; } -err: - if (ret) - dev_dbg(&s->client->dev, "failed=%d\n", ret); + return 0; +err: + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int e4000_set_if_gain(struct dvb_frontend *fe) { - struct e4000 *s = fe->tuner_priv; + struct e4000_dev *dev = fe->tuner_priv; + struct i2c_client *client = dev->client; int ret; u8 buf[2]; u8 u8tmp; - dev_dbg(&s->client->dev, "if auto=%d->%d val=%d->%d\n", - s->if_gain_auto->cur.val, s->if_gain_auto->val, - s->if_gain->cur.val, s->if_gain->val); + dev_dbg(&client->dev, "if auto=%d->%d val=%d->%d\n", + dev->if_gain_auto->cur.val, dev->if_gain_auto->val, + dev->if_gain->cur.val, dev->if_gain->val); - if (s->if_gain_auto->val && s->lna_gain_auto->cur.val) + if (dev->if_gain_auto->val && dev->lna_gain_auto->cur.val) u8tmp = 0x17; - else if (s->lna_gain_auto->cur.val) + else if (dev->lna_gain_auto->cur.val) u8tmp = 0x19; - else if (s->if_gain_auto->val) + else if (dev->if_gain_auto->val) u8tmp = 0x16; else u8tmp = 0x10; - ret = regmap_write(s->regmap, 0x1a, u8tmp); + ret = regmap_write(dev->regmap, 0x1a, u8tmp); if (ret) goto err; - if (s->if_gain_auto->val == false) { - buf[0] = e4000_if_gain_lut[s->if_gain->val].reg16_val; - buf[1] = e4000_if_gain_lut[s->if_gain->val].reg17_val; - ret = regmap_bulk_write(s->regmap, 0x16, buf, 2); + if (dev->if_gain_auto->val == false) { + buf[0] = e4000_if_gain_lut[dev->if_gain->val].reg16_val; + buf[1] = e4000_if_gain_lut[dev->if_gain->val].reg17_val; + ret = regmap_bulk_write(dev->regmap, 0x16, buf, 2); if (ret) goto err; } -err: - if (ret) - dev_dbg(&s->client->dev, "failed=%d\n", ret); + return 0; +err: + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int e4000_pll_lock(struct dvb_frontend *fe) { - struct e4000 *s = fe->tuner_priv; + struct e4000_dev *dev = fe->tuner_priv; + struct i2c_client *client = dev->client; int ret; - unsigned int utmp; + unsigned int uitmp; - ret = regmap_read(s->regmap, 0x07, &utmp); + ret = regmap_read(dev->regmap, 0x07, &uitmp); if (ret) goto err; - s->pll_lock->val = (utmp & 0x01); -err: - if (ret) - dev_dbg(&s->client->dev, "failed=%d\n", ret); + dev->pll_lock->val = (uitmp & 0x01); + return 0; +err: + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int e4000_g_volatile_ctrl(struct v4l2_ctrl *ctrl) { - struct e4000 *s = container_of(ctrl->handler, struct e4000, hdl); + struct e4000_dev *dev = container_of(ctrl->handler, struct e4000_dev, hdl); + struct i2c_client *client = dev->client; int ret; - if (!s->active) + if (!dev->active) return 0; switch (ctrl->id) { case V4L2_CID_RF_TUNER_PLL_LOCK: - ret = e4000_pll_lock(s->fe); + ret = e4000_pll_lock(dev->fe); break; default: - dev_dbg(&s->client->dev, "unknown ctrl: id=%d name=%s\n", - ctrl->id, ctrl->name); + dev_dbg(&client->dev, "unknown ctrl: id=%d name=%s\n", + ctrl->id, ctrl->name); ret = -EINVAL; } @@ -431,35 +432,35 @@ static int e4000_g_volatile_ctrl(struct v4l2_ctrl *ctrl) static int e4000_s_ctrl(struct v4l2_ctrl *ctrl) { - struct e4000 *s = container_of(ctrl->handler, struct e4000, hdl); - struct dvb_frontend *fe = s->fe; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct e4000_dev *dev = container_of(ctrl->handler, struct e4000_dev, hdl); + struct i2c_client *client = dev->client; + struct dtv_frontend_properties *c = &dev->fe->dtv_property_cache; int ret; - if (!s->active) + if (!dev->active) return 0; switch (ctrl->id) { case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO: case V4L2_CID_RF_TUNER_BANDWIDTH: - c->bandwidth_hz = s->bandwidth->val; - ret = e4000_set_params(s->fe); + c->bandwidth_hz = dev->bandwidth->val; + ret = e4000_set_params(dev->fe); break; case V4L2_CID_RF_TUNER_LNA_GAIN_AUTO: case V4L2_CID_RF_TUNER_LNA_GAIN: - ret = e4000_set_lna_gain(s->fe); + ret = e4000_set_lna_gain(dev->fe); break; case V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO: case V4L2_CID_RF_TUNER_MIXER_GAIN: - ret = e4000_set_mixer_gain(s->fe); + ret = e4000_set_mixer_gain(dev->fe); break; case V4L2_CID_RF_TUNER_IF_GAIN_AUTO: case V4L2_CID_RF_TUNER_IF_GAIN: - ret = e4000_set_if_gain(s->fe); + ret = e4000_set_if_gain(dev->fe); break; default: - dev_dbg(&s->client->dev, "unknown ctrl: id=%d name=%s\n", - ctrl->id, ctrl->name); + dev_dbg(&client->dev, "unknown ctrl: id=%d name=%s\n", + ctrl->id, ctrl->name); ret = -EINVAL; } @@ -491,138 +492,129 @@ static const struct dvb_tuner_ops e4000_tuner_ops = { * subdev itself, just to avoid reinventing the wheel. */ static int e4000_probe(struct i2c_client *client, - const struct i2c_device_id *id) + const struct i2c_device_id *id) { + struct e4000_dev *dev; struct e4000_config *cfg = client->dev.platform_data; struct dvb_frontend *fe = cfg->fe; - struct e4000 *s; int ret; - unsigned int utmp; + unsigned int uitmp; static const struct regmap_config regmap_config = { .reg_bits = 8, .val_bits = 8, - .max_register = 0xff, }; - s = kzalloc(sizeof(struct e4000), GFP_KERNEL); - if (!s) { + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) { ret = -ENOMEM; - dev_err(&client->dev, "kzalloc() failed\n"); goto err; } - s->clock = cfg->clock; - s->client = client; - s->fe = cfg->fe; - s->regmap = devm_regmap_init_i2c(client, ®map_config); - if (IS_ERR(s->regmap)) { - ret = PTR_ERR(s->regmap); - goto err; + dev->clk = cfg->clock; + dev->client = client; + dev->fe = cfg->fe; + dev->regmap = devm_regmap_init_i2c(client, ®map_config); + if (IS_ERR(dev->regmap)) { + ret = PTR_ERR(dev->regmap); + goto err_kfree; } /* check if the tuner is there */ - ret = regmap_read(s->regmap, 0x02, &utmp); + ret = regmap_read(dev->regmap, 0x02, &uitmp); if (ret) - goto err; + goto err_kfree; - dev_dbg(&s->client->dev, "chip id=%02x\n", utmp); + dev_dbg(&client->dev, "chip id=%02x\n", uitmp); - if (utmp != 0x40) { + if (uitmp != 0x40) { ret = -ENODEV; - goto err; + goto err_kfree; } /* put sleep as chip seems to be in normal mode by default */ - ret = regmap_write(s->regmap, 0x00, 0x00); + ret = regmap_write(dev->regmap, 0x00, 0x00); if (ret) - goto err; + goto err_kfree; #if IS_ENABLED(CONFIG_VIDEO_V4L2) /* Register controls */ - v4l2_ctrl_handler_init(&s->hdl, 9); - s->bandwidth_auto = v4l2_ctrl_new_std(&s->hdl, &e4000_ctrl_ops, + v4l2_ctrl_handler_init(&dev->hdl, 9); + dev->bandwidth_auto = v4l2_ctrl_new_std(&dev->hdl, &e4000_ctrl_ops, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1); - s->bandwidth = v4l2_ctrl_new_std(&s->hdl, &e4000_ctrl_ops, + dev->bandwidth = v4l2_ctrl_new_std(&dev->hdl, &e4000_ctrl_ops, V4L2_CID_RF_TUNER_BANDWIDTH, 4300000, 11000000, 100000, 4300000); - v4l2_ctrl_auto_cluster(2, &s->bandwidth_auto, 0, false); - s->lna_gain_auto = v4l2_ctrl_new_std(&s->hdl, &e4000_ctrl_ops, + v4l2_ctrl_auto_cluster(2, &dev->bandwidth_auto, 0, false); + dev->lna_gain_auto = v4l2_ctrl_new_std(&dev->hdl, &e4000_ctrl_ops, V4L2_CID_RF_TUNER_LNA_GAIN_AUTO, 0, 1, 1, 1); - s->lna_gain = v4l2_ctrl_new_std(&s->hdl, &e4000_ctrl_ops, + dev->lna_gain = v4l2_ctrl_new_std(&dev->hdl, &e4000_ctrl_ops, V4L2_CID_RF_TUNER_LNA_GAIN, 0, 15, 1, 10); - v4l2_ctrl_auto_cluster(2, &s->lna_gain_auto, 0, false); - s->mixer_gain_auto = v4l2_ctrl_new_std(&s->hdl, &e4000_ctrl_ops, + v4l2_ctrl_auto_cluster(2, &dev->lna_gain_auto, 0, false); + dev->mixer_gain_auto = v4l2_ctrl_new_std(&dev->hdl, &e4000_ctrl_ops, V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO, 0, 1, 1, 1); - s->mixer_gain = v4l2_ctrl_new_std(&s->hdl, &e4000_ctrl_ops, + dev->mixer_gain = v4l2_ctrl_new_std(&dev->hdl, &e4000_ctrl_ops, V4L2_CID_RF_TUNER_MIXER_GAIN, 0, 1, 1, 1); - v4l2_ctrl_auto_cluster(2, &s->mixer_gain_auto, 0, false); - s->if_gain_auto = v4l2_ctrl_new_std(&s->hdl, &e4000_ctrl_ops, + v4l2_ctrl_auto_cluster(2, &dev->mixer_gain_auto, 0, false); + dev->if_gain_auto = v4l2_ctrl_new_std(&dev->hdl, &e4000_ctrl_ops, V4L2_CID_RF_TUNER_IF_GAIN_AUTO, 0, 1, 1, 1); - s->if_gain = v4l2_ctrl_new_std(&s->hdl, &e4000_ctrl_ops, + dev->if_gain = v4l2_ctrl_new_std(&dev->hdl, &e4000_ctrl_ops, V4L2_CID_RF_TUNER_IF_GAIN, 0, 54, 1, 0); - v4l2_ctrl_auto_cluster(2, &s->if_gain_auto, 0, false); - s->pll_lock = v4l2_ctrl_new_std(&s->hdl, &e4000_ctrl_ops, + v4l2_ctrl_auto_cluster(2, &dev->if_gain_auto, 0, false); + dev->pll_lock = v4l2_ctrl_new_std(&dev->hdl, &e4000_ctrl_ops, V4L2_CID_RF_TUNER_PLL_LOCK, 0, 1, 1, 0); - if (s->hdl.error) { - ret = s->hdl.error; - dev_err(&s->client->dev, "Could not initialize controls\n"); - v4l2_ctrl_handler_free(&s->hdl); - goto err; + if (dev->hdl.error) { + ret = dev->hdl.error; + dev_err(&client->dev, "Could not initialize controls\n"); + v4l2_ctrl_handler_free(&dev->hdl); + goto err_kfree; } - s->sd.ctrl_handler = &s->hdl; + dev->sd.ctrl_handler = &dev->hdl; #endif - - dev_info(&s->client->dev, "Elonics E4000 successfully identified\n"); - - fe->tuner_priv = s; + fe->tuner_priv = dev; memcpy(&fe->ops.tuner_ops, &e4000_tuner_ops, sizeof(struct dvb_tuner_ops)); + v4l2_set_subdevdata(&dev->sd, client); + i2c_set_clientdata(client, &dev->sd); - v4l2_set_subdevdata(&s->sd, client); - i2c_set_clientdata(client, &s->sd); - + dev_info(&client->dev, "Elonics E4000 successfully identified\n"); return 0; +err_kfree: + kfree(dev); err: - if (ret) { - dev_dbg(&client->dev, "failed=%d\n", ret); - kfree(s); - } - + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int e4000_remove(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct e4000 *s = container_of(sd, struct e4000, sd); - struct dvb_frontend *fe = s->fe; + struct e4000_dev *dev = container_of(sd, struct e4000_dev, sd); dev_dbg(&client->dev, "\n"); #if IS_ENABLED(CONFIG_VIDEO_V4L2) - v4l2_ctrl_handler_free(&s->hdl); + v4l2_ctrl_handler_free(&dev->hdl); #endif - memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops)); - fe->tuner_priv = NULL; - kfree(s); + kfree(dev); return 0; } -static const struct i2c_device_id e4000_id[] = { +static const struct i2c_device_id e4000_id_table[] = { {"e4000", 0}, {} }; -MODULE_DEVICE_TABLE(i2c, e4000_id); +MODULE_DEVICE_TABLE(i2c, e4000_id_table); static struct i2c_driver e4000_driver = { .driver = { .owner = THIS_MODULE, .name = "e4000", + .suppress_bind_attrs = true, }, .probe = e4000_probe, .remove = e4000_remove, - .id_table = e4000_id, + .id_table = e4000_id_table, }; module_i2c_driver(e4000_driver); diff --git a/drivers/media/tuners/e4000.h b/drivers/media/tuners/e4000.h index e74b8b2f2fc3..aa9340c05b43 100644 --- a/drivers/media/tuners/e4000.h +++ b/drivers/media/tuners/e4000.h @@ -21,7 +21,6 @@ #ifndef E4000_H #define E4000_H -#include #include "dvb_frontend.h" /* diff --git a/drivers/media/tuners/e4000_priv.h b/drivers/media/tuners/e4000_priv.h index 6214fc05bf70..8e991df9509e 100644 --- a/drivers/media/tuners/e4000_priv.h +++ b/drivers/media/tuners/e4000_priv.h @@ -22,14 +22,15 @@ #define E4000_PRIV_H #include "e4000.h" +#include #include #include #include -struct e4000 { +struct e4000_dev { struct i2c_client *client; struct regmap *regmap; - u32 clock; + u32 clk; struct dvb_frontend *fe; struct v4l2_subdev sd; bool active; -- cgit v1.2.3-59-g8ed1b From c7861bb048669540ff51e2e1bf84d60f165007ad Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 12 May 2015 14:26:07 -0300 Subject: [media] e4000: implement V4L2 subdevice tuner and core ops Implement V4L2 subdevice tuner and core ops. After that this driver is hybrid driver implementing both V4L2 and DVB ops. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/e4000.c | 216 +++++++++++++++++++++++++++++++------- drivers/media/tuners/e4000_priv.h | 2 + 2 files changed, 182 insertions(+), 36 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/e4000.c b/drivers/media/tuners/e4000.c index 57bdca44a5bd..3b49a4550bd3 100644 --- a/drivers/media/tuners/e4000.c +++ b/drivers/media/tuners/e4000.c @@ -20,9 +20,8 @@ #include "e4000_priv.h" -static int e4000_init(struct dvb_frontend *fe) +static int e4000_init(struct e4000_dev *dev) { - struct e4000_dev *dev = fe->tuner_priv; struct i2c_client *client = dev->client; int ret; @@ -89,9 +88,8 @@ err: return ret; } -static int e4000_sleep(struct dvb_frontend *fe) +static int e4000_sleep(struct e4000_dev *dev) { - struct e4000_dev *dev = fe->tuner_priv; struct i2c_client *client = dev->client; int ret; @@ -109,19 +107,18 @@ err: return ret; } -static int e4000_set_params(struct dvb_frontend *fe) +static int e4000_set_params(struct e4000_dev *dev) { - struct e4000_dev *dev = fe->tuner_priv; struct i2c_client *client = dev->client; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, i; unsigned int div_n, k, k_cw, div_out; u64 f_vco; u8 buf[5], i_data[4], q_data[4]; - dev_dbg(&client->dev, - "delivery_system=%d frequency=%u bandwidth_hz=%u\n", - c->delivery_system, c->frequency, c->bandwidth_hz); + if (!dev->active) { + dev_dbg(&client->dev, "tuner is sleeping\n"); + return 0; + } /* gain control manual */ ret = regmap_write(dev->regmap, 0x1a, 0x00); @@ -144,7 +141,7 @@ static int e4000_set_params(struct dvb_frontend *fe) * +-------+ */ for (i = 0; i < ARRAY_SIZE(e4000_pll_lut); i++) { - if (c->frequency <= e4000_pll_lut[i].freq) + if (dev->f_frequency <= e4000_pll_lut[i].freq) break; } if (i == ARRAY_SIZE(e4000_pll_lut)) { @@ -154,14 +151,15 @@ static int e4000_set_params(struct dvb_frontend *fe) #define F_REF dev->clk div_out = e4000_pll_lut[i].div_out; - f_vco = (u64) c->frequency * div_out; + f_vco = (u64) dev->f_frequency * div_out; /* calculate PLL integer and fractional control word */ div_n = div_u64_rem(f_vco, F_REF, &k); k_cw = div_u64((u64) k * 0x10000, F_REF); dev_dbg(&client->dev, - "frequency=%u f_vco=%llu F_REF=%u div_n=%u k=%u k_cw=%04x div_out=%u\n", - c->frequency, f_vco, F_REF, div_n, k, k_cw, div_out); + "frequency=%u bandwidth=%u f_vco=%llu F_REF=%u div_n=%u k=%u k_cw=%04x div_out=%u\n", + dev->f_frequency, dev->f_bandwidth, f_vco, F_REF, div_n, k, + k_cw, div_out); buf[0] = div_n; buf[1] = (k_cw >> 0) & 0xff; @@ -174,7 +172,7 @@ static int e4000_set_params(struct dvb_frontend *fe) /* LNA filter (RF filter) */ for (i = 0; i < ARRAY_SIZE(e400_lna_filter_lut); i++) { - if (c->frequency <= e400_lna_filter_lut[i].freq) + if (dev->f_frequency <= e400_lna_filter_lut[i].freq) break; } if (i == ARRAY_SIZE(e400_lna_filter_lut)) { @@ -188,7 +186,7 @@ static int e4000_set_params(struct dvb_frontend *fe) /* IF filters */ for (i = 0; i < ARRAY_SIZE(e4000_if_filter_lut); i++) { - if (c->bandwidth_hz <= e4000_if_filter_lut[i].freq) + if (dev->f_bandwidth <= e4000_if_filter_lut[i].freq) break; } if (i == ARRAY_SIZE(e4000_if_filter_lut)) { @@ -205,7 +203,7 @@ static int e4000_set_params(struct dvb_frontend *fe) /* frequency band */ for (i = 0; i < ARRAY_SIZE(e4000_band_lut); i++) { - if (c->frequency <= e4000_band_lut[i].freq) + if (dev->f_frequency <= e4000_band_lut[i].freq) break; } if (i == ARRAY_SIZE(e4000_band_lut)) { @@ -269,19 +267,133 @@ err: return ret; } -static int e4000_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) +/* + * V4L2 API + */ +#if IS_ENABLED(CONFIG_VIDEO_V4L2) +static const struct v4l2_frequency_band bands[] = { + { + .type = V4L2_TUNER_RF, + .index = 0, + .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS, + .rangelow = 59000000, + .rangehigh = 1105000000, + }, + { + .type = V4L2_TUNER_RF, + .index = 1, + .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS, + .rangelow = 1249000000, + .rangehigh = 2208000000, + }, +}; + +static inline struct e4000_dev *e4000_subdev_to_dev(struct v4l2_subdev *sd) { - struct e4000_dev *dev = fe->tuner_priv; + return container_of(sd, struct e4000_dev, sd); +} + +static int e4000_s_power(struct v4l2_subdev *sd, int on) +{ + struct e4000_dev *dev = e4000_subdev_to_dev(sd); struct i2c_client *client = dev->client; + int ret; - dev_dbg(&client->dev, "\n"); + dev_dbg(&client->dev, "on=%d\n", on); - *frequency = 0; /* Zero-IF */ + if (on) + ret = e4000_init(dev); + else + ret = e4000_sleep(dev); + if (ret) + return ret; + + return e4000_set_params(dev); +} + +static const struct v4l2_subdev_core_ops e4000_subdev_core_ops = { + .s_power = e4000_s_power, +}; +static int e4000_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v) +{ + struct e4000_dev *dev = e4000_subdev_to_dev(sd); + struct i2c_client *client = dev->client; + + dev_dbg(&client->dev, "index=%d\n", v->index); + + strlcpy(v->name, "Elonics E4000", sizeof(v->name)); + v->type = V4L2_TUNER_RF; + v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS; + v->rangelow = bands[0].rangelow; + v->rangehigh = bands[1].rangehigh; return 0; } -#if IS_ENABLED(CONFIG_VIDEO_V4L2) +static int e4000_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *v) +{ + struct e4000_dev *dev = e4000_subdev_to_dev(sd); + struct i2c_client *client = dev->client; + + dev_dbg(&client->dev, "index=%d\n", v->index); + return 0; +} + +static int e4000_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) +{ + struct e4000_dev *dev = e4000_subdev_to_dev(sd); + struct i2c_client *client = dev->client; + + dev_dbg(&client->dev, "tuner=%d\n", f->tuner); + f->frequency = dev->f_frequency; + return 0; +} + +static int e4000_s_frequency(struct v4l2_subdev *sd, + const struct v4l2_frequency *f) +{ + struct e4000_dev *dev = e4000_subdev_to_dev(sd); + struct i2c_client *client = dev->client; + + dev_dbg(&client->dev, "tuner=%d type=%d frequency=%u\n", + f->tuner, f->type, f->frequency); + + dev->f_frequency = clamp_t(unsigned int, f->frequency, + bands[0].rangelow, bands[1].rangehigh); + return e4000_set_params(dev); +} + +static int e4000_enum_freq_bands(struct v4l2_subdev *sd, + struct v4l2_frequency_band *band) +{ + struct e4000_dev *dev = e4000_subdev_to_dev(sd); + struct i2c_client *client = dev->client; + + dev_dbg(&client->dev, "tuner=%d type=%d index=%d\n", + band->tuner, band->type, band->index); + + if (band->index >= ARRAY_SIZE(bands)) + return -EINVAL; + + band->capability = bands[band->index].capability; + band->rangelow = bands[band->index].rangelow; + band->rangehigh = bands[band->index].rangehigh; + return 0; +} + +static const struct v4l2_subdev_tuner_ops e4000_subdev_tuner_ops = { + .g_tuner = e4000_g_tuner, + .s_tuner = e4000_s_tuner, + .g_frequency = e4000_g_frequency, + .s_frequency = e4000_s_frequency, + .enum_freq_bands = e4000_enum_freq_bands, +}; + +static const struct v4l2_subdev_ops e4000_subdev_ops = { + .core = &e4000_subdev_core_ops, + .tuner = &e4000_subdev_tuner_ops, +}; + static int e4000_set_lna_gain(struct dvb_frontend *fe) { struct e4000_dev *dev = fe->tuner_priv; @@ -434,7 +546,6 @@ static int e4000_s_ctrl(struct v4l2_ctrl *ctrl) { struct e4000_dev *dev = container_of(ctrl->handler, struct e4000_dev, hdl); struct i2c_client *client = dev->client; - struct dtv_frontend_properties *c = &dev->fe->dtv_property_cache; int ret; if (!dev->active) @@ -443,8 +554,13 @@ static int e4000_s_ctrl(struct v4l2_ctrl *ctrl) switch (ctrl->id) { case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO: case V4L2_CID_RF_TUNER_BANDWIDTH: - c->bandwidth_hz = dev->bandwidth->val; - ret = e4000_set_params(dev->fe); + /* + * TODO: Auto logic does not work 100% correctly as tuner driver + * do not have information to calculate maximum suitable + * bandwidth. Calculating it is responsible of master driver. + */ + dev->f_bandwidth = dev->bandwidth->val; + ret = e4000_set_params(dev); break; case V4L2_CID_RF_TUNER_LNA_GAIN_AUTO: case V4L2_CID_RF_TUNER_LNA_GAIN: @@ -473,24 +589,49 @@ static const struct v4l2_ctrl_ops e4000_ctrl_ops = { }; #endif -static const struct dvb_tuner_ops e4000_tuner_ops = { +/* + * DVB API + */ +static int e4000_dvb_set_params(struct dvb_frontend *fe) +{ + struct e4000_dev *dev = fe->tuner_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + + dev->f_frequency = c->frequency; + dev->f_bandwidth = c->bandwidth_hz; + return e4000_set_params(dev); +} + +static int e4000_dvb_init(struct dvb_frontend *fe) +{ + return e4000_init(fe->tuner_priv); +} + +static int e4000_dvb_sleep(struct dvb_frontend *fe) +{ + return e4000_sleep(fe->tuner_priv); +} + +static int e4000_dvb_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + *frequency = 0; /* Zero-IF */ + return 0; +} + +static const struct dvb_tuner_ops e4000_dvb_tuner_ops = { .info = { .name = "Elonics E4000", .frequency_min = 174000000, .frequency_max = 862000000, }, - .init = e4000_init, - .sleep = e4000_sleep, - .set_params = e4000_set_params, + .init = e4000_dvb_init, + .sleep = e4000_dvb_sleep, + .set_params = e4000_dvb_set_params, - .get_if_frequency = e4000_get_if_frequency, + .get_if_frequency = e4000_dvb_get_if_frequency, }; -/* - * Use V4L2 subdev to carry V4L2 control handler, even we don't implement - * subdev itself, just to avoid reinventing the wheel. - */ static int e4000_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -569,10 +710,13 @@ static int e4000_probe(struct i2c_client *client, } dev->sd.ctrl_handler = &dev->hdl; + dev->f_frequency = bands[0].rangelow; + dev->f_bandwidth = dev->bandwidth->val; + v4l2_i2c_subdev_init(&dev->sd, client, &e4000_subdev_ops); #endif fe->tuner_priv = dev; - memcpy(&fe->ops.tuner_ops, &e4000_tuner_ops, - sizeof(struct dvb_tuner_ops)); + memcpy(&fe->ops.tuner_ops, &e4000_dvb_tuner_ops, + sizeof(fe->ops.tuner_ops)); v4l2_set_subdevdata(&dev->sd, client); i2c_set_clientdata(client, &dev->sd); diff --git a/drivers/media/tuners/e4000_priv.h b/drivers/media/tuners/e4000_priv.h index 8e991df9509e..d6d5d11bbfe0 100644 --- a/drivers/media/tuners/e4000_priv.h +++ b/drivers/media/tuners/e4000_priv.h @@ -34,6 +34,8 @@ struct e4000_dev { struct dvb_frontend *fe; struct v4l2_subdev sd; bool active; + unsigned int f_frequency; + unsigned int f_bandwidth; /* Controls */ struct v4l2_ctrl_handler hdl; -- cgit v1.2.3-59-g8ed1b From 13b019bbd170d788b1461c2e00b4578a07541dc5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 20 May 2015 13:52:48 -0300 Subject: [media] e4000: Fix rangehigh value As reported by smatch: drivers/media/tuners/e4000.c:287:32: warning: constant 2208000000 is so big it is long long drivers/media/tuners/e4000.c:287:32: warning: decimal constant 2208000000 is between LONG_MAX and ULONG_MAX. For C99 that means long long, C90 compilers are very likely to produce unsigned long (and a warning) here drivers/media/tuners/e4000.c:287:3: warning: this decimal constant is unsigned only in ISO C90 .rangehigh = 2208000000, ^ Cc: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/e4000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/e4000.c b/drivers/media/tuners/e4000.c index 3b49a4550bd3..fdf07ce4177a 100644 --- a/drivers/media/tuners/e4000.c +++ b/drivers/media/tuners/e4000.c @@ -284,7 +284,7 @@ static const struct v4l2_frequency_band bands[] = { .index = 1, .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS, .rangelow = 1249000000, - .rangehigh = 2208000000, + .rangehigh = 2208000000L, }, }; -- cgit v1.2.3-59-g8ed1b From 2a80f296422a01178d0a993479369e94f5830127 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 14 Apr 2015 15:12:54 -0300 Subject: [media] dvb-core: fix 32-bit overflow during bandwidth calculation Frontend bandwidth calculation overflows on very high DVB-S/S2 symbol rates. Use mult_frac() macro in order to keep calculation correct. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_frontend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 882ca417f328..a894d4c99ee8 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -2216,7 +2216,7 @@ static int dtv_set_frontend(struct dvb_frontend *fe) break; } if (rolloff) - c->bandwidth_hz = (c->symbol_rate * rolloff) / 100; + c->bandwidth_hz = mult_frac(c->symbol_rate, rolloff, 100); /* force auto frequency inversion if requested */ if (dvb_force_auto_inversion) -- cgit v1.2.3-59-g8ed1b From bf8de2d38a4ba82a69db221915375199c9e5d761 Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Wed, 20 May 2015 11:57:49 -0300 Subject: [media] cx24120: Assume ucb registers is a counter The ucblocks register is probably a counter and not a rate; assume it is so and change the calculations as required. Signed-off-by: Jemma Denson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index a14d0f1cc71e..10a948ef8440 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -154,7 +154,7 @@ struct cx24120_state { u32 bitrate; u32 berw_usecs; u32 ber_prev; - u32 per_prev; + u32 ucb_offset; unsigned long ber_jiffies_stats; unsigned long per_jiffies_stats; }; @@ -698,8 +698,12 @@ static void cx24120_get_stats(struct cx24120_state *state) ucb |= cx24120_readreg(state, CX24120_REG_UCB_L); dev_dbg(&state->i2c->dev, "ucblocks = %d\n", ucb); + /* handle reset */ + if (ucb < state->ucb_offset) + state->ucb_offset = c->block_error.stat[0].uvalue; + c->block_error.stat[0].scale = FE_SCALE_COUNTER; - c->block_error.stat[0].uvalue += ucb; + c->block_error.stat[0].uvalue = ucb + state->ucb_offset; c->block_count.stat[0].scale = FE_SCALE_COUNTER; c->block_count.stat[0].uvalue += state->bitrate / 8 / 208; @@ -1541,8 +1545,7 @@ static int cx24120_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) return 0; } - *ucblocks = c->block_error.stat[0].uvalue - state->per_prev; - state->per_prev = c->block_error.stat[0].uvalue; + *ucblocks = c->block_error.stat[0].uvalue - state->ucb_offset; return 0; } -- cgit v1.2.3-59-g8ed1b From 86bad00a2fd5327925417eb05a2b3d1819c42a70 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 21 May 2015 06:19:28 -0300 Subject: [media] cobalt: fix irqs used for the adv7511 transmitter The interrupt bit assignments use for the adv7511 were off by one. This means that the current scheme (bit << (4 * stream_index)) can no longer be used. Fix this by precalculating and storing the correct masks in the cobalt_stream struct. This wasn't noticed before because the adv7511 interrupts are very rare. But for CEC support these interrupts are essential, so this made me realize that it wasn't working correctly. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cobalt/cobalt-driver.c | 14 ++++++++++++-- drivers/media/pci/cobalt/cobalt-driver.h | 8 +++++--- drivers/media/pci/cobalt/cobalt-irq.c | 7 +++---- 3 files changed, 20 insertions(+), 9 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/cobalt/cobalt-driver.c b/drivers/media/pci/cobalt/cobalt-driver.c index 0f2549ab4c2b..0534d7183809 100644 --- a/drivers/media/pci/cobalt/cobalt-driver.c +++ b/drivers/media/pci/cobalt/cobalt-driver.c @@ -451,20 +451,30 @@ static void cobalt_stream_struct_init(struct cobalt *cobalt) if (i <= COBALT_HSMA_IN_NODE) { s->dma_channel = i + cobalt->first_fifo_channel; s->video_channel = i; + s->dma_fifo_mask = + COBALT_SYSSTAT_VI0_LOST_DATA_MSK << (4 * i); + s->adv_irq_mask = + COBALT_SYSSTAT_VI0_INT1_MSK << (4 * i); } else if (i >= COBALT_AUDIO_IN_STREAM && i <= COBALT_AUDIO_IN_STREAM + 4) { - s->dma_channel = 6 + i - COBALT_AUDIO_IN_STREAM; + unsigned idx = i - COBALT_AUDIO_IN_STREAM; + + s->dma_channel = 6 + idx; s->is_audio = true; - s->video_channel = i - COBALT_AUDIO_IN_STREAM; + s->video_channel = idx; + s->dma_fifo_mask = COBALT_SYSSTAT_AUD_IN_LOST_DATA_MSK; } else if (i == COBALT_HSMA_OUT_NODE) { s->dma_channel = 11; s->is_output = true; s->video_channel = 5; + s->dma_fifo_mask = COBALT_SYSSTAT_VOHSMA_LOST_DATA_MSK; + s->adv_irq_mask = COBALT_SYSSTAT_VOHSMA_INT1_MSK; } else if (i == COBALT_AUDIO_OUT_STREAM) { s->dma_channel = 12; s->is_audio = true; s->is_output = true; s->video_channel = 5; + s->dma_fifo_mask = COBALT_SYSSTAT_AUD_OUT_LOST_DATA_MSK; } else { /* FIXME: Memory DMA for debug purpose */ s->dma_channel = i - COBALT_NUM_NODES; diff --git a/drivers/media/pci/cobalt/cobalt-driver.h b/drivers/media/pci/cobalt/cobalt-driver.h index 082bf8255759..bb062ff950de 100644 --- a/drivers/media/pci/cobalt/cobalt-driver.h +++ b/drivers/media/pci/cobalt/cobalt-driver.h @@ -96,9 +96,9 @@ #define COBALT_SYSSTAT_VIHSMA_INT1_MSK (1 << 21) #define COBALT_SYSSTAT_VIHSMA_INT2_MSK (1 << 22) #define COBALT_SYSSTAT_VIHSMA_LOST_DATA_MSK (1 << 23) -#define COBALT_SYSSTAT_VOHSMA_INT1_MSK (1 << 25) -#define COBALT_SYSSTAT_VOHSMA_PLL_LOCKED_MSK (1 << 26) -#define COBALT_SYSSTAT_VOHSMA_LOST_DATA_MSK (1 << 27) +#define COBALT_SYSSTAT_VOHSMA_INT1_MSK (1 << 24) +#define COBALT_SYSSTAT_VOHSMA_PLL_LOCKED_MSK (1 << 25) +#define COBALT_SYSSTAT_VOHSMA_LOST_DATA_MSK (1 << 26) #define COBALT_SYSSTAT_AUD_PLL_LOCKED_MSK (1 << 28) #define COBALT_SYSSTAT_AUD_IN_LOST_DATA_MSK (1 << 29) #define COBALT_SYSSTAT_AUD_OUT_LOST_DATA_MSK (1 << 30) @@ -236,6 +236,8 @@ struct cobalt_stream { u8 dma_channel; int video_channel; + unsigned dma_fifo_mask; + unsigned adv_irq_mask; struct sg_dma_desc_info dma_desc_info[NR_BUFS]; unsigned long flags; bool unstable_frame; diff --git a/drivers/media/pci/cobalt/cobalt-irq.c b/drivers/media/pci/cobalt/cobalt-irq.c index e18f49e6f0e3..a133dfcb2ead 100644 --- a/drivers/media/pci/cobalt/cobalt-irq.c +++ b/drivers/media/pci/cobalt/cobalt-irq.c @@ -153,8 +153,7 @@ irqreturn_t cobalt_irq_handler(int irq, void *dev_id) for (i = 0; i < COBALT_NUM_STREAMS; i++) { struct cobalt_stream *s = &cobalt->streams[i]; - unsigned dma_fifo_mask = - COBALT_SYSSTAT_VI0_LOST_DATA_MSK << (4 * s->video_channel); + unsigned dma_fifo_mask = s->dma_fifo_mask; if (dma_interrupt & (1 << s->dma_channel)) { cobalt->irq_dma[i]++; @@ -169,7 +168,7 @@ irqreturn_t cobalt_irq_handler(int irq, void *dev_id) } if (s->is_audio) continue; - if (edge & (0x20 << (4 * s->video_channel))) + if (edge & s->adv_irq_mask) set_bit(COBALT_STREAM_FL_ADV_IRQ, &s->flags); if ((edge & mask & dma_fifo_mask) && vb2_is_streaming(&s->q)) { cobalt_info("full rx FIFO %d\n", i); @@ -219,7 +218,7 @@ void cobalt_irq_work_handler(struct work_struct *work) interrupt_service_routine, 0, NULL); mask = cobalt_read_bar1(cobalt, COBALT_SYS_STAT_MASK); cobalt_write_bar1(cobalt, COBALT_SYS_STAT_MASK, - mask | (0x20 << (4 * s->video_channel))); + mask | s->adv_irq_mask); } } } -- cgit v1.2.3-59-g8ed1b From 99cabb187100e5bae12ec835431a2868e5d9afc9 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 21 May 2015 09:37:40 -0300 Subject: [media] cobalt: fix 64-bit division link error [linuxtv-media:master 1023/1029] ERROR: "__aeabi_uldivmod" [drivers/media/pci/cobalt/cobalt.ko] undefined! Signed-off-by: Hans Verkuil Reported-by: kbuild test robot Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cobalt/cobalt-v4l2.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/cobalt/cobalt-v4l2.c b/drivers/media/pci/cobalt/cobalt-v4l2.c index bf80f11d94d8..6e8d25b18b4e 100644 --- a/drivers/media/pci/cobalt/cobalt-v4l2.c +++ b/drivers/media/pci/cobalt/cobalt-v4l2.c @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -314,8 +315,8 @@ static int cobalt_start_streaming(struct vb2_queue *q, unsigned int count) cvi->frame_height = bt->height; tot_size = V4L2_DV_BT_FRAME_WIDTH(bt) * V4L2_DV_BT_FRAME_HEIGHT(bt); vmr->hsync_timeout_val = - ((u64)V4L2_DV_BT_FRAME_WIDTH(bt) * COBALT_CLK * 4) / - bt->pixelclock; + div_u64((u64)V4L2_DV_BT_FRAME_WIDTH(bt) * COBALT_CLK * 4, + bt->pixelclock); vmr->control = M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK; clkloss->ref_clk_cnt_val = fw->clk_freq / 1000000; /* The lower bound for the clock frequency is 0.5% lower as is @@ -324,7 +325,7 @@ static int cobalt_start_streaming(struct vb2_queue *q, unsigned int count) (((u64)bt->pixelclock * 995) / 1000) / 1000000; /* will be enabled after the first frame has been received */ fw->active_length = bt->width * bt->height; - fw->total_length = ((u64)fw->clk_freq * tot_size) / bt->pixelclock; + fw->total_length = div_u64((u64)fw->clk_freq * tot_size, bt->pixelclock); vmr->irq_triggers = M00233_IRQ_TRIGGERS_BITMAP_VACTIVE_AREA_MSK | M00233_IRQ_TRIGGERS_BITMAP_HACTIVE_AREA_MSK; cvi->control = 0; -- cgit v1.2.3-59-g8ed1b From 40c942a1746ffcb632933a2195fa80e6f4c2d6f0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 22 May 2015 04:37:27 -0300 Subject: [media] cobalt: fix compiler warnings on 32 bit OSes Fixes these warnings: drivers/media/pci/cobalt/cobalt-omnitek.c: In function 'omni_sg_dma_start': drivers/media/pci/cobalt/cobalt-omnitek.c:112:28: warning: right shift count >= width of type [-Wshift-count-overflow] iowrite32((u32)(desc->bus >> 32), DESCRIPTOR(s->dma_channel) + 4); ^ drivers/media/pci/cobalt/cobalt-omnitek.c: In function 'descriptor_list_create': drivers/media/pci/cobalt/cobalt-omnitek.c:222:28: warning: right shift count >= width of type [-Wshift-count-overflow] d->next_h = (u32)(next >> 32); ^ drivers/media/pci/cobalt/cobalt-omnitek.c:268:32: warning: right shift count >= width of type [-Wshift-count-overflow] d->next_h = (u32)(desc->bus >> 32); ^ drivers/media/pci/cobalt/cobalt-omnitek.c:275:27: warning: right shift count >= width of type [-Wshift-count-overflow] d->next_h = (u32)(next >> 32); ^ drivers/media/pci/cobalt/cobalt-omnitek.c: In function 'descriptor_list_chain': drivers/media/pci/cobalt/cobalt-omnitek.c:293:31: warning: right shift count >= width of type [-Wshift-count-overflow] d->next_h = (u32)(next->bus >> 32); ^ drivers/media/pci/cobalt/cobalt-omnitek.c: In function 'descriptor_list_loopback': drivers/media/pci/cobalt/cobalt-omnitek.c:332:30: warning: right shift count >= width of type [-Wshift-count-overflow] d->next_h = (u32)(desc->bus >> 32); ^ Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cobalt/cobalt-omnitek.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/cobalt/cobalt-omnitek.c b/drivers/media/pci/cobalt/cobalt-omnitek.c index 560445846235..a28a8482c1d4 100644 --- a/drivers/media/pci/cobalt/cobalt-omnitek.c +++ b/drivers/media/pci/cobalt/cobalt-omnitek.c @@ -109,7 +109,7 @@ void omni_sg_dma_start(struct cobalt_stream *s, struct sg_dma_desc_info *desc) { struct cobalt *cobalt = s->cobalt; - iowrite32((u32)(desc->bus >> 32), DESCRIPTOR(s->dma_channel) + 4); + iowrite32((u32)((u64)desc->bus >> 32), DESCRIPTOR(s->dma_channel) + 4); iowrite32((u32)desc->bus & NEXT_ADRS_MSK, DESCRIPTOR(s->dma_channel)); iowrite32(ENABLE | SCATTER_GATHER_MODE | START, CS_REG(s->dma_channel)); } @@ -219,7 +219,7 @@ int descriptor_list_create(struct cobalt *cobalt, offset += d->bytes; addr += d->bytes; next += sizeof(struct sg_dma_descriptor); - d->next_h = (u32)(next >> 32); + d->next_h = (u32)((u64)next >> 32); d->next_l = (u32)next | (to_pci ? WRITE_TO_PCI : 0); bytes -= d->bytes; @@ -265,14 +265,14 @@ int descriptor_list_create(struct cobalt *cobalt, next += sizeof(struct sg_dma_descriptor); if (size == 0) { /* Loopback to the first descriptor */ - d->next_h = (u32)(desc->bus >> 32); + d->next_h = (u32)((u64)desc->bus >> 32); d->next_l = (u32)desc->bus | (to_pci ? WRITE_TO_PCI : 0) | INTERRUPT_ENABLE; if (!to_pci) d->local = 0x22222222; desc->last_desc_virt = d; } else { - d->next_h = (u32)(next >> 32); + d->next_h = (u32)((u64)next >> 32); d->next_l = (u32)next | (to_pci ? WRITE_TO_PCI : 0); } d++; @@ -290,7 +290,7 @@ void descriptor_list_chain(struct sg_dma_desc_info *this, d->next_h = 0; d->next_l = direction | INTERRUPT_ENABLE | END_OF_CHAIN; } else { - d->next_h = (u32)(next->bus >> 32); + d->next_h = (u32)((u64)next->bus >> 32); d->next_l = (u32)next->bus | direction | INTERRUPT_ENABLE; } } @@ -329,7 +329,7 @@ void descriptor_list_loopback(struct sg_dma_desc_info *desc) { struct sg_dma_descriptor *d = desc->last_desc_virt; - d->next_h = (u32)(desc->bus >> 32); + d->next_h = (u32)((u64)desc->bus >> 32); d->next_l = (u32)desc->bus | (d->next_l & DESCRIPTOR_FLAG_MSK); } -- cgit v1.2.3-59-g8ed1b From 1ba90492289003e7939574eca8b1ff6cce2d5520 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 22 May 2015 04:39:54 -0300 Subject: [media] e4000: fix compiler warning drivers/media/tuners/e4000.c:287:3: warning: this decimal constant is unsigned only in ISO C90 .rangehigh = 2208000000L, ^ Signed-off-by: Hans Verkuil Cc: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/e4000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/e4000.c b/drivers/media/tuners/e4000.c index fdf07ce4177a..03538f88f488 100644 --- a/drivers/media/tuners/e4000.c +++ b/drivers/media/tuners/e4000.c @@ -284,7 +284,7 @@ static const struct v4l2_frequency_band bands[] = { .index = 1, .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS, .rangelow = 1249000000, - .rangehigh = 2208000000L, + .rangehigh = 2208000000UL, }, }; -- cgit v1.2.3-59-g8ed1b From 4a561c4b70b908c0b5cbcc8bc95bc796139e63ad Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 22 May 2015 05:31:46 -0300 Subject: [media] cobalt: fix sparse warnings drivers/media/pci/cobalt/cobalt-flash.c:39:36: warning: incorrect type in initializer (different address spaces) drivers/media/pci/cobalt/cobalt-flash.c:54:36: warning: incorrect type in initializer (different address spaces) drivers/media/pci/cobalt/cobalt-flash.c:63:36: warning: incorrect type in initializer (different address spaces) drivers/media/pci/cobalt/cobalt-flash.c:82:36: warning: incorrect type in initializer (different address spaces) drivers/media/pci/cobalt/cobalt-flash.c:107:19: warning: incorrect type in assignment (different address spaces) Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cobalt/cobalt-cpld.c | 4 ++-- drivers/media/pci/cobalt/cobalt-driver.c | 4 ++-- drivers/media/pci/cobalt/cobalt-driver.h | 12 ++++++------ drivers/media/pci/cobalt/cobalt-flash.c | 16 ++++++---------- 4 files changed, 16 insertions(+), 20 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/cobalt/cobalt-cpld.c b/drivers/media/pci/cobalt/cobalt-cpld.c index 77ed9e57d306..05df4584b2e2 100644 --- a/drivers/media/pci/cobalt/cobalt-cpld.c +++ b/drivers/media/pci/cobalt/cobalt-cpld.c @@ -26,12 +26,12 @@ static u16 cpld_read(struct cobalt *cobalt, u32 offset) { - return cobalt_bus_read32(cobalt, ADRS(offset)); + return cobalt_bus_read32(cobalt->bar1, ADRS(offset)); } static void cpld_write(struct cobalt *cobalt, u32 offset, u16 val) { - return cobalt_bus_write32(cobalt, ADRS(offset), val); + return cobalt_bus_write32(cobalt->bar1, ADRS(offset), val); } static void cpld_info_ver3(struct cobalt *cobalt) diff --git a/drivers/media/pci/cobalt/cobalt-driver.c b/drivers/media/pci/cobalt/cobalt-driver.c index 0534d7183809..c2974e699ecf 100644 --- a/drivers/media/pci/cobalt/cobalt-driver.c +++ b/drivers/media/pci/cobalt/cobalt-driver.c @@ -296,11 +296,11 @@ static void cobalt_pci_iounmap(struct cobalt *cobalt, struct pci_dev *pci_dev) { if (cobalt->bar0) { pci_iounmap(pci_dev, cobalt->bar0); - cobalt->bar0 = 0; + cobalt->bar0 = NULL; } if (cobalt->bar1) { pci_iounmap(pci_dev, cobalt->bar1); - cobalt->bar1 = 0; + cobalt->bar1 = NULL; } } diff --git a/drivers/media/pci/cobalt/cobalt-driver.h b/drivers/media/pci/cobalt/cobalt-driver.h index bb062ff950de..3d9a9ffb65ec 100644 --- a/drivers/media/pci/cobalt/cobalt-driver.h +++ b/drivers/media/pci/cobalt/cobalt-driver.h @@ -342,17 +342,17 @@ static inline u32 cobalt_g_sysstat(struct cobalt *cobalt) return cobalt_read_bar1(cobalt, COBALT_SYS_STAT_BASE); } -#define ADRS_REG (cobalt->bar1 + COBALT_BUS_BAR1_BASE + 0) -#define LOWER_DATA (cobalt->bar1 + COBALT_BUS_BAR1_BASE + 4) -#define UPPER_DATA (cobalt->bar1 + COBALT_BUS_BAR1_BASE + 6) +#define ADRS_REG (bar1 + COBALT_BUS_BAR1_BASE + 0) +#define LOWER_DATA (bar1 + COBALT_BUS_BAR1_BASE + 4) +#define UPPER_DATA (bar1 + COBALT_BUS_BAR1_BASE + 6) -static inline u32 cobalt_bus_read32(struct cobalt *cobalt, u32 bus_adrs) +static inline u32 cobalt_bus_read32(void __iomem *bar1, u32 bus_adrs) { iowrite32(bus_adrs, ADRS_REG); return ioread32(LOWER_DATA); } -static inline void cobalt_bus_write16(struct cobalt *cobalt, +static inline void cobalt_bus_write16(void __iomem *bar1, u32 bus_adrs, u16 data) { iowrite32(bus_adrs, ADRS_REG); @@ -362,7 +362,7 @@ static inline void cobalt_bus_write16(struct cobalt *cobalt, iowrite16(data, LOWER_DATA); } -static inline void cobalt_bus_write32(struct cobalt *cobalt, +static inline void cobalt_bus_write32(void __iomem *bar1, u32 bus_adrs, u16 data) { iowrite32(bus_adrs, ADRS_REG); diff --git a/drivers/media/pci/cobalt/cobalt-flash.c b/drivers/media/pci/cobalt/cobalt-flash.c index 129f48ffe8a9..89fd667962f4 100644 --- a/drivers/media/pci/cobalt/cobalt-flash.c +++ b/drivers/media/pci/cobalt/cobalt-flash.c @@ -36,10 +36,9 @@ static struct map_info cobalt_flash_map = { static map_word flash_read16(struct map_info *map, unsigned long offset) { - struct cobalt *cobalt = map->virt; map_word r; - r.x[0] = cobalt_bus_read32(cobalt, ADRS(offset)); + r.x[0] = cobalt_bus_read32(map->virt, ADRS(offset)); if (offset & 0x2) r.x[0] >>= 16; else @@ -51,22 +50,20 @@ static map_word flash_read16(struct map_info *map, unsigned long offset) static void flash_write16(struct map_info *map, const map_word datum, unsigned long offset) { - struct cobalt *cobalt = map->virt; u16 data = (u16)datum.x[0]; - cobalt_bus_write16(cobalt, ADRS(offset), data); + cobalt_bus_write16(map->virt, ADRS(offset), data); } static void flash_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) { - struct cobalt *cobalt = map->virt; u32 src = from; u8 *dest = to; u32 data; while (len) { - data = cobalt_bus_read32(cobalt, ADRS(src)); + data = cobalt_bus_read32(map->virt, ADRS(src)); do { *dest = data >> (8 * (src & 3)); src++; @@ -79,11 +76,10 @@ static void flash_copy_from(struct map_info *map, void *to, static void flash_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) { - struct cobalt *cobalt = map->virt; const u8 *src = from; u32 dest = to; - cobalt_info("%s: offset 0x%x: length %zu\n", __func__, dest, len); + pr_info("%s: offset 0x%x: length %zu\n", __func__, dest, len); while (len) { u16 data = 0xffff; @@ -94,7 +90,7 @@ static void flash_copy_to(struct map_info *map, unsigned long to, len--; } while (len && (dest % 2)); - cobalt_bus_write16(cobalt, ADRS(dest - 2), data); + cobalt_bus_write16(map->virt, ADRS(dest - 2), data); } } @@ -104,7 +100,7 @@ int cobalt_flash_probe(struct cobalt *cobalt) struct mtd_info *mtd; BUG_ON(!map_bankwidth_supported(map->bankwidth)); - map->virt = cobalt; + map->virt = cobalt->bar1; map->read = flash_read16; map->write = flash_write16; map->copy_from = flash_copy_from; -- cgit v1.2.3-59-g8ed1b From dd2567c0f9629bddd3cdb6cee3b3b66f963464e5 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 22 May 2015 05:30:02 -0300 Subject: [media] cobalt: fix sparse warnings drivers/media/pci/cobalt/cobalt-flash.c:101:5: warning: symbol 'cobalt_flash_probe' was not declared. Should it be static? drivers/media/pci/cobalt/cobalt-flash.c:126:6: warning: symbol 'cobalt_flash_remove' was not declared. Should it be static? drivers/media/pci/cobalt/cobalt-cpld.c:101:6: warning: symbol 'cobalt_cpld_status' was not declared. Should it be static? drivers/media/pci/cobalt/cobalt-cpld.c:240:6: warning: symbol 'cobalt_cpld_set_freq' was not declared. Should it be static? Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cobalt/cobalt-cpld.c | 2 +- drivers/media/pci/cobalt/cobalt-flash.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/cobalt/cobalt-cpld.c b/drivers/media/pci/cobalt/cobalt-cpld.c index 05df4584b2e2..5a28d9b28dc9 100644 --- a/drivers/media/pci/cobalt/cobalt-cpld.c +++ b/drivers/media/pci/cobalt/cobalt-cpld.c @@ -20,7 +20,7 @@ #include -#include "cobalt-driver.h" +#include "cobalt-cpld.h" #define ADRS(offset) (COBALT_BUS_CPLD_BASE + offset) diff --git a/drivers/media/pci/cobalt/cobalt-flash.c b/drivers/media/pci/cobalt/cobalt-flash.c index 89fd667962f4..04dcaf9198d2 100644 --- a/drivers/media/pci/cobalt/cobalt-flash.c +++ b/drivers/media/pci/cobalt/cobalt-flash.c @@ -23,7 +23,7 @@ #include #include -#include "cobalt-driver.h" +#include "cobalt-flash.h" #define ADRS(offset) (COBALT_BUS_FLASH_BASE + offset) -- cgit v1.2.3-59-g8ed1b From c0ce6220a5bf7ba892cd1ef9c9d4b622cf6f0894 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 22 May 2015 05:44:23 -0300 Subject: [media] cobalt: fix sparse warnings drivers/media/pci/cobalt/cobalt-irq.c:62:33: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-irq.c:64:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-irq.c:65:23: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-irq.c:72:21: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-irq.c:73:25: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-irq.c:74:25: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-irq.c:82:33: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-irq.c:83:33: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-irq.c:91:25: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-irq.c:94:23: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-irq.c:103:25: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-irq.c:107:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-irq.c:109:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-irq.c:116:13: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-irq.c:119:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-irq.c:120:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-irq.c:122:17: warning: dereference of noderef expression Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cobalt/cobalt-irq.c | 51 +++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 23 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/cobalt/cobalt-irq.c b/drivers/media/pci/cobalt/cobalt-irq.c index a133dfcb2ead..dd4bff9cf339 100644 --- a/drivers/media/pci/cobalt/cobalt-irq.c +++ b/drivers/media/pci/cobalt/cobalt-irq.c @@ -28,13 +28,13 @@ static void cobalt_dma_stream_queue_handler(struct cobalt_stream *s) { struct cobalt *cobalt = s->cobalt; int rx = s->video_channel; - volatile struct m00473_freewheel_regmap __iomem *fw = + struct m00473_freewheel_regmap __iomem *fw = COBALT_CVI_FREEWHEEL(s->cobalt, rx); - volatile struct m00233_video_measure_regmap __iomem *vmr = + struct m00233_video_measure_regmap __iomem *vmr = COBALT_CVI_VMR(s->cobalt, rx); - volatile struct m00389_cvi_regmap __iomem *cvi = + struct m00389_cvi_regmap __iomem *cvi = COBALT_CVI(s->cobalt, rx); - volatile struct m00479_clk_loss_detector_regmap __iomem *clkloss = + struct m00479_clk_loss_detector_regmap __iomem *clkloss = COBALT_CVI_CLK_LOSS(s->cobalt, rx); struct cobalt_buffer *cb; bool skip = false; @@ -59,19 +59,21 @@ static void cobalt_dma_stream_queue_handler(struct cobalt_stream *s) goto done; if (s->unstable_frame) { - uint32_t stat = vmr->irq_status; + uint32_t stat = ioread32(&vmr->irq_status); - vmr->irq_status = stat; - if (!(vmr->status & M00233_STATUS_BITMAP_INIT_DONE_MSK)) { + iowrite32(stat, &vmr->irq_status); + if (!(ioread32(&vmr->status) & + M00233_STATUS_BITMAP_INIT_DONE_MSK)) { cobalt_dbg(1, "!init_done\n"); if (s->enable_freewheel) goto restart_fw; goto done; } - if (clkloss->status & M00479_STATUS_BITMAP_CLOCK_MISSING_MSK) { - clkloss->ctrl = 0; - clkloss->ctrl = M00479_CTRL_BITMAP_ENABLE_MSK; + if (ioread32(&clkloss->status) & + M00479_STATUS_BITMAP_CLOCK_MISSING_MSK) { + iowrite32(0, &clkloss->ctrl); + iowrite32(M00479_CTRL_BITMAP_ENABLE_MSK, &clkloss->ctrl); cobalt_dbg(1, "no clock\n"); if (s->enable_freewheel) goto restart_fw; @@ -79,8 +81,8 @@ static void cobalt_dma_stream_queue_handler(struct cobalt_stream *s) } if ((stat & (M00233_IRQ_STATUS_BITMAP_VACTIVE_AREA_MSK | M00233_IRQ_STATUS_BITMAP_HACTIVE_AREA_MSK)) || - vmr->vactive_area != s->timings.bt.height || - vmr->hactive_area != s->timings.bt.width) { + ioread32(&vmr->vactive_area) != s->timings.bt.height || + ioread32(&vmr->hactive_area) != s->timings.bt.width) { cobalt_dbg(1, "unstable\n"); if (s->enable_freewheel) goto restart_fw; @@ -88,10 +90,10 @@ static void cobalt_dma_stream_queue_handler(struct cobalt_stream *s) } if (!s->enable_cvi) { s->enable_cvi = true; - cvi->control = M00389_CONTROL_BITMAP_ENABLE_MSK; + iowrite32(M00389_CONTROL_BITMAP_ENABLE_MSK, &cvi->control); goto done; } - if (!(cvi->status & M00389_STATUS_BITMAP_LOCK_MSK)) { + if (!(ioread32(&cvi->status) & M00389_STATUS_BITMAP_LOCK_MSK)) { cobalt_dbg(1, "cvi no lock\n"); if (s->enable_freewheel) goto restart_fw; @@ -100,26 +102,29 @@ static void cobalt_dma_stream_queue_handler(struct cobalt_stream *s) if (!s->enable_freewheel) { cobalt_dbg(1, "stable\n"); s->enable_freewheel = true; - fw->ctrl = 0; + iowrite32(0, &fw->ctrl); goto done; } cobalt_dbg(1, "enabled fw\n"); - vmr->control = M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK | - M00233_CONTROL_BITMAP_ENABLE_INTERRUPT_MSK; - fw->ctrl = M00473_CTRL_BITMAP_ENABLE_MSK; + iowrite32(M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK | + M00233_CONTROL_BITMAP_ENABLE_INTERRUPT_MSK, + &vmr->control); + iowrite32(M00473_CTRL_BITMAP_ENABLE_MSK, &fw->ctrl); s->enable_freewheel = false; s->unstable_frame = false; s->skip_first_frames = 2; skip = true; goto done; } - if (fw->status & M00473_STATUS_BITMAP_FREEWHEEL_MODE_MSK) { + if (ioread32(&fw->status) & M00473_STATUS_BITMAP_FREEWHEEL_MODE_MSK) { restart_fw: cobalt_dbg(1, "lost lock\n"); - vmr->control = M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK; - fw->ctrl = M00473_CTRL_BITMAP_ENABLE_MSK | - M00473_CTRL_BITMAP_FORCE_FREEWHEEL_MODE_MSK; - cvi->control = 0; + iowrite32(M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK, + &vmr->control); + iowrite32(M00473_CTRL_BITMAP_ENABLE_MSK | + M00473_CTRL_BITMAP_FORCE_FREEWHEEL_MODE_MSK, + &fw->ctrl); + iowrite32(0, &cvi->control); s->unstable_frame = true; s->enable_freewheel = false; s->enable_cvi = false; -- cgit v1.2.3-59-g8ed1b From 0664fb61a42de62bfac2bbaece693f7ae712a942 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 22 May 2015 05:51:39 -0300 Subject: [media] cobalt: fix sparse warnings drivers/media/pci/cobalt/cobalt-i2c.c:130:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-i2c.c:147:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-i2c.c:151:26: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-i2c.c:156:34: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-i2c.c:206:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-i2c.c:210:26: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-i2c.c:215:34: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-i2c.c:225:27: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-i2c.c:335:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-i2c.c:336:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-i2c.c:337:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-i2c.c:348:34: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-i2c.c:352:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-i2c.c:353:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-i2c.c:356:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-i2c.c:357:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-i2c.c:359:17: warning: dereference of noderef expression Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cobalt/cobalt-driver.h | 2 +- drivers/media/pci/cobalt/cobalt-i2c.c | 56 ++++++++++++++++---------------- 2 files changed, 29 insertions(+), 29 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/cobalt/cobalt-driver.h b/drivers/media/pci/cobalt/cobalt-driver.h index 3d9a9ffb65ec..f63ce193a65d 100644 --- a/drivers/media/pci/cobalt/cobalt-driver.h +++ b/drivers/media/pci/cobalt/cobalt-driver.h @@ -177,7 +177,7 @@ struct cobalt_i2c_regs; /* Per I2C bus private algo callback data */ struct cobalt_i2c_data { struct cobalt *cobalt; - volatile struct cobalt_i2c_regs __iomem *regs; + struct cobalt_i2c_regs __iomem *regs; }; struct pci_consistent_buffer { diff --git a/drivers/media/pci/cobalt/cobalt-i2c.c b/drivers/media/pci/cobalt/cobalt-i2c.c index 57b330f4f94b..ad16b89b8d0c 100644 --- a/drivers/media/pci/cobalt/cobalt-i2c.c +++ b/drivers/media/pci/cobalt/cobalt-i2c.c @@ -90,25 +90,25 @@ struct cobalt_i2c_regs { #define I2C_FREQUENCY 400000 #define ALT_CPU_FREQ 83333333 -static volatile struct cobalt_i2c_regs __iomem * +static struct cobalt_i2c_regs __iomem * cobalt_i2c_regs(struct cobalt *cobalt, unsigned idx) { switch (idx) { case 0: default: - return (volatile struct cobalt_i2c_regs __iomem *) + return (struct cobalt_i2c_regs __iomem *) (cobalt->bar1 + COBALT_I2C_0_BASE); case 1: - return (volatile struct cobalt_i2c_regs __iomem *) + return (struct cobalt_i2c_regs __iomem *) (cobalt->bar1 + COBALT_I2C_1_BASE); case 2: - return (volatile struct cobalt_i2c_regs __iomem *) + return (struct cobalt_i2c_regs __iomem *) (cobalt->bar1 + COBALT_I2C_2_BASE); case 3: - return (volatile struct cobalt_i2c_regs __iomem *) + return (struct cobalt_i2c_regs __iomem *) (cobalt->bar1 + COBALT_I2C_3_BASE); case 4: - return (volatile struct cobalt_i2c_regs __iomem *) + return (struct cobalt_i2c_regs __iomem *) (cobalt->bar1 + COBALT_I2C_HSMA_BASE); } } @@ -116,7 +116,7 @@ cobalt_i2c_regs(struct cobalt *cobalt, unsigned idx) /* Do low-level i2c byte transfer. * Returns -1 in case of an error or 0 otherwise. */ -static int cobalt_tx_bytes(volatile struct cobalt_i2c_regs __iomem *regs, +static int cobalt_tx_bytes(struct cobalt_i2c_regs __iomem *regs, struct i2c_adapter *adap, bool start, bool stop, u8 *data, u16 len) { @@ -127,7 +127,7 @@ static int cobalt_tx_bytes(volatile struct cobalt_i2c_regs __iomem *regs, for (i = 0; i < len; i++) { /* Setup data */ - regs->txr_rxr = data[i]; + iowrite8(data[i], ®s->txr_rxr); /* Setup command */ if (i == 0 && start != 0) { @@ -144,16 +144,16 @@ static int cobalt_tx_bytes(volatile struct cobalt_i2c_regs __iomem *regs, } /* Execute command */ - regs->cr_sr = cmd; + iowrite8(cmd, ®s->cr_sr); /* Wait for transfer to complete (TIP = 0) */ start_time = jiffies; - status = regs->cr_sr; + status = ioread8(®s->cr_sr); while (status & M00018_SR_BITMAP_TIP_MSK) { if (time_after(jiffies, start_time + adap->timeout)) return -ETIMEDOUT; cond_resched(); - status = regs->cr_sr; + status = ioread8(®s->cr_sr); } /* Verify ACK */ @@ -174,7 +174,7 @@ static int cobalt_tx_bytes(volatile struct cobalt_i2c_regs __iomem *regs, /* Do low-level i2c byte read. * Returns -1 in case of an error or 0 otherwise. */ -static int cobalt_rx_bytes(volatile struct cobalt_i2c_regs __iomem *regs, +static int cobalt_rx_bytes(struct cobalt_i2c_regs __iomem *regs, struct i2c_adapter *adap, bool start, bool stop, u8 *data, u16 len) { @@ -203,16 +203,16 @@ static int cobalt_rx_bytes(volatile struct cobalt_i2c_regs __iomem *regs, cmd |= M00018_CR_BITMAP_ACK_MSK; /* Execute command */ - regs->cr_sr = cmd; + iowrite8(cmd, ®s->cr_sr); /* Wait for transfer to complete (TIP = 0) */ start_time = jiffies; - status = regs->cr_sr; + status = ioread8(®s->cr_sr); while (status & M00018_SR_BITMAP_TIP_MSK) { if (time_after(jiffies, start_time + adap->timeout)) return -ETIMEDOUT; cond_resched(); - status = regs->cr_sr; + status = ioread8(®s->cr_sr); } /* Verify arbitration */ @@ -222,7 +222,7 @@ static int cobalt_rx_bytes(volatile struct cobalt_i2c_regs __iomem *regs, } /* Store data */ - data[i] = regs->txr_rxr; + data[i] = ioread8(®s->txr_rxr); } return 0; } @@ -231,7 +231,7 @@ static int cobalt_rx_bytes(volatile struct cobalt_i2c_regs __iomem *regs, * The m00018 stop isn't doing the right thing (wrong timing). * So instead send a start condition, 8 zeroes and a stop condition. */ -static int cobalt_stop(volatile struct cobalt_i2c_regs __iomem *regs, +static int cobalt_stop(struct cobalt_i2c_regs __iomem *regs, struct i2c_adapter *adap) { u8 data = 0; @@ -243,7 +243,7 @@ static int cobalt_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) { struct cobalt_i2c_data *data = adap->algo_data; - volatile struct cobalt_i2c_regs __iomem *regs = data->regs; + struct cobalt_i2c_regs __iomem *regs = data->regs; struct i2c_msg *pmsg; unsigned short flags; int ret = 0; @@ -327,14 +327,14 @@ int cobalt_i2c_init(struct cobalt *cobalt) prescale = ((ALT_CPU_FREQ) / (5 * I2C_FREQUENCY)) - 1; for (i = 0; i < COBALT_NUM_ADAPTERS; i++) { - volatile struct cobalt_i2c_regs __iomem *regs = + struct cobalt_i2c_regs __iomem *regs = cobalt_i2c_regs(cobalt, i); struct i2c_adapter *adap = &cobalt->i2c_adap[i]; /* Disable I2C */ - regs->cr_sr = M00018_CTR_BITMAP_EN_MSK; - regs->ctr = 0; - regs->cr_sr = 0; + iowrite8(M00018_CTR_BITMAP_EN_MSK, ®s->cr_sr); + iowrite8(0, ®s->ctr); + iowrite8(0, ®s->cr_sr); start_time = jiffies; do { @@ -345,18 +345,18 @@ int cobalt_i2c_init(struct cobalt *cobalt) } return -ETIMEDOUT; } - status = regs->cr_sr; + status = ioread8(®s->cr_sr); } while (status & M00018_SR_BITMAP_TIP_MSK); /* Disable I2C */ - regs->ctr = 0; - regs->cr_sr = 0; + iowrite8(0, ®s->ctr); + iowrite8(0, ®s->cr_sr); /* Calculate i2c prescaler */ - regs->prerlo = prescale & 0xff; - regs->prerhi = (prescale >> 8) & 0xff; + iowrite8(prescale & 0xff, ®s->prerlo); + iowrite8((prescale >> 8) & 0xff, ®s->prerhi); /* Enable I2C, interrupts disabled */ - regs->ctr = M00018_CTR_BITMAP_EN_MSK; + iowrite8(M00018_CTR_BITMAP_EN_MSK, ®s->ctr); /* Setup algorithm for adapter */ cobalt->i2c_data[i].cobalt = cobalt; cobalt->i2c_data[i].regs = regs; -- cgit v1.2.3-59-g8ed1b From 4da707688b1f7628efe26058dffd6dbf3343f8ba Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 22 May 2015 06:30:59 -0300 Subject: [media] cobalt: fix sparse warnings drivers/media/pci/cobalt/cobalt-v4l2.c:189:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:191:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:192:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:193:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:194:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:195:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:196:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:197:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:198:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:199:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:201:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:202:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:203:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:234:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:240:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:246:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:266:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:267:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:271:28: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:275:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:276:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:312:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:313:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:314:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:315:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:317:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:320:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:321:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:321:36: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:324:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:327:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:328:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:328:41: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:329:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:331:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:332:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:334:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:335:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:336:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:362:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:367:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:368:17: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:420:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:421:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:422:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:423:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:516:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:516:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:518:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:518:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:518:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:525:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:525:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:531:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:531:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:531:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:531:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:531:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:531:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:531:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:546:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:546:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:548:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:549:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:550:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:551:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:552:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:553:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:554:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:555:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:556:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:556:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:556:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:563:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:564:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:564:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:569:9: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:595:16: warning: dereference of noderef expression drivers/media/pci/cobalt/cobalt-v4l2.c:602:9: warning: dereference of noderef expression Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cobalt/cobalt-v4l2.c | 234 +++++++++++++++++---------------- 1 file changed, 124 insertions(+), 110 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/cobalt/cobalt-v4l2.c b/drivers/media/pci/cobalt/cobalt-v4l2.c index 6e8d25b18b4e..8b14bec123eb 100644 --- a/drivers/media/pci/cobalt/cobalt-v4l2.c +++ b/drivers/media/pci/cobalt/cobalt-v4l2.c @@ -156,7 +156,7 @@ static void cobalt_enable_output(struct cobalt_stream *s) { struct cobalt *cobalt = s->cobalt; struct v4l2_bt_timings *bt = &s->timings.bt; - volatile struct m00514_syncgen_flow_evcnt_regmap __iomem *vo = + struct m00514_syncgen_flow_evcnt_regmap __iomem *vo = COBALT_TX_BASE(cobalt); unsigned fmt = s->pixfmt != V4L2_PIX_FMT_BGR32 ? M00514_CONTROL_BITMAP_FORMAT_16_BPP_MSK : 0; @@ -186,30 +186,31 @@ static void cobalt_enable_output(struct cobalt_stream *s) } v4l2_subdev_call(s->sd, pad, set_fmt, NULL, &sd_fmt); - vo->control = 0; + iowrite32(0, &vo->control); /* 1080p60 */ - vo->sync_generator_h_sync_length = bt->hsync; - vo->sync_generator_h_backporch_length = bt->hbackporch; - vo->sync_generator_h_active_length = bt->width; - vo->sync_generator_h_frontporch_length = bt->hfrontporch; - vo->sync_generator_v_sync_length = bt->vsync; - vo->sync_generator_v_backporch_length = bt->vbackporch; - vo->sync_generator_v_active_length = bt->height; - vo->sync_generator_v_frontporch_length = bt->vfrontporch; - vo->error_color = 0x9900c1; - - vo->control = M00514_CONTROL_BITMAP_SYNC_GENERATOR_LOAD_PARAM_MSK | fmt; - vo->control = M00514_CONTROL_BITMAP_EVCNT_CLEAR_MSK | fmt; - vo->control = M00514_CONTROL_BITMAP_SYNC_GENERATOR_ENABLE_MSK | - M00514_CONTROL_BITMAP_FLOW_CTRL_OUTPUT_ENABLE_MSK | - fmt; + iowrite32(bt->hsync, &vo->sync_generator_h_sync_length); + iowrite32(bt->hbackporch, &vo->sync_generator_h_backporch_length); + iowrite32(bt->width, &vo->sync_generator_h_active_length); + iowrite32(bt->hfrontporch, &vo->sync_generator_h_frontporch_length); + iowrite32(bt->vsync, &vo->sync_generator_v_sync_length); + iowrite32(bt->vbackporch, &vo->sync_generator_v_backporch_length); + iowrite32(bt->height, &vo->sync_generator_v_active_length); + iowrite32(bt->vfrontporch, &vo->sync_generator_v_frontporch_length); + iowrite32(0x9900c1, &vo->error_color); + + iowrite32(M00514_CONTROL_BITMAP_SYNC_GENERATOR_LOAD_PARAM_MSK | fmt, + &vo->control); + iowrite32(M00514_CONTROL_BITMAP_EVCNT_CLEAR_MSK | fmt, &vo->control); + iowrite32(M00514_CONTROL_BITMAP_SYNC_GENERATOR_ENABLE_MSK | + M00514_CONTROL_BITMAP_FLOW_CTRL_OUTPUT_ENABLE_MSK | + fmt, &vo->control); } static void cobalt_enable_input(struct cobalt_stream *s) { struct cobalt *cobalt = s->cobalt; int ch = (int)s->video_channel; - volatile struct m00235_fdma_packer_regmap __iomem *packer; + struct m00235_fdma_packer_regmap __iomem *packer; struct v4l2_subdev_format sd_fmt_yuyv = { .pad = s->pad_source, .which = V4L2_SUBDEV_FORMAT_ACTIVE, @@ -231,21 +232,24 @@ static void cobalt_enable_input(struct cobalt_stream *s) /* Set up FDMA packer */ switch (s->pixfmt) { case V4L2_PIX_FMT_YUYV: - packer->control = M00235_CONTROL_BITMAP_ENABLE_MSK | - (1 << M00235_CONTROL_BITMAP_PACK_FORMAT_OFST); + iowrite32(M00235_CONTROL_BITMAP_ENABLE_MSK | + (1 << M00235_CONTROL_BITMAP_PACK_FORMAT_OFST), + &packer->control); v4l2_subdev_call(s->sd, pad, set_fmt, NULL, &sd_fmt_yuyv); break; case V4L2_PIX_FMT_RGB24: - packer->control = M00235_CONTROL_BITMAP_ENABLE_MSK | - (2 << M00235_CONTROL_BITMAP_PACK_FORMAT_OFST); + iowrite32(M00235_CONTROL_BITMAP_ENABLE_MSK | + (2 << M00235_CONTROL_BITMAP_PACK_FORMAT_OFST), + &packer->control); v4l2_subdev_call(s->sd, pad, set_fmt, NULL, &sd_fmt_rgb); break; case V4L2_PIX_FMT_BGR32: - packer->control = M00235_CONTROL_BITMAP_ENABLE_MSK | - M00235_CONTROL_BITMAP_ENDIAN_FORMAT_MSK | - (3 << M00235_CONTROL_BITMAP_PACK_FORMAT_OFST); + iowrite32(M00235_CONTROL_BITMAP_ENABLE_MSK | + M00235_CONTROL_BITMAP_ENDIAN_FORMAT_MSK | + (3 << M00235_CONTROL_BITMAP_PACK_FORMAT_OFST), + &packer->control); v4l2_subdev_call(s->sd, pad, set_fmt, NULL, &sd_fmt_rgb); break; @@ -256,24 +260,26 @@ static void cobalt_dma_start_streaming(struct cobalt_stream *s) { struct cobalt *cobalt = s->cobalt; int rx = s->video_channel; - volatile struct m00460_evcnt_regmap __iomem *evcnt = + struct m00460_evcnt_regmap __iomem *evcnt = COBALT_CVI_EVCNT(cobalt, rx); struct cobalt_buffer *cb; unsigned long flags; spin_lock_irqsave(&s->irqlock, flags); if (!s->is_output) { - evcnt->control = M00460_CONTROL_BITMAP_CLEAR_MSK; - evcnt->control = M00460_CONTROL_BITMAP_ENABLE_MSK; + iowrite32(M00460_CONTROL_BITMAP_CLEAR_MSK, &evcnt->control); + iowrite32(M00460_CONTROL_BITMAP_ENABLE_MSK, &evcnt->control); } else { - volatile struct m00514_syncgen_flow_evcnt_regmap __iomem *vo = + struct m00514_syncgen_flow_evcnt_regmap __iomem *vo = COBALT_TX_BASE(cobalt); - u32 ctrl = vo->control; + u32 ctrl = ioread32(&vo->control); ctrl &= ~(M00514_CONTROL_BITMAP_EVCNT_ENABLE_MSK | M00514_CONTROL_BITMAP_EVCNT_CLEAR_MSK); - vo->control = ctrl | M00514_CONTROL_BITMAP_EVCNT_CLEAR_MSK; - vo->control = ctrl | M00514_CONTROL_BITMAP_EVCNT_ENABLE_MSK; + iowrite32(ctrl | M00514_CONTROL_BITMAP_EVCNT_CLEAR_MSK, + &vo->control); + iowrite32(ctrl | M00514_CONTROL_BITMAP_EVCNT_ENABLE_MSK, + &vo->control); } cb = list_first_entry(&s->bufs, struct cobalt_buffer, list); omni_sg_dma_start(s, &s->dma_desc_info[cb->vb.v4l2_buf.index]); @@ -284,16 +290,15 @@ static int cobalt_start_streaming(struct vb2_queue *q, unsigned int count) { struct cobalt_stream *s = q->drv_priv; struct cobalt *cobalt = s->cobalt; - volatile struct m00233_video_measure_regmap __iomem *vmr; - volatile struct m00473_freewheel_regmap __iomem *fw; - volatile struct m00479_clk_loss_detector_regmap __iomem *clkloss; + struct m00233_video_measure_regmap __iomem *vmr; + struct m00473_freewheel_regmap __iomem *fw; + struct m00479_clk_loss_detector_regmap __iomem *clkloss; int rx = s->video_channel; - volatile struct m00389_cvi_regmap __iomem *cvi = - COBALT_CVI(cobalt, rx); - volatile struct m00460_evcnt_regmap __iomem *evcnt = - COBALT_CVI_EVCNT(cobalt, rx); + struct m00389_cvi_regmap __iomem *cvi = COBALT_CVI(cobalt, rx); + struct m00460_evcnt_regmap __iomem *evcnt = COBALT_CVI_EVCNT(cobalt, rx); struct v4l2_bt_timings *bt = &s->timings.bt; u64 tot_size; + u32 clk_freq; if (s->is_audio) goto done; @@ -309,32 +314,34 @@ static int cobalt_start_streaming(struct vb2_queue *q, unsigned int count) vmr = COBALT_CVI_VMR(cobalt, rx); clkloss = COBALT_CVI_CLK_LOSS(cobalt, rx); - evcnt->control = M00460_CONTROL_BITMAP_CLEAR_MSK; - evcnt->control = M00460_CONTROL_BITMAP_ENABLE_MSK; - cvi->frame_width = bt->width; - cvi->frame_height = bt->height; + iowrite32(M00460_CONTROL_BITMAP_CLEAR_MSK, &evcnt->control); + iowrite32(M00460_CONTROL_BITMAP_ENABLE_MSK, &evcnt->control); + iowrite32(bt->width, &cvi->frame_width); + iowrite32(bt->height, &cvi->frame_height); tot_size = V4L2_DV_BT_FRAME_WIDTH(bt) * V4L2_DV_BT_FRAME_HEIGHT(bt); - vmr->hsync_timeout_val = - div_u64((u64)V4L2_DV_BT_FRAME_WIDTH(bt) * COBALT_CLK * 4, - bt->pixelclock); - vmr->control = M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK; - clkloss->ref_clk_cnt_val = fw->clk_freq / 1000000; + iowrite32(div_u64((u64)V4L2_DV_BT_FRAME_WIDTH(bt) * COBALT_CLK * 4, + bt->pixelclock), &vmr->hsync_timeout_val); + iowrite32(M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK, &vmr->control); + clk_freq = ioread32(&fw->clk_freq); + iowrite32(clk_freq / 1000000, &clkloss->ref_clk_cnt_val); /* The lower bound for the clock frequency is 0.5% lower as is * allowed by the spec */ - clkloss->test_clk_cnt_val = - (((u64)bt->pixelclock * 995) / 1000) / 1000000; + iowrite32((((u64)bt->pixelclock * 995) / 1000) / 1000000, + &clkloss->test_clk_cnt_val); /* will be enabled after the first frame has been received */ - fw->active_length = bt->width * bt->height; - fw->total_length = div_u64((u64)fw->clk_freq * tot_size, bt->pixelclock); - vmr->irq_triggers = M00233_IRQ_TRIGGERS_BITMAP_VACTIVE_AREA_MSK | - M00233_IRQ_TRIGGERS_BITMAP_HACTIVE_AREA_MSK; - cvi->control = 0; - vmr->control = M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK; - - fw->output_color = 0xff; - clkloss->ctrl = M00479_CTRL_BITMAP_ENABLE_MSK; - fw->ctrl = M00473_CTRL_BITMAP_ENABLE_MSK | - M00473_CTRL_BITMAP_FORCE_FREEWHEEL_MODE_MSK; + iowrite32(bt->width * bt->height, &fw->active_length); + iowrite32(div_u64((u64)clk_freq * tot_size, bt->pixelclock), + &fw->total_length); + iowrite32(M00233_IRQ_TRIGGERS_BITMAP_VACTIVE_AREA_MSK | + M00233_IRQ_TRIGGERS_BITMAP_HACTIVE_AREA_MSK, + &vmr->irq_triggers); + iowrite32(0, &cvi->control); + iowrite32(M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK, &vmr->control); + + iowrite32(0xff, &fw->output_color); + iowrite32(M00479_CTRL_BITMAP_ENABLE_MSK, &clkloss->ctrl); + iowrite32(M00473_CTRL_BITMAP_ENABLE_MSK | + M00473_CTRL_BITMAP_FORCE_FREEWHEEL_MODE_MSK, &fw->ctrl); s->unstable_frame = true; s->enable_freewheel = false; s->enable_cvi = false; @@ -355,17 +362,17 @@ static void cobalt_dma_stop_streaming(struct cobalt_stream *s) unsigned long flags; int timeout_msec = 100; int rx = s->video_channel; - volatile struct m00460_evcnt_regmap __iomem *evcnt = + struct m00460_evcnt_regmap __iomem *evcnt = COBALT_CVI_EVCNT(cobalt, rx); if (!s->is_output) { - evcnt->control = 0; + iowrite32(0, &evcnt->control); } else if (!s->is_audio) { - volatile struct m00514_syncgen_flow_evcnt_regmap __iomem *vo = + struct m00514_syncgen_flow_evcnt_regmap __iomem *vo = COBALT_TX_BASE(cobalt); - vo->control = M00514_CONTROL_BITMAP_EVCNT_CLEAR_MSK; - vo->control = 0; + iowrite32(M00514_CONTROL_BITMAP_EVCNT_CLEAR_MSK, &vo->control); + iowrite32(0, &vo->control); } /* Try to stop the DMA engine gracefully */ @@ -393,9 +400,9 @@ static void cobalt_stop_streaming(struct vb2_queue *q) struct cobalt_stream *s = q->drv_priv; struct cobalt *cobalt = s->cobalt; int rx = s->video_channel; - volatile struct m00233_video_measure_regmap __iomem *vmr; - volatile struct m00473_freewheel_regmap __iomem *fw; - volatile struct m00479_clk_loss_detector_regmap __iomem *clkloss; + struct m00233_video_measure_regmap __iomem *vmr; + struct m00473_freewheel_regmap __iomem *fw; + struct m00479_clk_loss_detector_regmap __iomem *clkloss; struct cobalt_buffer *cb; struct list_head *p, *safe; unsigned long flags; @@ -417,10 +424,10 @@ static void cobalt_stop_streaming(struct vb2_queue *q) fw = COBALT_CVI_FREEWHEEL(cobalt, rx); vmr = COBALT_CVI_VMR(cobalt, rx); clkloss = COBALT_CVI_CLK_LOSS(cobalt, rx); - vmr->control = 0; - vmr->control = M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK; - fw->ctrl = 0; - clkloss->ctrl = 0; + iowrite32(0, &vmr->control); + iowrite32(M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK, &vmr->control); + iowrite32(0, &fw->ctrl); + iowrite32(0, &clkloss->ctrl); } static const struct vb2_ops cobalt_qops = { @@ -500,80 +507,87 @@ static int cobalt_querycap(struct file *file, void *priv_fh, static void cobalt_video_input_status_show(struct cobalt_stream *s) { - volatile struct m00389_cvi_regmap __iomem *cvi; - volatile struct m00233_video_measure_regmap __iomem *vmr; - volatile struct m00473_freewheel_regmap __iomem *fw; - volatile struct m00479_clk_loss_detector_regmap __iomem *clkloss; - volatile struct m00235_fdma_packer_regmap __iomem *packer; + struct m00389_cvi_regmap __iomem *cvi; + struct m00233_video_measure_regmap __iomem *vmr; + struct m00473_freewheel_regmap __iomem *fw; + struct m00479_clk_loss_detector_regmap __iomem *clkloss; + struct m00235_fdma_packer_regmap __iomem *packer; int rx = s->video_channel; struct cobalt *cobalt = s->cobalt; + u32 cvi_ctrl, cvi_stat; + u32 vmr_ctrl, vmr_stat; cvi = COBALT_CVI(cobalt, rx); vmr = COBALT_CVI_VMR(cobalt, rx); fw = COBALT_CVI_FREEWHEEL(cobalt, rx); clkloss = COBALT_CVI_CLK_LOSS(cobalt, rx); packer = COBALT_CVI_PACKER(cobalt, rx); + cvi_ctrl = ioread32(&cvi->control); + cvi_stat = ioread32(&cvi->status); + vmr_ctrl = ioread32(&vmr->control); + vmr_stat = ioread32(&vmr->control); cobalt_info("rx%d: cvi resolution: %dx%d\n", rx, - cvi->frame_width, cvi->frame_height); + ioread32(&cvi->frame_width), ioread32(&cvi->frame_height)); cobalt_info("rx%d: cvi control: %s%s%s\n", rx, - (cvi->control & M00389_CONTROL_BITMAP_ENABLE_MSK) ? + (cvi_ctrl & M00389_CONTROL_BITMAP_ENABLE_MSK) ? "enable " : "disable ", - (cvi->control & M00389_CONTROL_BITMAP_HSYNC_POLARITY_LOW_MSK) ? + (cvi_ctrl & M00389_CONTROL_BITMAP_HSYNC_POLARITY_LOW_MSK) ? "HSync- " : "HSync+ ", - (cvi->control & M00389_CONTROL_BITMAP_VSYNC_POLARITY_LOW_MSK) ? + (cvi_ctrl & M00389_CONTROL_BITMAP_VSYNC_POLARITY_LOW_MSK) ? "VSync- " : "VSync+ "); cobalt_info("rx%d: cvi status: %s%s\n", rx, - (cvi->status & M00389_STATUS_BITMAP_LOCK_MSK) ? + (cvi_stat & M00389_STATUS_BITMAP_LOCK_MSK) ? "lock " : "no-lock ", - (cvi->status & M00389_STATUS_BITMAP_ERROR_MSK) ? + (cvi_stat & M00389_STATUS_BITMAP_ERROR_MSK) ? "error " : "no-error "); cobalt_info("rx%d: Measurements: %s%s%s%s%s%s%s\n", rx, - (vmr->control & M00233_CONTROL_BITMAP_HSYNC_POLARITY_LOW_MSK) ? + (vmr_ctrl & M00233_CONTROL_BITMAP_HSYNC_POLARITY_LOW_MSK) ? "HSync- " : "HSync+ ", - (vmr->control & M00233_CONTROL_BITMAP_VSYNC_POLARITY_LOW_MSK) ? + (vmr_ctrl & M00233_CONTROL_BITMAP_VSYNC_POLARITY_LOW_MSK) ? "VSync- " : "VSync+ ", - (vmr->control & M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK) ? + (vmr_ctrl & M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK) ? "enabled " : "disabled ", - (vmr->control & M00233_CONTROL_BITMAP_ENABLE_INTERRUPT_MSK) ? + (vmr_ctrl & M00233_CONTROL_BITMAP_ENABLE_INTERRUPT_MSK) ? "irq-enabled " : "irq-disabled ", - (vmr->control & M00233_CONTROL_BITMAP_UPDATE_ON_HSYNC_MSK) ? + (vmr_ctrl & M00233_CONTROL_BITMAP_UPDATE_ON_HSYNC_MSK) ? "update-on-hsync " : "", - (vmr->status & M00233_STATUS_BITMAP_HSYNC_TIMEOUT_MSK) ? + (vmr_stat & M00233_STATUS_BITMAP_HSYNC_TIMEOUT_MSK) ? "hsync-timeout " : "", - (vmr->status & M00233_STATUS_BITMAP_INIT_DONE_MSK) ? + (vmr_stat & M00233_STATUS_BITMAP_INIT_DONE_MSK) ? "init-done" : ""); cobalt_info("rx%d: irq_status: 0x%02x irq_triggers: 0x%02x\n", rx, - vmr->irq_status & 0xff, vmr->irq_triggers & 0xff); - cobalt_info("rx%d: vsync: %d\n", rx, vmr->vsync_time); - cobalt_info("rx%d: vbp: %d\n", rx, vmr->vback_porch); - cobalt_info("rx%d: vact: %d\n", rx, vmr->vactive_area); - cobalt_info("rx%d: vfb: %d\n", rx, vmr->vfront_porch); - cobalt_info("rx%d: hsync: %d\n", rx, vmr->hsync_time); - cobalt_info("rx%d: hbp: %d\n", rx, vmr->hback_porch); - cobalt_info("rx%d: hact: %d\n", rx, vmr->hactive_area); - cobalt_info("rx%d: hfb: %d\n", rx, vmr->hfront_porch); + ioread32(&vmr->irq_status) & 0xff, + ioread32(&vmr->irq_triggers) & 0xff); + cobalt_info("rx%d: vsync: %d\n", rx, ioread32(&vmr->vsync_time)); + cobalt_info("rx%d: vbp: %d\n", rx, ioread32(&vmr->vback_porch)); + cobalt_info("rx%d: vact: %d\n", rx, ioread32(&vmr->vactive_area)); + cobalt_info("rx%d: vfb: %d\n", rx, ioread32(&vmr->vfront_porch)); + cobalt_info("rx%d: hsync: %d\n", rx, ioread32(&vmr->hsync_time)); + cobalt_info("rx%d: hbp: %d\n", rx, ioread32(&vmr->hback_porch)); + cobalt_info("rx%d: hact: %d\n", rx, ioread32(&vmr->hactive_area)); + cobalt_info("rx%d: hfb: %d\n", rx, ioread32(&vmr->hfront_porch)); cobalt_info("rx%d: Freewheeling: %s%s%s\n", rx, - (fw->ctrl & M00473_CTRL_BITMAP_ENABLE_MSK) ? + (ioread32(&fw->ctrl) & M00473_CTRL_BITMAP_ENABLE_MSK) ? "enabled " : "disabled ", - (fw->ctrl & M00473_CTRL_BITMAP_FORCE_FREEWHEEL_MODE_MSK) ? + (ioread32(&fw->ctrl) & M00473_CTRL_BITMAP_FORCE_FREEWHEEL_MODE_MSK) ? "forced " : "", - (fw->status & M00473_STATUS_BITMAP_FREEWHEEL_MODE_MSK) ? + (ioread32(&fw->status) & M00473_STATUS_BITMAP_FREEWHEEL_MODE_MSK) ? "freewheeling " : "video-passthrough "); - vmr->irq_status = 0xff; + iowrite32(0xff, &vmr->irq_status); cobalt_info("rx%d: Clock Loss Detection: %s%s\n", rx, - (clkloss->ctrl & M00479_CTRL_BITMAP_ENABLE_MSK) ? + (ioread32(&clkloss->ctrl) & M00479_CTRL_BITMAP_ENABLE_MSK) ? "enabled " : "disabled ", - (clkloss->status & M00479_STATUS_BITMAP_CLOCK_MISSING_MSK) ? + (ioread32(&clkloss->status) & M00479_STATUS_BITMAP_CLOCK_MISSING_MSK) ? "clock-missing " : "found-clock "); - cobalt_info("rx%d: Packer: %x\n", rx, packer->control); + cobalt_info("rx%d: Packer: %x\n", rx, ioread32(&packer->control)); } static int cobalt_log_status(struct file *file, void *priv_fh) { struct cobalt_stream *s = video_drvdata(file); struct cobalt *cobalt = s->cobalt; - volatile struct m00514_syncgen_flow_evcnt_regmap __iomem *vo = + struct m00514_syncgen_flow_evcnt_regmap __iomem *vo = COBALT_TX_BASE(cobalt); u8 stat; @@ -592,14 +606,14 @@ static int cobalt_log_status(struct file *file, void *priv_fh) return 0; } - stat = vo->rd_status; + stat = ioread32(&vo->rd_status); cobalt_info("tx: status: %s%s\n", (stat & M00514_RD_STATUS_BITMAP_FLOW_CTRL_NO_DATA_ERROR_MSK) ? "no_data " : "", (stat & M00514_RD_STATUS_BITMAP_READY_BUFFER_FULL_MSK) ? "ready_buffer_full " : ""); - cobalt_info("tx: evcnt: %d\n", vo->rd_evcnt_count); + cobalt_info("tx: evcnt: %d\n", ioread32(&vo->rd_evcnt_count)); return 0; } -- cgit v1.2.3-59-g8ed1b From edff2bac9d3c3b94c0e790a49289824ff2c0a68c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 22 May 2015 10:44:49 -0300 Subject: [media] cx24120: fix sparse warning drivers/media/dvb-frontends/cx24120.c:837:6: warning: symbol 'cx24120_calculate_ber_window' was not declared. Should it be static? Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24120.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index 10a948ef8440..a1d1b1c44b40 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -838,7 +838,7 @@ static int cx24120_get_fec(struct dvb_frontend *fe) } /* Calculate ber window time */ -void cx24120_calculate_ber_window(struct cx24120_state *state, u32 rate) +static void cx24120_calculate_ber_window(struct cx24120_state *state, u32 rate) { struct dvb_frontend *fe = &state->frontend; struct dtv_frontend_properties *c = &fe->dtv_property_cache; -- cgit v1.2.3-59-g8ed1b From 7071b2eaba9fd209a415738cc87857212db93ed1 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 22 May 2015 10:45:28 -0300 Subject: [media] saa7164: fix sparse warning drivers/media/pci/saa7164/saa7164-i2c.c:45:33: warning: Using plain integer as NULL pointer Signed-off-by: Hans Verkuil Reviewed-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7164/saa7164-i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7164/saa7164-i2c.c b/drivers/media/pci/saa7164/saa7164-i2c.c index 6ea9d4f9ef2e..0342d84913b8 100644 --- a/drivers/media/pci/saa7164/saa7164-i2c.c +++ b/drivers/media/pci/saa7164/saa7164-i2c.c @@ -42,7 +42,7 @@ static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) retval = saa7164_api_i2c_read(bus, msgs[i].addr, 0 /* reglen */, - 0 /* reg */, msgs[i].len, msgs[i].buf); + NULL /* reg */, msgs[i].len, msgs[i].buf); } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) && msgs[i].addr == msgs[i + 1].addr) { /* write then read from same address */ -- cgit v1.2.3-59-g8ed1b From 29fba6a84bc73b9250472e4779ca255f585878a6 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 22 May 2015 11:02:45 -0300 Subject: [media] adv7604/cobalt: missing GPIOLIB dependency The adv7604 driver depends on GPIOLIB, and therefore cobalt depends on it as well. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/Kconfig | 2 +- drivers/media/pci/cobalt/Kconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 6f30ea76151a..36f5563ca9cd 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -196,7 +196,7 @@ config VIDEO_ADV7183 config VIDEO_ADV7604 tristate "Analog Devices ADV7604 decoder" - depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API + depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && GPIOLIB ---help--- Support for the Analog Devices ADV7604 video decoder. diff --git a/drivers/media/pci/cobalt/Kconfig b/drivers/media/pci/cobalt/Kconfig index e3c03e9b8263..3be1b2c3c386 100644 --- a/drivers/media/pci/cobalt/Kconfig +++ b/drivers/media/pci/cobalt/Kconfig @@ -1,7 +1,7 @@ config VIDEO_COBALT tristate "Cisco Cobalt support" depends on VIDEO_V4L2 && I2C && MEDIA_CONTROLLER - depends on PCI_MSI && MTD_COMPLEX_MAPPINGS + depends on PCI_MSI && MTD_COMPLEX_MAPPINGS && GPIOLIB select I2C_ALGOBIT select VIDEO_ADV7604 select VIDEO_ADV7511 -- cgit v1.2.3-59-g8ed1b From 6a5d77cbf26078e9ee8f88c7d77fe0a7fa4a0364 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Wed, 29 Apr 2015 09:00:45 -0300 Subject: [media] media/videobuf2-dma-sg: Fix handling of sg_table structure When sg_alloc_table_from_pages() does not fail it returns a sg_table structure with nents and nents_orig initialized to the same value. dma_map_sg returns the number of areas mapped by the hardware, which could be different than the areas given as an input. The output must be saved to nent. The output of dma_map, should be used to transverse the scatter list. dma_unmap_sg needs the value passed to dma_map_sg (nents_orig). sg_free_tables uses also orig_nent. This patch fix the file to follow this paradigm. Signed-off-by: Ricardo Ribalda Delgado Reviewed-by: Marek Szyprowski Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-dma-sg.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c index afd4b514affc..d7bcb05c7058 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c @@ -147,8 +147,9 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, * No need to sync to the device, this will happen later when the * prepare() memop is called. */ - if (dma_map_sg_attrs(buf->dev, sgt->sgl, sgt->nents, - buf->dma_dir, &attrs) == 0) + sgt->nents = dma_map_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents, + buf->dma_dir, &attrs); + if (!sgt->nents) goto fail_map; buf->handler.refcount = &buf->refcount; @@ -187,7 +188,7 @@ static void vb2_dma_sg_put(void *buf_priv) dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs); dprintk(1, "%s: Freeing buffer of %d pages\n", __func__, buf->num_pages); - dma_unmap_sg_attrs(buf->dev, sgt->sgl, sgt->nents, + dma_unmap_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir, &attrs); if (buf->vaddr) vm_unmap_ram(buf->vaddr, buf->num_pages); @@ -316,9 +317,11 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr, * No need to sync to the device, this will happen later when the * prepare() memop is called. */ - if (dma_map_sg_attrs(buf->dev, sgt->sgl, sgt->nents, - buf->dma_dir, &attrs) == 0) + sgt->nents = dma_map_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents, + buf->dma_dir, &attrs); + if (!sgt->nents) goto userptr_fail_map; + return buf; userptr_fail_map: @@ -355,7 +358,8 @@ static void vb2_dma_sg_put_userptr(void *buf_priv) dprintk(1, "%s: Releasing userspace buffer of %d pages\n", __func__, buf->num_pages); - dma_unmap_sg_attrs(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir, &attrs); + dma_unmap_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir, + &attrs); if (buf->vaddr) vm_unmap_ram(buf->vaddr, buf->num_pages); sg_free_table(buf->dma_sgt); @@ -508,7 +512,6 @@ static struct sg_table *vb2_dma_sg_dmabuf_ops_map( /* stealing dmabuf mutex to serialize map/unmap operations */ struct mutex *lock = &db_attach->dmabuf->lock; struct sg_table *sgt; - int ret; mutex_lock(lock); @@ -527,8 +530,9 @@ static struct sg_table *vb2_dma_sg_dmabuf_ops_map( } /* mapping to the client with new direction */ - ret = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, dma_dir); - if (ret <= 0) { + sgt->nents = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, + dma_dir); + if (!sgt->nents) { pr_err("failed to map scatterlist\n"); mutex_unlock(lock); return ERR_PTR(-EIO); -- cgit v1.2.3-59-g8ed1b From 60a471923869394a47c10262d080286eb01451b5 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Wed, 29 Apr 2015 09:00:46 -0300 Subject: [media] media/videobuf2-dma-contig: Save output from dma_map_sg dma_map_sg returns the number of areas mapped by the hardware, which could be different than the areas given as an input. The output must be saved to nent. Signed-off-by: Ricardo Ribalda Delgado Reviewed-by: Marek Szyprowski Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-dma-contig.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 620c4aa78881..369df95af5c7 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -299,7 +299,6 @@ static struct sg_table *vb2_dc_dmabuf_ops_map( /* stealing dmabuf mutex to serialize map/unmap operations */ struct mutex *lock = &db_attach->dmabuf->lock; struct sg_table *sgt; - int ret; mutex_lock(lock); @@ -318,8 +317,9 @@ static struct sg_table *vb2_dc_dmabuf_ops_map( } /* mapping to the client with new direction */ - ret = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, dma_dir); - if (ret <= 0) { + sgt->nents = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, + dma_dir); + if (!sgt->nents) { pr_err("failed to map scatterlist\n"); mutex_unlock(lock); return ERR_PTR(-EIO); -- cgit v1.2.3-59-g8ed1b From ba81c6ed3dd4717439940cd5f60b152ea924093d Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Wed, 29 Apr 2015 09:00:47 -0300 Subject: [media] media/videobuf2-dma-vmalloc: Save output from dma_map_sg dma_map_sg returns the number of areas mapped by the hardware, which could be different than the areas given as an input. The output must be saved to nent. Signed-off-by: Ricardo Ribalda Delgado Reviewed-by: Marek Szyprowski Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-vmalloc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c b/drivers/media/v4l2-core/videobuf2-vmalloc.c index 0ba40be21ebd..f6656fefc035 100644 --- a/drivers/media/v4l2-core/videobuf2-vmalloc.c +++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c @@ -291,7 +291,6 @@ static struct sg_table *vb2_vmalloc_dmabuf_ops_map( /* stealing dmabuf mutex to serialize map/unmap operations */ struct mutex *lock = &db_attach->dmabuf->lock; struct sg_table *sgt; - int ret; mutex_lock(lock); @@ -310,8 +309,9 @@ static struct sg_table *vb2_vmalloc_dmabuf_ops_map( } /* mapping to the client with new direction */ - ret = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, dma_dir); - if (ret <= 0) { + sgt->nents = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, + dma_dir); + if (!sgt->nents) { pr_err("failed to map scatterlist\n"); mutex_unlock(lock); return ERR_PTR(-EIO); -- cgit v1.2.3-59-g8ed1b From 2e5e435fb4fdcc64db49e903baddb1ea8827385e Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Mon, 4 May 2015 05:07:30 -0300 Subject: [media] media/v4l2-core: Add support for V4L2_PIX_FMT_Y16_BE 16 bit greyscale format, structured in Big Endian. Such a format can be converted into a PMN image just by adding a header. Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ioctl.c | 3 ++- include/uapi/linux/videodev2.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 14766029bf49..c5677e4030bb 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1146,6 +1146,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_Y10: descr = "10-bit Greyscale"; break; case V4L2_PIX_FMT_Y12: descr = "12-bit Greyscale"; break; case V4L2_PIX_FMT_Y16: descr = "16-bit Greyscale"; break; + case V4L2_PIX_FMT_Y16_BE: descr = "16-bit Greyscale BE"; break; case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; break; case V4L2_PIX_FMT_PAL8: descr = "8-bit Palette"; break; case V4L2_PIX_FMT_UV8: descr = "8-bit Chrominance UV 4-4"; break; @@ -2539,7 +2540,7 @@ static long __video_do_ioctl(struct file *file, if (v4l2_is_known_ioctl(cmd)) { info = &v4l2_ioctls[_IOC_NR(cmd)]; - if (!test_bit(_IOC_NR(cmd), vfd->valid_ioctls) && + if (!test_bit(_IOC_NR(cmd), vfd->valid_ioctls) && !((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler)) goto done; diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 0f5a4673f3e4..bda496adb50b 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -404,6 +404,7 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ') /* 10 Greyscale */ #define V4L2_PIX_FMT_Y12 v4l2_fourcc('Y', '1', '2', ' ') /* 12 Greyscale */ #define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */ +#define V4L2_PIX_FMT_Y16_BE v4l2_fourcc_be('Y', '1', '6', ' ') /* 16 Greyscale BE */ /* Grey bit-packed formats */ #define V4L2_PIX_FMT_Y10BPACK v4l2_fourcc('Y', '1', '0', 'B') /* 10 Greyscale bit-packed */ -- cgit v1.2.3-59-g8ed1b From b0ce23f065744ba136e6b059369f51e5ae1fb769 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Mon, 4 May 2015 05:07:31 -0300 Subject: [media] media/vivid: Add support for Y16_BE format Support for V4L2_PIX_FMT_Y16_BE, a 16 bit big endian greyscale format. Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-tpg.c | 9 ++++++++- drivers/media/platform/vivid/vivid-vid-common.c | 8 ++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/vivid/vivid-tpg.c b/drivers/media/platform/vivid/vivid-tpg.c index af4bc9780099..8cac0bdefd9a 100644 --- a/drivers/media/platform/vivid/vivid-tpg.c +++ b/drivers/media/platform/vivid/vivid-tpg.c @@ -221,6 +221,7 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) case V4L2_PIX_FMT_ABGR32: case V4L2_PIX_FMT_GREY: case V4L2_PIX_FMT_Y16: + case V4L2_PIX_FMT_Y16_BE: tpg->is_yuv = false; break; case V4L2_PIX_FMT_YUV444: @@ -316,6 +317,7 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) case V4L2_PIX_FMT_YUV555: case V4L2_PIX_FMT_YUV565: case V4L2_PIX_FMT_Y16: + case V4L2_PIX_FMT_Y16_BE: tpg->twopixelsize[0] = 2 * 2; break; case V4L2_PIX_FMT_RGB24: @@ -713,7 +715,8 @@ static void precalculate_color(struct tpg_data *tpg, int k) b <<= 4; } if (tpg->qual == TPG_QUAL_GRAY || tpg->fourcc == V4L2_PIX_FMT_GREY || - tpg->fourcc == V4L2_PIX_FMT_Y16) { + tpg->fourcc == V4L2_PIX_FMT_Y16 || + tpg->fourcc == V4L2_PIX_FMT_Y16_BE) { /* Rec. 709 Luma function */ /* (0.2126, 0.7152, 0.0722) * (255 * 256) */ r = g = b = (13879 * r + 46688 * g + 4713 * b) >> 16; @@ -900,6 +903,10 @@ static void gen_twopix(struct tpg_data *tpg, buf[0][offset] = 0; buf[0][offset+1] = r_y; break; + case V4L2_PIX_FMT_Y16_BE: + buf[0][offset] = r_y; + buf[0][offset+1] = 0; + break; case V4L2_PIX_FMT_YUV422P: case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YUV420M: diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c index 96ccd3c38dd2..45f10a7f9b46 100644 --- a/drivers/media/platform/vivid/vivid-vid-common.c +++ b/drivers/media/platform/vivid/vivid-vid-common.c @@ -196,6 +196,14 @@ struct vivid_fmt vivid_formats[] = { .planes = 1, .buffers = 1, }, + { + .fourcc = V4L2_PIX_FMT_Y16_BE, + .vdownsampling = { 1 }, + .bit_depth = { 16 }, + .is_yuv = true, + .planes = 1, + .buffers = 1, + }, { .fourcc = V4L2_PIX_FMT_RGB332, /* rrrgggbb */ .vdownsampling = { 1 }, -- cgit v1.2.3-59-g8ed1b From 3725d53149e190c6d8da80d458795a396705010e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 18 May 2015 10:29:17 -0300 Subject: [media] ivtv: fix incorrect audio mode report in log_status The log_status ioctl should report if the audio input has mode Bilingual. However, the check against the itv->dualwatch_stereo_mode is completely wrong and is a left-over from the distant past. Not only is the bitmask obviously wrong, the test itself is broken too since itv->dualwatch_stereo_mode is no longer a bitmask at all. Fix this code properly. Signed-off-by: Hans Verkuil Reported-by: Dan Carpenter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ivtv/ivtv-ioctl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.c b/drivers/media/pci/ivtv/ivtv-ioctl.c index 10c31cd43e03..9a21c17fc376 100644 --- a/drivers/media/pci/ivtv/ivtv-ioctl.c +++ b/drivers/media/pci/ivtv/ivtv-ioctl.c @@ -1531,7 +1531,8 @@ static int ivtv_log_status(struct file *file, void *fh) ivtv_get_audio_input(itv, itv->audio_input, &audin); IVTV_INFO("Video Input: %s\n", vidin.name); IVTV_INFO("Audio Input: %s%s\n", audin.name, - (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : ""); + itv->dualwatch_stereo_mode == V4L2_MPEG_AUDIO_MODE_DUAL ? + " (Bilingual)" : ""); if (has_output) { struct v4l2_output vidout; struct v4l2_audioout audout; -- cgit v1.2.3-59-g8ed1b From 9c54faef71c0dd7ce01ff0c4251d6fdfbf570b09 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 15 May 2015 09:29:10 -0300 Subject: [media] vivid: use new V4L2_MAP_*_DEFAULT defines Use these defines instead of hardcoding this in any driver that needs it. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-tpg.c | 51 ++++++-------------------------- 1 file changed, 9 insertions(+), 42 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/vivid/vivid-tpg.c b/drivers/media/platform/vivid/vivid-tpg.c index 8cac0bdefd9a..b1147f2df26c 100644 --- a/drivers/media/platform/vivid/vivid-tpg.c +++ b/drivers/media/platform/vivid/vivid-tpg.c @@ -1652,48 +1652,15 @@ static void tpg_recalc(struct tpg_data *tpg) tpg->recalc_lines = true; tpg->real_ycbcr_enc = tpg->ycbcr_enc; tpg->real_quantization = tpg->quantization; - if (tpg->ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT) { - switch (tpg->colorspace) { - case V4L2_COLORSPACE_REC709: - tpg->real_ycbcr_enc = V4L2_YCBCR_ENC_709; - break; - case V4L2_COLORSPACE_SRGB: - tpg->real_ycbcr_enc = V4L2_YCBCR_ENC_SYCC; - break; - case V4L2_COLORSPACE_BT2020: - tpg->real_ycbcr_enc = V4L2_YCBCR_ENC_BT2020; - break; - case V4L2_COLORSPACE_SMPTE240M: - tpg->real_ycbcr_enc = V4L2_YCBCR_ENC_SMPTE240M; - break; - case V4L2_COLORSPACE_SMPTE170M: - case V4L2_COLORSPACE_470_SYSTEM_M: - case V4L2_COLORSPACE_470_SYSTEM_BG: - case V4L2_COLORSPACE_ADOBERGB: - default: - tpg->real_ycbcr_enc = V4L2_YCBCR_ENC_601; - break; - } - } - if (tpg->quantization == V4L2_QUANTIZATION_DEFAULT) { - tpg->real_quantization = V4L2_QUANTIZATION_FULL_RANGE; - if (tpg->is_yuv) { - switch (tpg->real_ycbcr_enc) { - case V4L2_YCBCR_ENC_SYCC: - case V4L2_YCBCR_ENC_XV601: - case V4L2_YCBCR_ENC_XV709: - break; - default: - tpg->real_quantization = - V4L2_QUANTIZATION_LIM_RANGE; - break; - } - } else if (tpg->colorspace == V4L2_COLORSPACE_BT2020) { - /* R'G'B' BT.2020 is limited range */ - tpg->real_quantization = - V4L2_QUANTIZATION_LIM_RANGE; - } - } + if (tpg->ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT) + tpg->real_ycbcr_enc = + V4L2_MAP_YCBCR_ENC_DEFAULT(tpg->colorspace); + + if (tpg->quantization == V4L2_QUANTIZATION_DEFAULT) + tpg->real_quantization = + V4L2_MAP_QUANTIZATION_DEFAULT(!tpg->is_yuv, + tpg->colorspace, tpg->real_ycbcr_enc); + tpg_precalculate_colors(tpg); } if (tpg->recalc_square_border) { -- cgit v1.2.3-59-g8ed1b From 7615f4bcfae51a4cc5a5ad9610c02b735496a96b Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 17 May 2015 08:34:37 -0300 Subject: [media] vivid: SDR cap add 'CU08' Complex U8 format Add complex unsigned 8-bit sample format for SDR capture. Signed-off-by: Antti Palosaari Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-core.c | 7 +- drivers/media/platform/vivid/vivid-core.h | 2 + drivers/media/platform/vivid/vivid-sdr-cap.c | 96 ++++++++++++++++++++++++---- drivers/media/platform/vivid/vivid-sdr-cap.h | 2 + 4 files changed, 94 insertions(+), 13 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c index d6caeeb5758d..a047b4716741 100644 --- a/drivers/media/platform/vivid/vivid-core.c +++ b/drivers/media/platform/vivid/vivid-core.c @@ -559,8 +559,8 @@ static const struct v4l2_ioctl_ops vivid_ioctl_ops = { .vidioc_enum_fmt_sdr_cap = vidioc_enum_fmt_sdr_cap, .vidioc_g_fmt_sdr_cap = vidioc_g_fmt_sdr_cap, - .vidioc_try_fmt_sdr_cap = vidioc_g_fmt_sdr_cap, - .vidioc_s_fmt_sdr_cap = vidioc_g_fmt_sdr_cap, + .vidioc_try_fmt_sdr_cap = vidioc_try_fmt_sdr_cap, + .vidioc_s_fmt_sdr_cap = vidioc_s_fmt_sdr_cap, .vidioc_overlay = vidioc_overlay, .vidioc_enum_framesizes = vidioc_enum_framesizes, @@ -977,6 +977,9 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) dev->radio_tx_subchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_RDS; dev->sdr_adc_freq = 300000; dev->sdr_fm_freq = 50000000; + dev->sdr_pixelformat = V4L2_SDR_FMT_CU8; + dev->sdr_buffersize = SDR_CAP_SAMPLES_PER_BUF * 2; + dev->edid_max_blocks = dev->edid_blocks = 2; memcpy(dev->edid, vivid_hdmi_edid, sizeof(vivid_hdmi_edid)); ktime_get_ts(&dev->radio_rds_init_ts); diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h index bf26173f1e3b..aa1b5232a963 100644 --- a/drivers/media/platform/vivid/vivid-core.h +++ b/drivers/media/platform/vivid/vivid-core.h @@ -446,6 +446,8 @@ struct vivid_dev { /* SDR capture */ struct vb2_queue vb_sdr_cap_q; struct list_head sdr_cap_active; + u32 sdr_pixelformat; /* v4l2 format id */ + unsigned sdr_buffersize; unsigned sdr_adc_freq; unsigned sdr_fm_freq; int sdr_fixp_src_phase; diff --git a/drivers/media/platform/vivid/vivid-sdr-cap.c b/drivers/media/platform/vivid/vivid-sdr-cap.c index caf131666e37..d2f2188a0efe 100644 --- a/drivers/media/platform/vivid/vivid-sdr-cap.c +++ b/drivers/media/platform/vivid/vivid-sdr-cap.c @@ -33,6 +33,25 @@ #include "vivid-ctrls.h" #include "vivid-sdr-cap.h" +/* stream formats */ +struct vivid_format { + u32 pixelformat; + u32 buffersize; +}; + +/* format descriptions for capture and preview */ +static struct vivid_format formats[] = { + { + .pixelformat = V4L2_SDR_FMT_CU8, + .buffersize = SDR_CAP_SAMPLES_PER_BUF * 2, + }, { + .pixelformat = V4L2_SDR_FMT_CS8, + .buffersize = SDR_CAP_SAMPLES_PER_BUF * 2, + }, +}; + +static const unsigned int NUM_FORMATS = ARRAY_SIZE(formats); + static const struct v4l2_frequency_band bands_adc[] = { { .tuner = 0, @@ -409,21 +428,63 @@ int vivid_sdr_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt) int vidioc_enum_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f) { - if (f->index) + if (f->index >= ARRAY_SIZE(formats)) return -EINVAL; - f->pixelformat = V4L2_SDR_FMT_CU8; - strlcpy(f->description, "IQ U8", sizeof(f->description)); + f->pixelformat = formats[f->index].pixelformat; return 0; } int vidioc_g_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f) { - f->fmt.sdr.pixelformat = V4L2_SDR_FMT_CU8; - f->fmt.sdr.buffersize = SDR_CAP_SAMPLES_PER_BUF * 2; + struct vivid_dev *dev = video_drvdata(file); + + f->fmt.sdr.pixelformat = dev->sdr_pixelformat; + f->fmt.sdr.buffersize = dev->sdr_buffersize; memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); return 0; } +int vidioc_s_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f) +{ + struct vivid_dev *dev = video_drvdata(file); + struct vb2_queue *q = &dev->vb_sdr_cap_q; + int i; + + if (vb2_is_busy(q)) + return -EBUSY; + + memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); + for (i = 0; i < ARRAY_SIZE(formats); i++) { + if (formats[i].pixelformat == f->fmt.sdr.pixelformat) { + dev->sdr_pixelformat = formats[i].pixelformat; + dev->sdr_buffersize = formats[i].buffersize; + f->fmt.sdr.buffersize = formats[i].buffersize; + return 0; + } + } + dev->sdr_pixelformat = formats[0].pixelformat; + dev->sdr_buffersize = formats[0].buffersize; + f->fmt.sdr.pixelformat = formats[0].pixelformat; + f->fmt.sdr.buffersize = formats[0].buffersize; + return 0; +} + +int vidioc_try_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f) +{ + int i; + + memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); + for (i = 0; i < ARRAY_SIZE(formats); i++) { + if (formats[i].pixelformat == f->fmt.sdr.pixelformat) { + f->fmt.sdr.buffersize = formats[i].buffersize; + return 0; + } + } + f->fmt.sdr.pixelformat = formats[0].pixelformat; + f->fmt.sdr.buffersize = formats[0].buffersize; + return 0; +} + #define FIXP_N (15) #define FIXP_FRAC (1 << FIXP_N) #define FIXP_2PI ((int)(2 * 3.141592653589 * FIXP_FRAC)) @@ -477,11 +538,24 @@ void vivid_sdr_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf) fixp_i >>= (31 - FIXP_N); fixp_q >>= (31 - FIXP_N); - /* convert 'fixp float' to u8 */ - /* u8 = X * 127.5f + 127.5f; where X is float [-1.0 / +1.0] */ - fixp_i = fixp_i * 1275 + FIXP_FRAC * 1275; - fixp_q = fixp_q * 1275 + FIXP_FRAC * 1275; - *vbuf++ = DIV_ROUND_CLOSEST(fixp_i, FIXP_FRAC * 10); - *vbuf++ = DIV_ROUND_CLOSEST(fixp_q, FIXP_FRAC * 10); + switch (dev->sdr_pixelformat) { + case V4L2_SDR_FMT_CU8: + /* convert 'fixp float' to u8 */ + /* u8 = X * 127.5 + 127.5; X is float [-1.0, +1.0] */ + fixp_i = fixp_i * 1275 + FIXP_FRAC * 1275; + fixp_q = fixp_q * 1275 + FIXP_FRAC * 1275; + *vbuf++ = DIV_ROUND_CLOSEST(fixp_i, FIXP_FRAC * 10); + *vbuf++ = DIV_ROUND_CLOSEST(fixp_q, FIXP_FRAC * 10); + break; + case V4L2_SDR_FMT_CS8: + /* convert 'fixp float' to s8 */ + fixp_i = fixp_i * 1275; + fixp_q = fixp_q * 1275; + *vbuf++ = DIV_ROUND_CLOSEST(fixp_i, FIXP_FRAC * 10); + *vbuf++ = DIV_ROUND_CLOSEST(fixp_q, FIXP_FRAC * 10); + break; + default: + break; + } } } diff --git a/drivers/media/platform/vivid/vivid-sdr-cap.h b/drivers/media/platform/vivid/vivid-sdr-cap.h index 79c1890de972..43014b2733db 100644 --- a/drivers/media/platform/vivid/vivid-sdr-cap.h +++ b/drivers/media/platform/vivid/vivid-sdr-cap.h @@ -27,6 +27,8 @@ int vivid_sdr_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt); int vivid_sdr_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt); int vidioc_enum_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f); int vidioc_g_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f); +int vidioc_s_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f); +int vidioc_try_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f); void vivid_sdr_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf); extern const struct vb2_ops vivid_sdr_cap_qops; -- cgit v1.2.3-59-g8ed1b From 48fc10aaf180d71bd7953f9e25b0fd7393b5123a Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 17 May 2015 08:38:04 -0300 Subject: [media] v4l2: correct two SDR format names U8 and U16LE format human readable names were translated with string containing emulated word. These strings were taken from msi2500 driver, where those formats were emulated (after module parameter is set). But on API correct names should be used, without any special case notes. Signed-off-by: Antti Palosaari Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ioctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index c5677e4030bb..368bc3a973d4 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1216,8 +1216,8 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_TM6000: descr = "A/V + VBI Mux Packet"; break; case V4L2_PIX_FMT_CIT_YYVYUY: descr = "GSPCA CIT YYVYUY"; break; case V4L2_PIX_FMT_KONICA420: descr = "GSPCA KONICA420"; break; - case V4L2_SDR_FMT_CU8: descr = "Complex U8 (Emulated)"; break; - case V4L2_SDR_FMT_CU16LE: descr = "Complex U16LE (Emulated)"; break; + case V4L2_SDR_FMT_CU8: descr = "Complex U8"; break; + case V4L2_SDR_FMT_CU16LE: descr = "Complex U16LE"; break; case V4L2_SDR_FMT_CS8: descr = "Complex S8"; break; case V4L2_SDR_FMT_CS14LE: descr = "Complex S14LE"; break; case V4L2_SDR_FMT_RU12LE: descr = "Real U12LE"; break; -- cgit v1.2.3-59-g8ed1b From c579401a246328e1a11bd4cce70e6d0b63c3cfdb Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 5 May 2015 13:32:26 -0300 Subject: [media] wl128x: Allow compile test of GPIO consumers if !GPIOLIB The GPIO subsystem provides dummy GPIO consumer functions if GPIOLIB is not enabled. Hence drivers that depend on GPIOLIB, but use GPIO consumer functionality only, can still be compiled if GPIOLIB is not enabled. Relax the dependency on GPIOLIB if COMPILE_TEST is enabled, where appropriate. Signed-off-by: Geert Uytterhoeven Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/wl128x/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/wl128x/Kconfig b/drivers/media/radio/wl128x/Kconfig index 9d6574bebf78..c9e349b169c4 100644 --- a/drivers/media/radio/wl128x/Kconfig +++ b/drivers/media/radio/wl128x/Kconfig @@ -4,8 +4,8 @@ menu "Texas Instruments WL128x FM driver (ST based)" config RADIO_WL128X tristate "Texas Instruments WL128x FM Radio" - depends on VIDEO_V4L2 && RFKILL && GPIOLIB && TTY - depends on TI_ST + depends on VIDEO_V4L2 && RFKILL && TTY && TI_ST + depends on GPIOLIB || COMPILE_TEST help Choose Y here if you have this FM radio chip. -- cgit v1.2.3-59-g8ed1b From 48c291eda79da46582438ec8d821c6efcd54120d Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Fri, 24 Apr 2015 04:04:03 -0300 Subject: [media] gspca: sn9c2028: Add support for Genius Videocam Live v2 This cam seems to return different values on long commands, so make status check in sn9c2028_long_command() more tolerant. Anyway, read value isn't used anywhere later. Signed-off-by: Vasily Khoruzhick Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/gspca/sn9c2028.c | 119 ++++++++++++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/gspca/sn9c2028.c b/drivers/media/usb/gspca/sn9c2028.c index 39b6b2e02963..e59576c43f73 100644 --- a/drivers/media/usb/gspca/sn9c2028.c +++ b/drivers/media/usb/gspca/sn9c2028.c @@ -128,7 +128,7 @@ static int sn9c2028_long_command(struct gspca_dev *gspca_dev, u8 *command) status = -1; for (i = 0; i < 256 && status < 2; i++) status = sn9c2028_read1(gspca_dev); - if (status != 2) { + if (status < 0) { pr_err("long command status read error %d\n", status); return (status < 0) ? status : -EIO; } @@ -178,6 +178,9 @@ static int sd_config(struct gspca_dev *gspca_dev, case 0x7005: PDEBUG(D_PROBE, "Genius Smart 300 camera"); break; + case 0x7003: + PDEBUG(D_PROBE, "Genius Videocam Live v2"); + break; case 0x8000: PDEBUG(D_PROBE, "DC31VC"); break; @@ -530,6 +533,116 @@ static int start_genius_cam(struct gspca_dev *gspca_dev) ARRAY_SIZE(genius_start_commands)); } +static int start_genius_videocam_live(struct gspca_dev *gspca_dev) +{ + int r; + struct sd *sd = (struct sd *) gspca_dev; + struct init_command genius_vcam_live_start_commands[] = { + {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 0}, + {{0x16, 0x01, 0x00, 0x00, 0x00, 0x00}, 4}, + {{0x10, 0x00, 0x00, 0x00, 0x00, 0x00}, 4}, + {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4}, + {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4}, + + {{0x13, 0x28, 0x01, 0x0e, 0x00, 0x00}, 4}, + {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4}, + {{0x13, 0x29, 0x01, 0x22, 0x00, 0x00}, 4}, + {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4}, + {{0x13, 0x2d, 0x01, 0x02, 0x00, 0x00}, 4}, + {{0x13, 0x2e, 0x01, 0x09, 0x00, 0x00}, 4}, + {{0x13, 0x2f, 0x01, 0x07, 0x00, 0x00}, 4}, + {{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x21, 0x2d, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x23, 0x03, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x11, 0x64, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x13, 0x91, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x14, 0x01, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x15, 0x20, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x16, 0x01, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x17, 0x60, 0x00, 0x00, 0x00}, 4}, + {{0x1c, 0x20, 0x00, 0x2d, 0x00, 0x00}, 4}, + {{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4}, + {{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4}, + {{0x13, 0x22, 0x01, 0x00, 0x00, 0x00}, 4}, + {{0x13, 0x23, 0x01, 0x01, 0x00, 0x00}, 4}, + {{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4}, + {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4}, + {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4}, + {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4}, + {{0x13, 0x28, 0x01, 0x0e, 0x00, 0x00}, 4}, + {{0x13, 0x29, 0x01, 0x22, 0x00, 0x00}, 4}, + {{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4}, + {{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4}, + {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4}, + {{0x13, 0x2d, 0x01, 0x02, 0x00, 0x00}, 4}, + {{0x13, 0x2e, 0x01, 0x09, 0x00, 0x00}, 4}, + {{0x13, 0x2f, 0x01, 0x07, 0x00, 0x00}, 4}, + {{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4}, + {{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4}, + {{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x01, 0x04, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x02, 0x92, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x11, 0x64, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x13, 0x91, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x14, 0x01, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x15, 0x20, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x16, 0x01, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x17, 0x60, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x21, 0x2d, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x23, 0x03, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x25, 0x00, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x26, 0x02, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x27, 0x88, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x30, 0x38, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x31, 0x2a, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x32, 0x2a, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x33, 0x2a, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x34, 0x02, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x5b, 0x0a, 0x00, 0x00, 0x00}, 4}, + {{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4}, + {{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4}, + {{0x13, 0x28, 0x01, 0x0e, 0x00, 0x00}, 4}, + {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4}, + {{0x13, 0x29, 0x01, 0x62, 0x00, 0x00}, 4}, + {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4}, + {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4}, + {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4}, + {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4}, + {{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x21, 0x2a, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x23, 0x28, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x11, 0x04, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x13, 0x03, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x14, 0x01, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x15, 0xe0, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x16, 0x02, 0x00, 0x00, 0x00}, 4}, + {{0x11, 0x17, 0x80, 0x00, 0x00, 0x00}, 4}, + {{0x1c, 0x20, 0x00, 0x2a, 0x00, 0x00}, 1}, + {{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 0}, + /* Camera should start to capture now. */ + {{0x12, 0x27, 0x01, 0x00, 0x00, 0x00}, 0}, + {{0x1b, 0x32, 0x26, 0x00, 0x00, 0x00}, 0}, + {{0x1d, 0x25, 0x10, 0x20, 0xab, 0x00}, 0}, + }; + + r = run_start_commands(gspca_dev, genius_vcam_live_start_commands, + ARRAY_SIZE(genius_vcam_live_start_commands)); + if (r < 0) + return r; + + return r; +} + static int start_vivitar_cam(struct gspca_dev *gspca_dev) { struct init_command vivitar_start_commands[] = { @@ -623,6 +736,9 @@ static int sd_start(struct gspca_dev *gspca_dev) case 0x7005: err_code = start_genius_cam(gspca_dev); break; + case 0x7003: + err_code = start_genius_videocam_live(gspca_dev); + break; case 0x8001: err_code = start_spy_cam(gspca_dev); break; @@ -701,6 +817,7 @@ static const struct sd_desc sd_desc = { /* -- module initialisation -- */ static const struct usb_device_id device_table[] = { {USB_DEVICE(0x0458, 0x7005)}, /* Genius Smart 300, version 2 */ + {USB_DEVICE(0x0458, 0x7003)}, /* Genius Videocam Live v2 */ /* The Genius Smart is untested. I can't find an owner ! */ /* {USB_DEVICE(0x0c45, 0x8000)}, DC31VC, Don't know this camera */ {USB_DEVICE(0x0c45, 0x8001)}, /* Wild Planet digital spy cam */ -- cgit v1.2.3-59-g8ed1b From d8fd9f56255cfeebe88b987543fd2d1399a35a25 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Fri, 24 Apr 2015 04:04:04 -0300 Subject: [media] gspca: sn9c2028: Add gain and autogain controls Genius Videocam Live v2 Autogain algorithm is very simple, if average luminance is low - increase gain, if it's high - decrease gain. Gain granularity is low enough for this algo to stabilize quickly. Signed-off-by: Vasily Khoruzhick Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/gspca/sn9c2028.c | 122 +++++++++++++++++++++++++++++++++++++ drivers/media/usb/gspca/sn9c2028.h | 18 +++++- 2 files changed, 137 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/gspca/sn9c2028.c b/drivers/media/usb/gspca/sn9c2028.c index e59576c43f73..c75b7388a85c 100644 --- a/drivers/media/usb/gspca/sn9c2028.c +++ b/drivers/media/usb/gspca/sn9c2028.c @@ -33,6 +33,16 @@ struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ u8 sof_read; u16 model; + +#define MIN_AVG_LUM 8500 +#define MAX_AVG_LUM 10000 + int avg_lum; + u8 avg_lum_l; + + struct { /* autogain and gain control cluster */ + struct v4l2_ctrl *autogain; + struct v4l2_ctrl *gain; + }; }; struct init_command { @@ -251,6 +261,78 @@ static int run_start_commands(struct gspca_dev *gspca_dev, return 0; } +static void set_gain(struct gspca_dev *gspca_dev, s32 g) +{ + struct sd *sd = (struct sd *) gspca_dev; + + struct init_command genius_vcam_live_gain_cmds[] = { + {{0x1d, 0x25, 0x10 /* This byte is gain */, + 0x20, 0xab, 0x00}, 0}, + }; + if (!gspca_dev->streaming) + return; + + switch (sd->model) { + case 0x7003: + genius_vcam_live_gain_cmds[0].instruction[2] = g; + run_start_commands(gspca_dev, genius_vcam_live_gain_cmds, + ARRAY_SIZE(genius_vcam_live_gain_cmds)); + break; + default: + break; + } +} + +static int sd_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct gspca_dev *gspca_dev = + container_of(ctrl->handler, struct gspca_dev, ctrl_handler); + struct sd *sd = (struct sd *)gspca_dev; + + gspca_dev->usb_err = 0; + + if (!gspca_dev->streaming) + return 0; + + switch (ctrl->id) { + /* standalone gain control */ + case V4L2_CID_GAIN: + set_gain(gspca_dev, ctrl->val); + break; + /* autogain */ + case V4L2_CID_AUTOGAIN: + set_gain(gspca_dev, sd->gain->val); + break; + } + return gspca_dev->usb_err; +} + +static const struct v4l2_ctrl_ops sd_ctrl_ops = { + .s_ctrl = sd_s_ctrl, +}; + + +static int sd_init_controls(struct gspca_dev *gspca_dev) +{ + struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; + struct sd *sd = (struct sd *)gspca_dev; + + gspca_dev->vdev.ctrl_handler = hdl; + v4l2_ctrl_handler_init(hdl, 2); + + switch (sd->model) { + case 0x7003: + sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, + V4L2_CID_GAIN, 0, 20, 1, 0); + sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, + V4L2_CID_AUTOGAIN, 0, 1, 1, 1); + break; + default: + break; + } + + return 0; +} static int start_spy_cam(struct gspca_dev *gspca_dev) { struct init_command spy_start_commands[] = { @@ -640,6 +722,9 @@ static int start_genius_videocam_live(struct gspca_dev *gspca_dev) if (r < 0) return r; + if (sd->gain) + set_gain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain)); + return r; } @@ -756,6 +841,8 @@ static int sd_start(struct gspca_dev *gspca_dev) return -ENXIO; } + sd->avg_lum = -1; + return err_code; } @@ -775,6 +862,39 @@ static void sd_stopN(struct gspca_dev *gspca_dev) PERR("Camera Stop command failed"); } +static void do_autogain(struct gspca_dev *gspca_dev, int avg_lum) +{ + struct sd *sd = (struct sd *) gspca_dev; + s32 cur_gain = v4l2_ctrl_g_ctrl(sd->gain); + + if (avg_lum == -1) + return; + + if (avg_lum < MIN_AVG_LUM) { + if (cur_gain == sd->gain->maximum) + return; + cur_gain++; + v4l2_ctrl_s_ctrl(sd->gain, cur_gain); + } + if (avg_lum > MAX_AVG_LUM) { + if (cur_gain == sd->gain->minimum) + return; + cur_gain--; + v4l2_ctrl_s_ctrl(sd->gain, cur_gain); + } + +} + +static void sd_dqcallback(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + if (sd->autogain == NULL || !v4l2_ctrl_g_ctrl(sd->autogain)) + return; + + do_autogain(gspca_dev, sd->avg_lum); +} + /* Include sn9c2028 sof detection functions */ #include "sn9c2028.h" @@ -809,8 +929,10 @@ static const struct sd_desc sd_desc = { .name = MODULE_NAME, .config = sd_config, .init = sd_init, + .init_controls = sd_init_controls, .start = sd_start, .stopN = sd_stopN, + .dq_callback = sd_dqcallback, .pkt_scan = sd_pkt_scan, }; diff --git a/drivers/media/usb/gspca/sn9c2028.h b/drivers/media/usb/gspca/sn9c2028.h index 8fd1d3e05665..f85bc106bc52 100644 --- a/drivers/media/usb/gspca/sn9c2028.h +++ b/drivers/media/usb/gspca/sn9c2028.h @@ -21,8 +21,15 @@ * */ -static const unsigned char sn9c2028_sof_marker[5] = - { 0xff, 0xff, 0x00, 0xc4, 0xc4 }; +static const unsigned char sn9c2028_sof_marker[] = { + 0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96, + 0x00, + 0x00, /* seq */ + 0x00, + 0x00, + 0x00, /* avg luminance lower 8 bit */ + 0x00, /* avg luminance higher 8 bit */ +}; static unsigned char *sn9c2028_find_sof(struct gspca_dev *gspca_dev, unsigned char *m, int len) @@ -32,8 +39,13 @@ static unsigned char *sn9c2028_find_sof(struct gspca_dev *gspca_dev, /* Search for the SOF marker (fixed part) in the header */ for (i = 0; i < len; i++) { - if (m[i] == sn9c2028_sof_marker[sd->sof_read]) { + if ((m[i] == sn9c2028_sof_marker[sd->sof_read]) || + (sd->sof_read > 5)) { sd->sof_read++; + if (sd->sof_read == 11) + sd->avg_lum_l = m[i]; + if (sd->sof_read == 12) + sd->avg_lum = (m[i] << 8) + sd->avg_lum_l; if (sd->sof_read == sizeof(sn9c2028_sof_marker)) { PDEBUG(D_FRAM, "SOF found, bytes to analyze: %u." -- cgit v1.2.3-59-g8ed1b From 9240c384f1c7cbf7ba15ccf818f37fad69fd4712 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 13 Apr 2015 21:00:09 -0300 Subject: [media] m88ds3103: do not return error from get_frontend() when not ready Do not return error from get_frontend() when status is queried, but the frontend didn't lock yet. The proper behavior is to only update the cache after having a lock. [mchehab@osg.samsung.com: fix the patch description] Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/m88ds3103.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index d3d928e1c0ce..03dceb50863f 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -742,7 +742,7 @@ static int m88ds3103_get_frontend(struct dvb_frontend *fe) dev_dbg(&priv->i2c->dev, "%s:\n", __func__); if (!priv->warm || !(priv->fe_status & FE_HAS_LOCK)) { - ret = -EAGAIN; + ret = 0; goto err; } -- cgit v1.2.3-59-g8ed1b From c1daf6511a5ddd9c6f4855978bb9345beef90937 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 13 Apr 2015 20:56:13 -0300 Subject: [media] m88ds3103: implement DVBv5 CNR statistics Implement DVBv5 CNR statistics. Wrap legacy DVBv3 SNR to DVBv5 CNR. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/m88ds3103.c | 154 +++++++++++++++++--------------- 1 file changed, 82 insertions(+), 72 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index 03dceb50863f..381a8ad173b5 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -190,8 +190,9 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, fe_status_t *status) { struct m88ds3103_priv *priv = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int ret; + int ret, i, itmp; u8 u8tmp; + u8 buf[3]; *status = 0; @@ -233,6 +234,77 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, fe_status_t *status) dev_dbg(&priv->i2c->dev, "%s: lock=%02x status=%02x\n", __func__, u8tmp, *status); + /* CNR */ + if (priv->fe_status & FE_HAS_VITERBI) { + unsigned int cnr, noise, signal, noise_tot, signal_tot; + + cnr = 0; + /* more iterations for more accurate estimation */ + #define M88DS3103_SNR_ITERATIONS 3 + + switch (c->delivery_system) { + case SYS_DVBS: + itmp = 0; + + for (i = 0; i < M88DS3103_SNR_ITERATIONS; i++) { + ret = m88ds3103_rd_reg(priv, 0xff, &buf[0]); + if (ret) + goto err; + + itmp += buf[0]; + } + + /* use of single register limits max value to 15 dB */ + /* SNR(X) dB = 10 * ln(X) / ln(10) dB */ + itmp = DIV_ROUND_CLOSEST(itmp, 8 * M88DS3103_SNR_ITERATIONS); + if (itmp) + cnr = div_u64((u64) 10000 * intlog2(itmp), intlog2(10)); + break; + case SYS_DVBS2: + noise_tot = 0; + signal_tot = 0; + + for (i = 0; i < M88DS3103_SNR_ITERATIONS; i++) { + ret = m88ds3103_rd_regs(priv, 0x8c, buf, 3); + if (ret) + goto err; + + noise = buf[1] << 6; /* [13:6] */ + noise |= buf[0] & 0x3f; /* [5:0] */ + noise >>= 2; + signal = buf[2] * buf[2]; + signal >>= 1; + + noise_tot += noise; + signal_tot += signal; + } + + noise = noise_tot / M88DS3103_SNR_ITERATIONS; + signal = signal_tot / M88DS3103_SNR_ITERATIONS; + + /* SNR(X) dB = 10 * log10(X) dB */ + if (signal > noise) { + itmp = signal / noise; + cnr = div_u64((u64) 10000 * intlog10(itmp), (1 << 24)); + } + break; + default: + dev_dbg(&priv->i2c->dev, + "%s: invalid delivery_system\n", __func__); + ret = -EINVAL; + goto err; + } + + if (cnr) { + c->cnr.stat[0].scale = FE_SCALE_DECIBEL; + c->cnr.stat[0].svalue = cnr; + } else { + c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + } + } else { + c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + } + return 0; err: dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); @@ -577,6 +649,7 @@ err: static int m88ds3103_init(struct dvb_frontend *fe) { struct m88ds3103_priv *priv = fe->demodulator_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, len, remaining; const struct firmware *fw = NULL; u8 *fw_file; @@ -684,7 +757,9 @@ static int m88ds3103_init(struct dvb_frontend *fe) skip_fw_download: /* warm state */ priv->warm = true; - + /* init stats here in order signal app which stats are supported */ + c->cnr.len = 1; + c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; return 0; error_fw_release: @@ -702,6 +777,7 @@ static int m88ds3103_sleep(struct dvb_frontend *fe) dev_dbg(&priv->i2c->dev, "%s:\n", __func__); + priv->fe_status = 0; priv->delivery_system = SYS_UNDEFINED; /* TS Hi-Z */ @@ -908,80 +984,14 @@ err: static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *snr) { - struct m88ds3103_priv *priv = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int ret, i, tmp; - u8 buf[3]; - u16 noise, signal; - u32 noise_tot, signal_tot; - dev_dbg(&priv->i2c->dev, "%s:\n", __func__); - /* reports SNR in resolution of 0.1 dB */ - - /* more iterations for more accurate estimation */ - #define M88DS3103_SNR_ITERATIONS 3 - - switch (c->delivery_system) { - case SYS_DVBS: - tmp = 0; - - for (i = 0; i < M88DS3103_SNR_ITERATIONS; i++) { - ret = m88ds3103_rd_reg(priv, 0xff, &buf[0]); - if (ret) - goto err; - - tmp += buf[0]; - } - - /* use of one register limits max value to 15 dB */ - /* SNR(X) dB = 10 * ln(X) / ln(10) dB */ - tmp = DIV_ROUND_CLOSEST(tmp, 8 * M88DS3103_SNR_ITERATIONS); - if (tmp) - *snr = div_u64((u64) 100 * intlog2(tmp), intlog2(10)); - else - *snr = 0; - break; - case SYS_DVBS2: - noise_tot = 0; - signal_tot = 0; - - for (i = 0; i < M88DS3103_SNR_ITERATIONS; i++) { - ret = m88ds3103_rd_regs(priv, 0x8c, buf, 3); - if (ret) - goto err; - - noise = buf[1] << 6; /* [13:6] */ - noise |= buf[0] & 0x3f; /* [5:0] */ - noise >>= 2; - signal = buf[2] * buf[2]; - signal >>= 1; - - noise_tot += noise; - signal_tot += signal; - } - - noise = noise_tot / M88DS3103_SNR_ITERATIONS; - signal = signal_tot / M88DS3103_SNR_ITERATIONS; - - /* SNR(X) dB = 10 * log10(X) dB */ - if (signal > noise) { - tmp = signal / noise; - *snr = div_u64((u64) 100 * intlog10(tmp), (1 << 24)); - } else { - *snr = 0; - } - break; - default: - dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n", - __func__); - ret = -EINVAL; - goto err; - } + if (c->cnr.stat[0].scale == FE_SCALE_DECIBEL) + *snr = div_s64(c->cnr.stat[0].svalue, 100); + else + *snr = 0; return 0; -err: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); - return ret; } static int m88ds3103_read_ber(struct dvb_frontend *fe, u32 *ber) -- cgit v1.2.3-59-g8ed1b From ce80d713e380581071e4050410fe71a4c926884d Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 14 Apr 2015 09:44:20 -0300 Subject: [media] m88ds3103: implement DVBv5 BER Implement DVBv5 BER statistics. Wrap legacy DVBv3 BER to DVBv5 BER. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/m88ds3103.c | 165 +++++++++++++++------------ drivers/media/dvb-frontends/m88ds3103_priv.h | 4 +- 2 files changed, 94 insertions(+), 75 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index 381a8ad173b5..33d8c190661e 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -305,6 +305,92 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, fe_status_t *status) c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; } + /* BER */ + if (priv->fe_status & FE_HAS_LOCK) { + unsigned int utmp, post_bit_error, post_bit_count; + + switch (c->delivery_system) { + case SYS_DVBS: + ret = m88ds3103_wr_reg(priv, 0xf9, 0x04); + if (ret) + goto err; + + ret = m88ds3103_rd_reg(priv, 0xf8, &u8tmp); + if (ret) + goto err; + + /* measurement ready? */ + if (!(u8tmp & 0x10)) { + ret = m88ds3103_rd_regs(priv, 0xf6, buf, 2); + if (ret) + goto err; + + post_bit_error = buf[1] << 8 | buf[0] << 0; + post_bit_count = 0x800000; + priv->post_bit_error += post_bit_error; + priv->post_bit_count += post_bit_count; + priv->dvbv3_ber = post_bit_error; + + /* restart measurement */ + u8tmp |= 0x10; + ret = m88ds3103_wr_reg(priv, 0xf8, u8tmp); + if (ret) + goto err; + } + break; + case SYS_DVBS2: + ret = m88ds3103_rd_regs(priv, 0xd5, buf, 3); + if (ret) + goto err; + + utmp = buf[2] << 16 | buf[1] << 8 | buf[0] << 0; + + /* enough data? */ + if (utmp > 4000) { + ret = m88ds3103_rd_regs(priv, 0xf7, buf, 2); + if (ret) + goto err; + + post_bit_error = buf[1] << 8 | buf[0] << 0; + post_bit_count = 32 * utmp; /* TODO: FEC */ + priv->post_bit_error += post_bit_error; + priv->post_bit_count += post_bit_count; + priv->dvbv3_ber = post_bit_error; + + /* restart measurement */ + ret = m88ds3103_wr_reg(priv, 0xd1, 0x01); + if (ret) + goto err; + + ret = m88ds3103_wr_reg(priv, 0xf9, 0x01); + if (ret) + goto err; + + ret = m88ds3103_wr_reg(priv, 0xf9, 0x00); + if (ret) + goto err; + + ret = m88ds3103_wr_reg(priv, 0xd1, 0x00); + if (ret) + goto err; + } + break; + default: + dev_dbg(&priv->i2c->dev, + "%s: invalid delivery_system\n", __func__); + ret = -EINVAL; + goto err; + } + + c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_error.stat[0].uvalue = priv->post_bit_error; + c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_count.stat[0].uvalue = priv->post_bit_count; + } else { + c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + } + return 0; err: dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); @@ -760,6 +846,10 @@ skip_fw_download: /* init stats here in order signal app which stats are supported */ c->cnr.len = 1; c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->post_bit_error.len = 1; + c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->post_bit_count.len = 1; + c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; return 0; error_fw_release: @@ -997,83 +1087,10 @@ static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *snr) static int m88ds3103_read_ber(struct dvb_frontend *fe, u32 *ber) { struct m88ds3103_priv *priv = fe->demodulator_priv; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int ret; - unsigned int utmp; - u8 buf[3], u8tmp; - dev_dbg(&priv->i2c->dev, "%s:\n", __func__); - - switch (c->delivery_system) { - case SYS_DVBS: - ret = m88ds3103_wr_reg(priv, 0xf9, 0x04); - if (ret) - goto err; - - ret = m88ds3103_rd_reg(priv, 0xf8, &u8tmp); - if (ret) - goto err; - - if (!(u8tmp & 0x10)) { - u8tmp |= 0x10; - - ret = m88ds3103_rd_regs(priv, 0xf6, buf, 2); - if (ret) - goto err; - - priv->ber = (buf[1] << 8) | (buf[0] << 0); - - /* restart counters */ - ret = m88ds3103_wr_reg(priv, 0xf8, u8tmp); - if (ret) - goto err; - } - break; - case SYS_DVBS2: - ret = m88ds3103_rd_regs(priv, 0xd5, buf, 3); - if (ret) - goto err; - - utmp = (buf[2] << 16) | (buf[1] << 8) | (buf[0] << 0); - - if (utmp > 3000) { - ret = m88ds3103_rd_regs(priv, 0xf7, buf, 2); - if (ret) - goto err; - - priv->ber = (buf[1] << 8) | (buf[0] << 0); - - /* restart counters */ - ret = m88ds3103_wr_reg(priv, 0xd1, 0x01); - if (ret) - goto err; - - ret = m88ds3103_wr_reg(priv, 0xf9, 0x01); - if (ret) - goto err; - - ret = m88ds3103_wr_reg(priv, 0xf9, 0x00); - if (ret) - goto err; - - ret = m88ds3103_wr_reg(priv, 0xd1, 0x00); - if (ret) - goto err; - } - break; - default: - dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n", - __func__); - ret = -EINVAL; - goto err; - } - - *ber = priv->ber; + *ber = priv->dvbv3_ber; return 0; -err: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); - return ret; } static int m88ds3103_set_tone(struct dvb_frontend *fe, diff --git a/drivers/media/dvb-frontends/m88ds3103_priv.h b/drivers/media/dvb-frontends/m88ds3103_priv.h index a2c0958111f8..78e58e3c8c24 100644 --- a/drivers/media/dvb-frontends/m88ds3103_priv.h +++ b/drivers/media/dvb-frontends/m88ds3103_priv.h @@ -38,13 +38,15 @@ struct m88ds3103_priv { struct dvb_frontend fe; fe_delivery_system_t delivery_system; fe_status_t fe_status; - u32 ber; + u32 dvbv3_ber; /* for old DVBv3 API read_ber */ bool warm; /* FW running */ struct i2c_adapter *i2c_adapter; /* auto detect chip id to do different config */ u8 chip_id; /* main mclk is calculated for M88RS6000 dynamically */ u32 mclk_khz; + u64 post_bit_error; + u64 post_bit_count; }; struct m88ds3103_reg_val { -- cgit v1.2.3-59-g8ed1b From befa0cc1da62d5e27b9001900c397c0dada9b032 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 14 Apr 2015 12:56:24 -0300 Subject: [media] m88ds3103: use jiffies when polling DiSEqC TX ready Use jiffies to set timeout for DiSEqC TX ready polling. Using jiffies is more elegant solution than looping N times with sleep. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/m88ds3103.c | 53 +++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 19 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index 33d8c190661e..e45641f2c794 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -1195,7 +1195,8 @@ static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *diseqc_cmd) { struct m88ds3103_priv *priv = fe->demodulator_priv; - int ret, i; + int ret; + unsigned long timeout; u8 u8tmp; dev_dbg(&priv->i2c->dev, "%s: msg=%*ph\n", __func__, @@ -1226,21 +1227,24 @@ static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe, if (ret) goto err; - /* DiSEqC message typical period is 54 ms */ - usleep_range(40000, 60000); - /* wait DiSEqC TX ready */ - for (i = 20, u8tmp = 1; i && u8tmp; i--) { - usleep_range(5000, 10000); + #define SEND_MASTER_CMD_TIMEOUT 120 + timeout = jiffies + msecs_to_jiffies(SEND_MASTER_CMD_TIMEOUT); + + /* DiSEqC message typical period is 54 ms */ + usleep_range(50000, 54000); + for (u8tmp = 1; !time_after(jiffies, timeout) && u8tmp;) { ret = m88ds3103_rd_reg_mask(priv, 0xa1, &u8tmp, 0x40); if (ret) goto err; } - dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i); - - if (i == 0) { + if (u8tmp == 0) { + dev_dbg(&priv->i2c->dev, "%s: diseqc tx took %u ms\n", __func__, + jiffies_to_msecs(jiffies) - + (jiffies_to_msecs(timeout) - SEND_MASTER_CMD_TIMEOUT)); + } else { dev_dbg(&priv->i2c->dev, "%s: diseqc tx timeout\n", __func__); ret = m88ds3103_wr_reg_mask(priv, 0xa1, 0x40, 0xc0); @@ -1252,7 +1256,7 @@ static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe, if (ret) goto err; - if (i == 0) { + if (u8tmp == 1) { ret = -ETIMEDOUT; goto err; } @@ -1267,7 +1271,8 @@ static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t fe_sec_mini_cmd) { struct m88ds3103_priv *priv = fe->demodulator_priv; - int ret, i; + int ret; + unsigned long timeout; u8 u8tmp, burst; dev_dbg(&priv->i2c->dev, "%s: fe_sec_mini_cmd=%d\n", __func__, @@ -1301,26 +1306,36 @@ static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe, if (ret) goto err; - /* DiSEqC ToneBurst period is 12.5 ms */ - usleep_range(11000, 20000); - /* wait DiSEqC TX ready */ - for (i = 5, u8tmp = 1; i && u8tmp; i--) { - usleep_range(800, 2000); + #define SEND_BURST_TIMEOUT 40 + timeout = jiffies + msecs_to_jiffies(SEND_BURST_TIMEOUT); + + /* DiSEqC ToneBurst period is 12.5 ms */ + usleep_range(8500, 12500); + for (u8tmp = 1; !time_after(jiffies, timeout) && u8tmp;) { ret = m88ds3103_rd_reg_mask(priv, 0xa1, &u8tmp, 0x40); if (ret) goto err; } - dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i); + if (u8tmp == 0) { + dev_dbg(&priv->i2c->dev, "%s: diseqc tx took %u ms\n", __func__, + jiffies_to_msecs(jiffies) - + (jiffies_to_msecs(timeout) - SEND_BURST_TIMEOUT)); + } else { + dev_dbg(&priv->i2c->dev, "%s: diseqc tx timeout\n", __func__); + + ret = m88ds3103_wr_reg_mask(priv, 0xa1, 0x40, 0xc0); + if (ret) + goto err; + } ret = m88ds3103_wr_reg_mask(priv, 0xa2, 0x80, 0xc0); if (ret) goto err; - if (i == 0) { - dev_dbg(&priv->i2c->dev, "%s: diseqc tx timeout\n", __func__); + if (u8tmp == 1) { ret = -ETIMEDOUT; goto err; } -- cgit v1.2.3-59-g8ed1b From f01919e8f54f645fb00fdb823fe266e21eebe3b1 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 16 Apr 2015 20:04:55 -0300 Subject: [media] m88ds3103: add I2C client binding Implement I2C client device binding. Wrap media attach to driver I2C probe. Add wrapper from m88ds3103_attach() to m88ds3103_probe() via driver core in order to provide proper I2C client for legacy media attach binding. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/m88ds3103.c | 268 +++++++++++++++++++-------- drivers/media/dvb-frontends/m88ds3103.h | 63 ++++++- drivers/media/dvb-frontends/m88ds3103_priv.h | 2 + 3 files changed, 245 insertions(+), 88 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index e45641f2c794..01b9dedff3d1 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -1357,9 +1357,9 @@ static int m88ds3103_get_tune_settings(struct dvb_frontend *fe, static void m88ds3103_release(struct dvb_frontend *fe) { struct m88ds3103_priv *priv = fe->demodulator_priv; + struct i2c_client *client = priv->client; - i2c_del_mux_adapter(priv->i2c_adapter); - kfree(priv); + i2c_unregister_device(client); } static int m88ds3103_select(struct i2c_adapter *adap, void *mux_priv, u32 chan) @@ -1401,43 +1401,158 @@ static int m88ds3103_deselect(struct i2c_adapter *adap, void *mux_priv, return 0; } +/* + * XXX: That is wrapper to m88ds3103_probe() via driver core in order to provide + * proper I2C client for legacy media attach binding. + * New users must use I2C client binding directly! + */ struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg, struct i2c_adapter *i2c, struct i2c_adapter **tuner_i2c_adapter) { + struct i2c_client *client; + struct i2c_board_info board_info; + struct m88ds3103_platform_data pdata; + + pdata.clk = cfg->clock; + pdata.i2c_wr_max = cfg->i2c_wr_max; + pdata.ts_mode = cfg->ts_mode; + pdata.ts_clk = cfg->ts_clk; + pdata.ts_clk_pol = cfg->ts_clk_pol; + pdata.spec_inv = cfg->spec_inv; + pdata.agc = cfg->agc; + pdata.agc_inv = cfg->agc_inv; + pdata.clk_out = cfg->clock_out; + pdata.envelope_mode = cfg->envelope_mode; + pdata.lnb_hv_pol = cfg->lnb_hv_pol; + pdata.lnb_en_pol = cfg->lnb_en_pol; + pdata.attach_in_use = true; + + memset(&board_info, 0, sizeof(board_info)); + strlcpy(board_info.type, "m88ds3103", I2C_NAME_SIZE); + board_info.addr = cfg->i2c_addr; + board_info.platform_data = &pdata; + client = i2c_new_device(i2c, &board_info); + if (!client || !client->dev.driver) + return NULL; + + *tuner_i2c_adapter = pdata.get_i2c_adapter(client); + return pdata.get_dvb_frontend(client); +} +EXPORT_SYMBOL(m88ds3103_attach); + +static struct dvb_frontend_ops m88ds3103_ops = { + .delsys = { SYS_DVBS, SYS_DVBS2 }, + .info = { + .name = "Montage M88DS3103", + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_tolerance = 5000, + .symbol_rate_min = 1000000, + .symbol_rate_max = 45000000, + .caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_1_2 | + FE_CAN_FEC_2_3 | + FE_CAN_FEC_3_4 | + FE_CAN_FEC_4_5 | + FE_CAN_FEC_5_6 | + FE_CAN_FEC_6_7 | + FE_CAN_FEC_7_8 | + FE_CAN_FEC_8_9 | + FE_CAN_FEC_AUTO | + FE_CAN_QPSK | + FE_CAN_RECOVER | + FE_CAN_2G_MODULATION + }, + + .release = m88ds3103_release, + + .get_tune_settings = m88ds3103_get_tune_settings, + + .init = m88ds3103_init, + .sleep = m88ds3103_sleep, + + .set_frontend = m88ds3103_set_frontend, + .get_frontend = m88ds3103_get_frontend, + + .read_status = m88ds3103_read_status, + .read_snr = m88ds3103_read_snr, + .read_ber = m88ds3103_read_ber, + + .diseqc_send_master_cmd = m88ds3103_diseqc_send_master_cmd, + .diseqc_send_burst = m88ds3103_diseqc_send_burst, + + .set_tone = m88ds3103_set_tone, + .set_voltage = m88ds3103_set_voltage, +}; + +static struct dvb_frontend *m88ds3103_get_dvb_frontend(struct i2c_client *client) +{ + struct m88ds3103_priv *dev = i2c_get_clientdata(client); + + dev_dbg(&client->dev, "\n"); + + return &dev->fe; +} + +static struct i2c_adapter *m88ds3103_get_i2c_adapter(struct i2c_client *client) +{ + struct m88ds3103_priv *dev = i2c_get_clientdata(client); + + dev_dbg(&client->dev, "\n"); + + return dev->i2c_adapter; +} + +static int m88ds3103_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct m88ds3103_priv *dev; + struct m88ds3103_platform_data *pdata = client->dev.platform_data; int ret; - struct m88ds3103_priv *priv; u8 chip_id, u8tmp; - /* allocate memory for the internal priv */ - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) { + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) { ret = -ENOMEM; - dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME); goto err; } - priv->cfg = cfg; - priv->i2c = i2c; - mutex_init(&priv->i2c_mutex); + dev->client = client; + dev->i2c = client->adapter; + dev->config.i2c_addr = client->addr; + dev->config.clock = pdata->clk; + dev->config.i2c_wr_max = pdata->i2c_wr_max; + dev->config.ts_mode = pdata->ts_mode; + dev->config.ts_clk = pdata->ts_clk; + dev->config.ts_clk_pol = pdata->ts_clk_pol; + dev->config.spec_inv = pdata->spec_inv; + dev->config.agc_inv = pdata->agc_inv; + dev->config.clock_out = pdata->clk_out; + dev->config.envelope_mode = pdata->envelope_mode; + dev->config.agc = pdata->agc; + dev->config.lnb_hv_pol = pdata->lnb_hv_pol; + dev->config.lnb_en_pol = pdata->lnb_en_pol; + dev->cfg = &dev->config; + mutex_init(&dev->i2c_mutex); /* 0x00: chip id[6:0], 0x01: chip ver[7:0], 0x02: chip ver[15:8] */ - ret = m88ds3103_rd_reg(priv, 0x00, &chip_id); + ret = m88ds3103_rd_reg(dev, 0x00, &chip_id); if (ret) - goto err; + goto err_kfree; chip_id >>= 1; - dev_info(&priv->i2c->dev, "%s: chip_id=%02x\n", __func__, chip_id); + dev_dbg(&client->dev, "chip_id=%02x\n", chip_id); switch (chip_id) { case M88RS6000_CHIP_ID: case M88DS3103_CHIP_ID: break; default: - goto err; + goto err_kfree; } - priv->chip_id = chip_id; + dev->chip_id = chip_id; - switch (priv->cfg->clock_out) { + switch (dev->cfg->clock_out) { case M88DS3103_CLOCK_OUT_DISABLED: u8tmp = 0x80; break; @@ -1448,7 +1563,7 @@ struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg, u8tmp = 0x10; break; default: - goto err; + goto err_kfree; } /* 0x29 register is defined differently for m88rs6000. */ @@ -1456,91 +1571,80 @@ struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg, if (chip_id == M88RS6000_CHIP_ID) u8tmp = 0x00; - ret = m88ds3103_wr_reg(priv, 0x29, u8tmp); + ret = m88ds3103_wr_reg(dev, 0x29, u8tmp); if (ret) - goto err; + goto err_kfree; /* sleep */ - ret = m88ds3103_wr_reg_mask(priv, 0x08, 0x00, 0x01); + ret = m88ds3103_wr_reg_mask(dev, 0x08, 0x00, 0x01); if (ret) - goto err; - - ret = m88ds3103_wr_reg_mask(priv, 0x04, 0x01, 0x01); + goto err_kfree; + ret = m88ds3103_wr_reg_mask(dev, 0x04, 0x01, 0x01); if (ret) - goto err; - - ret = m88ds3103_wr_reg_mask(priv, 0x23, 0x10, 0x10); + goto err_kfree; + ret = m88ds3103_wr_reg_mask(dev, 0x23, 0x10, 0x10); if (ret) - goto err; + goto err_kfree; /* create mux i2c adapter for tuner */ - priv->i2c_adapter = i2c_add_mux_adapter(i2c, &i2c->dev, priv, 0, 0, 0, - m88ds3103_select, m88ds3103_deselect); - if (priv->i2c_adapter == NULL) - goto err; - - *tuner_i2c_adapter = priv->i2c_adapter; + dev->i2c_adapter = i2c_add_mux_adapter(client->adapter, &client->dev, + dev, 0, 0, 0, m88ds3103_select, + m88ds3103_deselect); + if (dev->i2c_adapter == NULL) + goto err_kfree; /* create dvb_frontend */ - memcpy(&priv->fe.ops, &m88ds3103_ops, sizeof(struct dvb_frontend_ops)); - if (priv->chip_id == M88RS6000_CHIP_ID) - strncpy(priv->fe.ops.info.name, - "Montage M88RS6000", sizeof(priv->fe.ops.info.name)); - priv->fe.demodulator_priv = priv; - - return &priv->fe; + memcpy(&dev->fe.ops, &m88ds3103_ops, sizeof(struct dvb_frontend_ops)); + if (dev->chip_id == M88RS6000_CHIP_ID) + strncpy(dev->fe.ops.info.name, + "Montage M88RS6000", sizeof(dev->fe.ops.info.name)); + if (!pdata->attach_in_use) + dev->fe.ops.release = NULL; + dev->fe.demodulator_priv = dev; + i2c_set_clientdata(client, dev); + + /* setup callbacks */ + pdata->get_dvb_frontend = m88ds3103_get_dvb_frontend; + pdata->get_i2c_adapter = m88ds3103_get_i2c_adapter; + return 0; +err_kfree: + kfree(dev); err: - dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret); - kfree(priv); - return NULL; + dev_dbg(&client->dev, "failed=%d\n", ret); + return ret; } -EXPORT_SYMBOL(m88ds3103_attach); - -static struct dvb_frontend_ops m88ds3103_ops = { - .delsys = { SYS_DVBS, SYS_DVBS2 }, - .info = { - .name = "Montage M88DS3103", - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_tolerance = 5000, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | - FE_CAN_FEC_2_3 | - FE_CAN_FEC_3_4 | - FE_CAN_FEC_4_5 | - FE_CAN_FEC_5_6 | - FE_CAN_FEC_6_7 | - FE_CAN_FEC_7_8 | - FE_CAN_FEC_8_9 | - FE_CAN_FEC_AUTO | - FE_CAN_QPSK | - FE_CAN_RECOVER | - FE_CAN_2G_MODULATION - }, - .release = m88ds3103_release, +static int m88ds3103_remove(struct i2c_client *client) +{ + struct m88ds3103_priv *dev = i2c_get_clientdata(client); - .get_tune_settings = m88ds3103_get_tune_settings, + dev_dbg(&client->dev, "\n"); - .init = m88ds3103_init, - .sleep = m88ds3103_sleep, + i2c_del_mux_adapter(dev->i2c_adapter); - .set_frontend = m88ds3103_set_frontend, - .get_frontend = m88ds3103_get_frontend, - - .read_status = m88ds3103_read_status, - .read_snr = m88ds3103_read_snr, - .read_ber = m88ds3103_read_ber, + kfree(dev); + return 0; +} - .diseqc_send_master_cmd = m88ds3103_diseqc_send_master_cmd, - .diseqc_send_burst = m88ds3103_diseqc_send_burst, +static const struct i2c_device_id m88ds3103_id_table[] = { + {"m88ds3103", 0}, + {} +}; +MODULE_DEVICE_TABLE(i2c, m88ds3103_id_table); - .set_tone = m88ds3103_set_tone, - .set_voltage = m88ds3103_set_voltage, +static struct i2c_driver m88ds3103_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "m88ds3103", + .suppress_bind_attrs = true, + }, + .probe = m88ds3103_probe, + .remove = m88ds3103_remove, + .id_table = m88ds3103_id_table, }; +module_i2c_driver(m88ds3103_driver); + MODULE_AUTHOR("Antti Palosaari "); MODULE_DESCRIPTION("Montage M88DS3103 DVB-S/S2 demodulator driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb-frontends/m88ds3103.h b/drivers/media/dvb-frontends/m88ds3103.h index 9b3b4962da7c..381146840c51 100644 --- a/drivers/media/dvb-frontends/m88ds3103.h +++ b/drivers/media/dvb-frontends/m88ds3103.h @@ -19,6 +19,63 @@ #include +/* + * I2C address + * 0x68, + */ + +/** + * struct m88ds3103_platform_data - Platform data for the m88ds3103 driver + * @clk: Clock frequency. + * @i2c_wr_max: Max bytes I2C adapter can write at once. + * @ts_mode: TS mode. + * @ts_clk: TS clock (KHz). + * @ts_clk_pol: TS clk polarity. 1-active at falling edge; 0-active at rising + * edge. + * @spec_inv: Input spectrum inversion. + * @agc: AGC configuration. + * @agc_inv: AGC polarity. + * @clk_out: Clock output. + * @envelope_mode: DiSEqC envelope mode. + * @lnb_hv_pol: LNB H/V pin polarity. 0: pin high set to VOLTAGE_18, pin low to + * set VOLTAGE_13. 1: pin high set to VOLTAGE_13, pin low to set VOLTAGE_18. + * @lnb_en_pol: LNB enable pin polarity. 0: pin high to disable, pin low to + * enable. 1: pin high to enable, pin low to disable. + * @get_dvb_frontend: Get DVB frontend. + * @get_i2c_adapter: Get I2C adapter. + */ + +struct m88ds3103_platform_data { + u32 clk; + u16 i2c_wr_max; +#define M88DS3103_TS_SERIAL 0 /* TS output pin D0, normal */ +#define M88DS3103_TS_SERIAL_D7 1 /* TS output pin D7 */ +#define M88DS3103_TS_PARALLEL 2 /* TS Parallel mode */ +#define M88DS3103_TS_CI 3 /* TS CI Mode */ + u8 ts_mode:2; + u32 ts_clk; + u8 ts_clk_pol:1; + u8 spec_inv:1; + u8 agc; + u8 agc_inv:1; +#define M88DS3103_CLOCK_OUT_DISABLED 0 +#define M88DS3103_CLOCK_OUT_ENABLED 1 +#define M88DS3103_CLOCK_OUT_ENABLED_DIV2 2 + u8 clk_out:2; + u8 envelope_mode:1; + u8 lnb_hv_pol:1; + u8 lnb_en_pol:1; + + struct dvb_frontend* (*get_dvb_frontend)(struct i2c_client *); + struct i2c_adapter* (*get_i2c_adapter)(struct i2c_client *); + +/* private: For legacy media attach wrapper. Do not set value. */ + u8 attach_in_use:1; +}; + +/* + * Do not add new m88ds3103_attach() users! Use I2C bindings instead. + */ struct m88ds3103_config { /* * I2C address @@ -113,12 +170,6 @@ struct m88ds3103_config { u8 lnb_en_pol:1; }; -/* - * Driver implements own I2C-adapter for tuner I2C access. That's since chip - * has I2C-gate control which closes gate automatically after I2C transfer. - * Using own I2C adapter we can workaround that. - */ - #if defined(CONFIG_DVB_M88DS3103) || \ (defined(CONFIG_DVB_M88DS3103_MODULE) && defined(MODULE)) extern struct dvb_frontend *m88ds3103_attach( diff --git a/drivers/media/dvb-frontends/m88ds3103_priv.h b/drivers/media/dvb-frontends/m88ds3103_priv.h index 78e58e3c8c24..6217d928c23e 100644 --- a/drivers/media/dvb-frontends/m88ds3103_priv.h +++ b/drivers/media/dvb-frontends/m88ds3103_priv.h @@ -32,8 +32,10 @@ struct m88ds3103_priv { struct i2c_adapter *i2c; + struct i2c_client *client; /* mutex needed due to own tuner I2C adapter */ struct mutex i2c_mutex; + struct m88ds3103_config config; const struct m88ds3103_config *cfg; struct dvb_frontend fe; fe_delivery_system_t delivery_system; -- cgit v1.2.3-59-g8ed1b From baf06b519051047b4ca6bcaa94ee2d85672dd443 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 21 May 2015 16:47:15 -0300 Subject: [media] af9035: add USB ID 07ca:0337 AVerMedia HD Volar (A867) It is AF9035 + MxL5007T. Driver reports: prechip_version=00 chip_version=03 chip_type=3802 Not sure if that USB ID is reserved only for HP brand or if it is common, but the stick I have is branded as HP part no. 580715-001 rmn A867. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/af9035.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index be077f2fd3ab..6e02a15d39ce 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c @@ -2035,6 +2035,8 @@ static const struct usb_device_id af9035_id_table[] = { &af9035_props, "Asus U3100Mini Plus", NULL) }, { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00aa, &af9035_props, "TerraTec Cinergy T Stick (rev. 2)", NULL) }, + { DVB_USB_DEVICE(USB_VID_AVERMEDIA, 0x0337, + &af9035_props, "AVerMedia HD Volar (A867)", NULL) }, /* IT9135 devices */ { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135, -- cgit v1.2.3-59-g8ed1b From 7195f61b801104add6453e1d8a39d5c8366fc446 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 14 Apr 2015 04:19:51 -0300 Subject: [media] uvcvideo: Implement DMABUF exporter role Now that videobuf2-vmalloc supports exporting buffers, add support for the DMABUF exporter role by plugging in the videobuf2 ioctl helper. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_queue.c | 12 ++++++++++++ drivers/media/usb/uvc/uvc_v4l2.c | 13 +++++++++++++ drivers/media/usb/uvc/uvcvideo.h | 2 ++ 3 files changed, 27 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c index 87a19f33e460..f16b9b42689d 100644 --- a/drivers/media/usb/uvc/uvc_queue.c +++ b/drivers/media/usb/uvc/uvc_queue.c @@ -270,6 +270,18 @@ int uvc_queue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf) return ret; } +int uvc_export_buffer(struct uvc_video_queue *queue, + struct v4l2_exportbuffer *exp) +{ + int ret; + + mutex_lock(&queue->mutex); + ret = vb2_expbuf(&queue->queue, exp); + mutex_unlock(&queue->mutex); + + return ret; +} + int uvc_dequeue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf, int nonblocking) { diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index c4b1ac6750d8..69d01803e0aa 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -723,6 +723,18 @@ static int uvc_ioctl_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) return uvc_queue_buffer(&stream->queue, buf); } +static int uvc_ioctl_expbuf(struct file *file, void *fh, + struct v4l2_exportbuffer *exp) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + + if (!uvc_has_privileges(handle)) + return -EBUSY; + + return uvc_export_buffer(&stream->queue, exp); +} + static int uvc_ioctl_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) { struct uvc_fh *handle = fh; @@ -1478,6 +1490,7 @@ const struct v4l2_ioctl_ops uvc_ioctl_ops = { .vidioc_reqbufs = uvc_ioctl_reqbufs, .vidioc_querybuf = uvc_ioctl_querybuf, .vidioc_qbuf = uvc_ioctl_qbuf, + .vidioc_expbuf = uvc_ioctl_expbuf, .vidioc_dqbuf = uvc_ioctl_dqbuf, .vidioc_create_bufs = uvc_ioctl_create_bufs, .vidioc_streamon = uvc_ioctl_streamon, diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 1b594c203992..ead00a83df04 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -635,6 +635,8 @@ extern int uvc_create_buffers(struct uvc_video_queue *queue, struct v4l2_create_buffers *v4l2_cb); extern int uvc_queue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *v4l2_buf); +extern int uvc_export_buffer(struct uvc_video_queue *queue, + struct v4l2_exportbuffer *exp); extern int uvc_dequeue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *v4l2_buf, int nonblocking); extern int uvc_queue_streamon(struct uvc_video_queue *queue, -- cgit v1.2.3-59-g8ed1b From 37f85b276a36b531234992b05eb057841af46fb4 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 12 May 2015 18:57:53 -0300 Subject: [media] uvcvideo: Fix incorrect bandwidth with Chicony device 04f2:b50b The "TOSHIBA Web Camera - 5M" Chicony device (04f2:b50b) seems to compute the bandwidth on 16 bits and erroneously sign-extend it to 32 bits, resulting in a huge bandwidth value. Detect and fix that condition by setting the 16 MSBs to 0 when they're all equal to 1. Reported-by: Hans de Goede Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_video.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index 20ccc9d315dc..f839654ea436 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -119,6 +119,14 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream, ctrl->dwMaxVideoFrameSize = frame->dwMaxVideoFrameBufferSize; + /* The "TOSHIBA Web Camera - 5M" Chicony device (04f2:b50b) seems to + * compute the bandwidth on 16 bits and erroneously sign-extend it to + * 32 bits, resulting in a huge bandwidth value. Detect and fix that + * condition by setting the 16 MSBs to 0 when they're all equal to 1. + */ + if ((ctrl->dwMaxPayloadTransferSize & 0xffff0000) == 0xffff0000) + ctrl->dwMaxPayloadTransferSize &= ~0xffff0000; + if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) && stream->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH && stream->intf->num_altsetting > 1) { -- cgit v1.2.3-59-g8ed1b From d511eb7d642aaf513fefeb05514dc6177c53c350 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 24 May 2015 19:45:38 -0300 Subject: [media] uvcvideo: Remove unneeded device disconnected flag The UVC_DEV_DISCONNECTED flag is set when the USB device is disconnected, and checked in the open() handler to refuse opening a device that has been disconnected. This is inherently racy, but the race condition is taken care of in the V4L2 core, which also fails open() calls when the V4L2 device node has been unregistered. As the uvcvideo USB disconnect handler unregisters all its video device nodes, the UVC_DEV_DISCONNECTED flag doesn't serve any purpose anymore and can be removed. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_driver.c | 2 -- drivers/media/usb/uvc/uvc_v4l2.c | 3 --- drivers/media/usb/uvc/uvcvideo.h | 5 ----- 3 files changed, 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 5970dd6a1c1c..4b5b3e8fb7d3 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -1967,8 +1967,6 @@ static void uvc_disconnect(struct usb_interface *intf) UVC_SC_VIDEOSTREAMING) return; - dev->state |= UVC_DEV_DISCONNECTED; - uvc_unregister_video(dev); } diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index 69d01803e0aa..2764f43607c1 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -483,9 +483,6 @@ static int uvc_v4l2_open(struct file *file) uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n"); stream = video_drvdata(file); - if (stream->dev->state & UVC_DEV_DISCONNECTED) - return -ENODEV; - ret = usb_autopm_get_interface(stream->dev->intf); if (ret < 0) return ret; diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index ead00a83df04..816dd1a0fd81 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -517,10 +517,6 @@ struct uvc_streaming { } clock; }; -enum uvc_device_state { - UVC_DEV_DISCONNECTED = 1, -}; - struct uvc_device { struct usb_device *udev; struct usb_interface *intf; @@ -529,7 +525,6 @@ struct uvc_device { int intfnum; char name[32]; - enum uvc_device_state state; struct mutex lock; /* Protects users */ unsigned int users; atomic_t nmappings; -- cgit v1.2.3-59-g8ed1b From d2b72f6482b9a3c57f036c11786a2489dcc81176 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Fri, 29 May 2015 16:42:33 -0300 Subject: [media] si2168: Implement own I2C adapter locking We need own I2C locking because of tuner I2C adapter/repeater. Firmware command is executed using I2C send + reply message. Default I2C adapter locking protects only single I2C operation, not whole send + reply sequence as needed. Due to that, it was possible tuner I2C message interrupts firmware command sequence. Reported-by: Adam Baker Signed-off-by: Antti Palosaari Reviewed-by: Adam Baker Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/si2168.c | 135 +++++++++++++++++------------- drivers/media/dvb-frontends/si2168_priv.h | 1 - 2 files changed, 79 insertions(+), 57 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c index b68ab346b93b..d6a4cb0688c3 100644 --- a/drivers/media/dvb-frontends/si2168.c +++ b/drivers/media/dvb-frontends/si2168.c @@ -18,23 +18,53 @@ static const struct dvb_frontend_ops si2168_ops; +/* Own I2C adapter locking is needed because of I2C gate logic. */ +static int si2168_i2c_master_send_unlocked(const struct i2c_client *client, + const char *buf, int count) +{ + int ret; + struct i2c_msg msg = { + .addr = client->addr, + .flags = 0, + .len = count, + .buf = (char *)buf, + }; + + ret = __i2c_transfer(client->adapter, &msg, 1); + return (ret == 1) ? count : ret; +} + +static int si2168_i2c_master_recv_unlocked(const struct i2c_client *client, + char *buf, int count) +{ + int ret; + struct i2c_msg msg = { + .addr = client->addr, + .flags = I2C_M_RD, + .len = count, + .buf = buf, + }; + + ret = __i2c_transfer(client->adapter, &msg, 1); + return (ret == 1) ? count : ret; +} + /* execute firmware command */ -static int si2168_cmd_execute(struct i2c_client *client, struct si2168_cmd *cmd) +static int si2168_cmd_execute_unlocked(struct i2c_client *client, + struct si2168_cmd *cmd) { - struct si2168_dev *dev = i2c_get_clientdata(client); int ret; unsigned long timeout; - mutex_lock(&dev->i2c_mutex); - if (cmd->wlen) { /* write cmd and args for firmware */ - ret = i2c_master_send(client, cmd->args, cmd->wlen); + ret = si2168_i2c_master_send_unlocked(client, cmd->args, + cmd->wlen); if (ret < 0) { - goto err_mutex_unlock; + goto err; } else if (ret != cmd->wlen) { ret = -EREMOTEIO; - goto err_mutex_unlock; + goto err; } } @@ -43,12 +73,13 @@ static int si2168_cmd_execute(struct i2c_client *client, struct si2168_cmd *cmd) #define TIMEOUT 70 timeout = jiffies + msecs_to_jiffies(TIMEOUT); while (!time_after(jiffies, timeout)) { - ret = i2c_master_recv(client, cmd->args, cmd->rlen); + ret = si2168_i2c_master_recv_unlocked(client, cmd->args, + cmd->rlen); if (ret < 0) { - goto err_mutex_unlock; + goto err; } else if (ret != cmd->rlen) { ret = -EREMOTEIO; - goto err_mutex_unlock; + goto err; } /* firmware ready? */ @@ -63,24 +94,32 @@ static int si2168_cmd_execute(struct i2c_client *client, struct si2168_cmd *cmd) /* error bit set? */ if ((cmd->args[0] >> 6) & 0x01) { ret = -EREMOTEIO; - goto err_mutex_unlock; + goto err; } if (!((cmd->args[0] >> 7) & 0x01)) { ret = -ETIMEDOUT; - goto err_mutex_unlock; + goto err; } } - mutex_unlock(&dev->i2c_mutex); return 0; - -err_mutex_unlock: - mutex_unlock(&dev->i2c_mutex); +err: dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } +static int si2168_cmd_execute(struct i2c_client *client, struct si2168_cmd *cmd) +{ + int ret; + + i2c_lock_adapter(client->adapter); + ret = si2168_cmd_execute_unlocked(client, cmd); + i2c_unlock_adapter(client->adapter); + + return ret; +} + static int si2168_read_status(struct dvb_frontend *fe, fe_status_t *status) { struct i2c_client *client = fe->demodulator_priv; @@ -569,60 +608,46 @@ static int si2168_get_tune_settings(struct dvb_frontend *fe, /* * I2C gate logic - * We must use unlocked i2c_transfer() here because I2C lock is already taken - * by tuner driver. + * We must use unlocked I2C I/O because I2C adapter lock is already taken + * by the caller (usually tuner driver). */ static int si2168_select(struct i2c_adapter *adap, void *mux_priv, u32 chan) { struct i2c_client *client = mux_priv; - struct si2168_dev *dev = i2c_get_clientdata(client); int ret; - struct i2c_msg gate_open_msg = { - .addr = client->addr, - .flags = 0, - .len = 3, - .buf = "\xc0\x0d\x01", - }; - - mutex_lock(&dev->i2c_mutex); + struct si2168_cmd cmd; - /* open tuner I2C gate */ - ret = __i2c_transfer(client->adapter, &gate_open_msg, 1); - if (ret != 1) { - dev_warn(&client->dev, "i2c write failed=%d\n", ret); - if (ret >= 0) - ret = -EREMOTEIO; - } else { - ret = 0; - } + /* open I2C gate */ + memcpy(cmd.args, "\xc0\x0d\x01", 3); + cmd.wlen = 3; + cmd.rlen = 0; + ret = si2168_cmd_execute_unlocked(client, &cmd); + if (ret) + goto err; + return 0; +err: + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int si2168_deselect(struct i2c_adapter *adap, void *mux_priv, u32 chan) { struct i2c_client *client = mux_priv; - struct si2168_dev *dev = i2c_get_clientdata(client); int ret; - struct i2c_msg gate_close_msg = { - .addr = client->addr, - .flags = 0, - .len = 3, - .buf = "\xc0\x0d\x00", - }; - - /* close tuner I2C gate */ - ret = __i2c_transfer(client->adapter, &gate_close_msg, 1); - if (ret != 1) { - dev_warn(&client->dev, "i2c write failed=%d\n", ret); - if (ret >= 0) - ret = -EREMOTEIO; - } else { - ret = 0; - } + struct si2168_cmd cmd; - mutex_unlock(&dev->i2c_mutex); + /* close I2C gate */ + memcpy(cmd.args, "\xc0\x0d\x00", 3); + cmd.wlen = 3; + cmd.rlen = 0; + ret = si2168_cmd_execute_unlocked(client, &cmd); + if (ret) + goto err; + return 0; +err: + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } @@ -679,8 +704,6 @@ static int si2168_probe(struct i2c_client *client, goto err; } - mutex_init(&dev->i2c_mutex); - /* create mux i2c adapter for tuner */ dev->adapter = i2c_add_mux_adapter(client->adapter, &client->dev, client, 0, 0, 0, si2168_select, si2168_deselect); diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h index d2589e3d2ff2..90b6b6eace24 100644 --- a/drivers/media/dvb-frontends/si2168_priv.h +++ b/drivers/media/dvb-frontends/si2168_priv.h @@ -30,7 +30,6 @@ /* state struct */ struct si2168_dev { struct i2c_adapter *adapter; - struct mutex i2c_mutex; struct dvb_frontend fe; fe_delivery_system_t delivery_system; fe_status_t fe_status; -- cgit v1.2.3-59-g8ed1b From 2f1ea29fca781b8e6600f3ece1f2dd98ae276294 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 7 Sep 2014 11:20:34 -0300 Subject: [media] si2157: implement signal strength stats Implement DVBv5 signal strength stats. Returns dBm. Signed-off-by: Antti Palosaari Tested-by: Adam Baker Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/si2157.c | 40 +++++++++++++++++++++++++++++++++++++- drivers/media/tuners/si2157_priv.h | 1 + 2 files changed, 40 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c index cdaf68781a2e..a6245ef379c4 100644 --- a/drivers/media/tuners/si2157.c +++ b/drivers/media/tuners/si2157.c @@ -79,6 +79,7 @@ static int si2157_init(struct dvb_frontend *fe) { struct i2c_client *client = fe->tuner_priv; struct si2157_dev *dev = i2c_get_clientdata(client); + struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, len, remaining; struct si2157_cmd cmd; const struct firmware *fw; @@ -201,9 +202,14 @@ skip_fw_download: dev->fw_loaded = true; warm: + /* init statistics in order signal app which are supported */ + c->strength.len = 1; + c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + /* start statistics polling */ + schedule_delayed_work(&dev->stat_work, msecs_to_jiffies(1000)); + dev->active = true; return 0; - err_release_firmware: release_firmware(fw); err: @@ -222,6 +228,9 @@ static int si2157_sleep(struct dvb_frontend *fe) dev->active = false; + /* stop statistics polling */ + cancel_delayed_work_sync(&dev->stat_work); + /* standby */ memcpy(cmd.args, "\x16\x00", 2); cmd.wlen = 2; @@ -360,6 +369,34 @@ static const struct dvb_tuner_ops si2157_ops = { .get_if_frequency = si2157_get_if_frequency, }; +static void si2157_stat_work(struct work_struct *work) +{ + struct si2157_dev *dev = container_of(work, struct si2157_dev, stat_work.work); + struct dvb_frontend *fe = dev->fe; + struct i2c_client *client = fe->tuner_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct si2157_cmd cmd; + int ret; + + dev_dbg(&client->dev, "\n"); + + memcpy(cmd.args, "\x42\x00", 2); + cmd.wlen = 2; + cmd.rlen = 12; + ret = si2157_cmd_execute(client, &cmd); + if (ret) + goto err; + + c->strength.stat[0].scale = FE_SCALE_DECIBEL; + c->strength.stat[0].svalue = (s8) cmd.args[3] * 1000; + + schedule_delayed_work(&dev->stat_work, msecs_to_jiffies(2000)); + return; +err: + c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + dev_dbg(&client->dev, "failed=%d\n", ret); +} + static int si2157_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -384,6 +421,7 @@ static int si2157_probe(struct i2c_client *client, dev->chiptype = (u8)id->driver_data; dev->if_frequency = 5000000; /* default value of property 0x0706 */ mutex_init(&dev->i2c_mutex); + INIT_DELAYED_WORK(&dev->stat_work, si2157_stat_work); /* check if the tuner is there */ cmd.wlen = 0; diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h index 71a5f8c389de..ecc463db8f69 100644 --- a/drivers/media/tuners/si2157_priv.h +++ b/drivers/media/tuners/si2157_priv.h @@ -30,6 +30,7 @@ struct si2157_dev { u8 chiptype; u8 if_port; u32 if_frequency; + struct delayed_work stat_work; }; #define SI2157_CHIPTYPE_SI2157 0 -- cgit v1.2.3-59-g8ed1b From e9763995e71020c55ec877da4f3444abc47e9ce2 Mon Sep 17 00:00:00 2001 From: "Lad, Prabhakar" Date: Tue, 26 May 2015 11:20:27 -0300 Subject: [media] media: davinci: vpbe: use v4l2_get_timestamp() this patch makes use of helper function v4l2_get_timestamp() to set the timestamp of vb2 buffer. Signed-off-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe_display.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index c4ab46f5bd92..f69cdd7da10c 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -71,15 +71,10 @@ static int venc_is_second_field(struct vpbe_display *disp_dev) static void vpbe_isr_even_field(struct vpbe_display *disp_obj, struct vpbe_layer *layer) { - struct timespec timevalue; - if (layer->cur_frm == layer->next_frm) return; - ktime_get_ts(&timevalue); - layer->cur_frm->vb.v4l2_buf.timestamp.tv_sec = - timevalue.tv_sec; - layer->cur_frm->vb.v4l2_buf.timestamp.tv_usec = - timevalue.tv_nsec / NSEC_PER_USEC; + + v4l2_get_timestamp(&layer->cur_frm->vb.v4l2_buf.timestamp); vb2_buffer_done(&layer->cur_frm->vb, VB2_BUF_STATE_DONE); /* Make cur_frm pointing to next_frm */ layer->cur_frm = layer->next_frm; -- cgit v1.2.3-59-g8ed1b From 1d03deff82671ae2c6a7ce9e75b69e5e334c0d04 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 28 May 2015 08:11:47 -0300 Subject: [media] media: s5p-mfc: fix sparse warnings Commits a0f10c131cc49d7d84394beb7903e1f246331224 and 6c9fe765360efa97c63b89af685b620baf5e0012 ("media: s5p-mfc: fix broken pointer cast on 64bit arch") fixed issue with lossy cast on 64-bit architectures. However it also removed __iomem attribute from that cast. This leads to sparse warnings. This patch fixes those warnings by adding __iomem cast in case of v6+ code version and replacing readl/writel by simple u32 load/store operations in case of v5 code (which is called on system memory allocated by dma_alloc_coherent() instead of io registers). Reported-by: Hans Verkuil Signed-off-by: Marek Szyprowski Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c | 4 ++-- drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c index c7adc3d26792..9a923b1a9bac 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c @@ -263,7 +263,7 @@ static void s5p_mfc_release_dev_context_buffer_v5(struct s5p_mfc_dev *dev) static void s5p_mfc_write_info_v5(struct s5p_mfc_ctx *ctx, unsigned int data, unsigned int ofs) { - writel(data, (void *)(ctx->shm.virt + ofs)); + *(u32 *)(ctx->shm.virt + ofs) = data; wmb(); } @@ -271,7 +271,7 @@ static unsigned int s5p_mfc_read_info_v5(struct s5p_mfc_ctx *ctx, unsigned long ofs) { rmb(); - return readl((void *)(ctx->shm.virt + ofs)); + return *(u32 *)(ctx->shm.virt + ofs); } static void s5p_mfc_dec_calc_dpb_size_v5(struct s5p_mfc_ctx *ctx) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c index cefad184fe96..12497f5ed8e9 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c @@ -1852,7 +1852,7 @@ static void s5p_mfc_write_info_v6(struct s5p_mfc_ctx *ctx, unsigned int data, unsigned int ofs) { s5p_mfc_clock_on(); - writel(data, (void *)((unsigned long)ofs)); + writel(data, (void __iomem *)((unsigned long)ofs)); s5p_mfc_clock_off(); } @@ -1862,7 +1862,7 @@ s5p_mfc_read_info_v6(struct s5p_mfc_ctx *ctx, unsigned long ofs) int ret; s5p_mfc_clock_on(); - ret = readl((void *)ofs); + ret = readl((void __iomem *)ofs); s5p_mfc_clock_off(); return ret; -- cgit v1.2.3-59-g8ed1b From 84cb7be43cec12868e94163c99fdc34c0297c3b8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 5 Jun 2015 07:24:22 -0300 Subject: [media] vivid: don't use more than 1024 bytes of stack Remove the following compilation warnings: drivers/media/platform/vivid/vivid-tpg.c: In function 'tpg_gen_text': drivers/media/platform/vivid/vivid-tpg.c:1562:1: warning: the frame size of 1308 bytes is larger than 1024 bytes [-Wframe-larger-than=] } ^ This seems to be due to some bad optimization done by gcc. Moving the for() loop to happen inside the macro solves the issue. While here, fix CodingStyle at the switch(). Signed-off-by: Mauro Carvalho Chehab Acked-by: Hans Verkuil --- drivers/media/platform/vivid/vivid-tpg.c | 33 ++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/vivid/vivid-tpg.c b/drivers/media/platform/vivid/vivid-tpg.c index b1147f2df26c..7a3ed580626a 100644 --- a/drivers/media/platform/vivid/vivid-tpg.c +++ b/drivers/media/platform/vivid/vivid-tpg.c @@ -1492,12 +1492,10 @@ void tpg_gen_text(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2], else if (tpg->field == V4L2_FIELD_SEQ_TB || tpg->field == V4L2_FIELD_SEQ_BT) div = 2; - for (p = 0; p < tpg->planes; p++) { - unsigned vdiv = tpg->vdownsampling[p]; - unsigned hdiv = tpg->hdownsampling[p]; - - /* Print text */ -#define PRINTSTR(PIXTYPE) do { \ + /* Print text */ +#define PRINTSTR(PIXTYPE) for (p = 0; p < tpg->planes; p++) { \ + unsigned vdiv = tpg->vdownsampling[p]; \ + unsigned hdiv = tpg->hdownsampling[p]; \ PIXTYPE fg; \ PIXTYPE bg; \ memcpy(&fg, tpg->textfg[p], sizeof(PIXTYPE)); \ @@ -1548,16 +1546,19 @@ void tpg_gen_text(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2], } \ } while (0) - switch (tpg->twopixelsize[p]) { - case 2: - PRINTSTR(u8); break; - case 4: - PRINTSTR(u16); break; - case 6: - PRINTSTR(x24); break; - case 8: - PRINTSTR(u32); break; - } + switch (tpg->twopixelsize[p]) { + case 2: + PRINTSTR(u8); + break; + case 4: + PRINTSTR(u16); + break; + case 6: + PRINTSTR(x24); + break; + case 8: + PRINTSTR(u32); + break; } } -- cgit v1.2.3-59-g8ed1b From 2f60f13c14b45b311843d2ca09b5e3ef94c16f71 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 5 Jun 2015 07:58:52 -0300 Subject: [media] drxk: better handle errors As reported by smatch: drivers/media/dvb-frontends/drxk_hard.c:3277 dvbt_sc_command() warn: missing break? reassigning 'status' This is basically because the error handling logic there was crappy. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/drxk_hard.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c index ad35264a3819..b1fc4bd44a2b 100644 --- a/drivers/media/dvb-frontends/drxk_hard.c +++ b/drivers/media/dvb-frontends/drxk_hard.c @@ -3262,6 +3262,7 @@ static int dvbt_sc_command(struct drxk_state *state, } /* Write needed parameters and the command */ + status = 0; switch (cmd) { /* All commands using 5 parameters */ /* All commands using 4 parameters */ @@ -3270,16 +3271,16 @@ static int dvbt_sc_command(struct drxk_state *state, case OFDM_SC_RA_RAM_CMD_PROC_START: case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM: case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM: - status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1); + status |= write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1); /* All commands using 1 parameters */ case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING: case OFDM_SC_RA_RAM_CMD_USER_IO: - status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0); + status |= write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0); /* All commands using 0 parameters */ case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM: case OFDM_SC_RA_RAM_CMD_NULL: /* Write command */ - status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd); + status |= write16(state, OFDM_SC_RA_RAM_CMD__A, cmd); break; default: /* Unknown command */ -- cgit v1.2.3-59-g8ed1b From 7fdc5561ca705dbecdabbcc33165c73330e4d13b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 5 Jun 2015 08:03:01 -0300 Subject: [media] em28xx: remove dead code As reported by smatch: drivers/media/usb/em28xx/em28xx-video.c:842 get_ressource() info: ignoring unreachable code. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-video.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 14eba9c65de3..4397ce5e78df 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -839,7 +839,6 @@ static int get_ressource(enum v4l2_buf_type f_type) return EM28XX_RESOURCE_VBI; default: BUG(); - return 0; } } -- cgit v1.2.3-59-g8ed1b From 5ac417efe66ddd7cd70a98f7f4e32a14ae40a651 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 5 Jun 2015 08:07:19 -0300 Subject: [media] sh_vou: avoid going past arrays Smatch reports two issues: drivers/media/platform/sh_vou.c:670 vou_adjust_output() error: buffer overflow 'vou_scale_v_num' 3 <= 4 drivers/media/platform/sh_vou.c:670 vou_adjust_output() error: buffer overflow 'vou_scale_v_den' 3 <= 4 It seems that there's actually a bug here: the same var (idx) is used as an index for vertical and horizontal scaling arrays. However, there are 4 elements on the h arrays, and only 3 at the v ones. On the first loop, it may select index 4 for the horizontal array. In this case, if the second loop fails to select an index, the code would keep using 4 for the vertical array, with is past of the array sizes. The intent here seems to use index 0, if the scale is not found. So, use a separate var for the vertical index. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sh_vou.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c index 829e85c26610..8b799bae01b8 100644 --- a/drivers/media/platform/sh_vou.c +++ b/drivers/media/platform/sh_vou.c @@ -600,7 +600,7 @@ static void vou_adjust_output(struct sh_vou_geometry *geo, v4l2_std_id std) { unsigned int best_err = UINT_MAX, best = geo->in_width, width_max, height_max, img_height_max; - int i, idx = 0; + int i, idx_h = 0, idx_v = 0; if (std & V4L2_STD_525_60) { width_max = 858; @@ -625,7 +625,7 @@ static void vou_adjust_output(struct sh_vou_geometry *geo, v4l2_std_id std) err = abs(found - geo->output.width); if (err < best_err) { best_err = err; - idx = i; + idx_h = i; best = found; } if (!err) @@ -633,12 +633,12 @@ static void vou_adjust_output(struct sh_vou_geometry *geo, v4l2_std_id std) } geo->output.width = best; - geo->scale_idx_h = idx; + geo->scale_idx_h = idx_h; if (geo->output.left + best > width_max) geo->output.left = width_max - best; pr_debug("%s(): W %u * %u/%u = %u\n", __func__, geo->in_width, - vou_scale_h_num[idx], vou_scale_h_den[idx], best); + vou_scale_h_num[idx_h], vou_scale_h_den[idx_h], best); best_err = UINT_MAX; @@ -655,7 +655,7 @@ static void vou_adjust_output(struct sh_vou_geometry *geo, v4l2_std_id std) err = abs(found - geo->output.height); if (err < best_err) { best_err = err; - idx = i; + idx_v = i; best = found; } if (!err) @@ -663,12 +663,12 @@ static void vou_adjust_output(struct sh_vou_geometry *geo, v4l2_std_id std) } geo->output.height = best; - geo->scale_idx_v = idx; + geo->scale_idx_v = idx_v; if (geo->output.top + best > height_max) geo->output.top = height_max - best; pr_debug("%s(): H %u * %u/%u = %u\n", __func__, geo->in_height, - vou_scale_v_num[idx], vou_scale_v_den[idx], best); + vou_scale_v_num[idx_v], vou_scale_v_den[idx_v], best); } static int sh_vou_s_fmt_vid_out(struct file *file, void *priv, -- cgit v1.2.3-59-g8ed1b From 91aff0c5d90fe57b81e2295437affc34d205a2d2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 5 Jun 2015 08:27:18 -0300 Subject: [media] dib0090: Remove a dead code As reported by smatch: drivers/media/dvb-frontends/dib0090.c:1710 dib0090_dc_offset_calibration() warn: missing break? reassigning '*tune_state' There's no need to change tune_state there, as the fall though code will change it again to another state. So, simplify it by removing the dead code. While here, fix a typo: Sart => Start Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dib0090.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/dib0090.c b/drivers/media/dvb-frontends/dib0090.c index 68e2af2650d3..47cb72243b9d 100644 --- a/drivers/media/dvb-frontends/dib0090.c +++ b/drivers/media/dvb-frontends/dib0090.c @@ -1696,12 +1696,10 @@ static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum front if (state->identity.p1g) state->dc = dc_p1g_table; - *tune_state = CT_TUNER_STEP_0; /* fall through */ - case CT_TUNER_STEP_0: - dprintk("Sart/continue DC calibration for %s path", (state->dc->i == 1) ? "I" : "Q"); + dprintk("Start/continue DC calibration for %s path", (state->dc->i == 1) ? "I" : "Q"); dib0090_write_reg(state, 0x01, state->dc->bb1); dib0090_write_reg(state, 0x07, state->bb7 | (state->dc->i << 7)); -- cgit v1.2.3-59-g8ed1b From c65171cf6fb1f9b525ea281b2297a4753c3a049d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 5 Jun 2015 08:35:09 -0300 Subject: [media] bt8xx: remove needless check As reported by smatch: drivers/media/pci/bt8xx/dst_ca.c:323 ca_get_message() warn: this array is probably non-NULL. 'p_ca_message->msg' drivers/media/pci/bt8xx/dst_ca.c:498 ca_send_message() warn: this array is probably non-NULL. 'p_ca_message->msg' Those two checks are needless/useless, as the ca_msg struct is declared as: typedef struct ca_msg { unsigned int index; unsigned int type; unsigned int length; unsigned char msg[256]; } ca_msg_t; So, if the p_ca_message pointer is not null, msg will also be not null. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/dst_ca.c | 138 +++++++++++++++++++-------------------- 1 file changed, 67 insertions(+), 71 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/bt8xx/dst_ca.c b/drivers/media/pci/bt8xx/dst_ca.c index c22c4ae06844..c5cc14ef8347 100644 --- a/drivers/media/pci/bt8xx/dst_ca.c +++ b/drivers/media/pci/bt8xx/dst_ca.c @@ -320,29 +320,27 @@ static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, if (copy_from_user(p_ca_message, arg, sizeof (struct ca_msg))) return -EFAULT; - if (p_ca_message->msg) { - dprintk(verbose, DST_CA_NOTICE, 1, " Message = [%*ph]", - 3, p_ca_message->msg); - - for (i = 0; i < 3; i++) { - command = command | p_ca_message->msg[i]; - if (i < 2) - command = command << 8; - } - dprintk(verbose, DST_CA_NOTICE, 1, " Command=[0x%x]", command); + dprintk(verbose, DST_CA_NOTICE, 1, " Message = [%*ph]", + 3, p_ca_message->msg); - switch (command) { - case CA_APP_INFO: - memcpy(p_ca_message->msg, state->messages, 128); - if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) ) - return -EFAULT; - break; - case CA_INFO: - memcpy(p_ca_message->msg, state->messages, 128); - if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) ) - return -EFAULT; - break; - } + for (i = 0; i < 3; i++) { + command = command | p_ca_message->msg[i]; + if (i < 2) + command = command << 8; + } + dprintk(verbose, DST_CA_NOTICE, 1, " Command=[0x%x]", command); + + switch (command) { + case CA_APP_INFO: + memcpy(p_ca_message->msg, state->messages, 128); + if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) ) + return -EFAULT; + break; + case CA_INFO: + memcpy(p_ca_message->msg, state->messages, 128); + if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) ) + return -EFAULT; + break; } return 0; @@ -494,60 +492,58 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, goto free_mem_and_exit; } + /* EN50221 tag */ + command = 0; - if (p_ca_message->msg) { - /* EN50221 tag */ - command = 0; + for (i = 0; i < 3; i++) { + command = command | p_ca_message->msg[i]; + if (i < 2) + command = command << 8; + } + dprintk(verbose, DST_CA_DEBUG, 1, " Command=[0x%x]\n", command); - for (i = 0; i < 3; i++) { - command = command | p_ca_message->msg[i]; - if (i < 2) - command = command << 8; + switch (command) { + case CA_PMT: + dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT"); + if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started + dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !"); + result = -1; + goto free_mem_and_exit; } - dprintk(verbose, DST_CA_DEBUG, 1, " Command=[0x%x]\n", command); - - switch (command) { - case CA_PMT: - dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT"); - if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started - dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !"); - result = -1; - goto free_mem_and_exit; - } - dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !"); - break; - case CA_PMT_REPLY: - dprintk(verbose, DST_CA_INFO, 1, "Command = CA_PMT_REPLY"); - /* Have to handle the 2 basic types of cards here */ - if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !"); - result = -1; - goto free_mem_and_exit; - } - dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !"); - break; - case CA_APP_INFO_ENQUIRY: // only for debugging - dprintk(verbose, DST_CA_INFO, 1, " Getting Cam Application information"); - - if ((ca_get_app_info(state)) < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !"); - result = -1; - goto free_mem_and_exit; - } - dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !"); - break; - case CA_INFO_ENQUIRY: - dprintk(verbose, DST_CA_INFO, 1, " Getting CA Information"); - - if ((ca_get_ca_info(state)) < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " -->CA_INFO_ENQUIRY Failed !"); - result = -1; - goto free_mem_and_exit; - } - dprintk(verbose, DST_CA_INFO, 1, " -->CA_INFO_ENQUIRY Success !"); - break; + dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !"); + break; + case CA_PMT_REPLY: + dprintk(verbose, DST_CA_INFO, 1, "Command = CA_PMT_REPLY"); + /* Have to handle the 2 basic types of cards here */ + if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) { + dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !"); + result = -1; + goto free_mem_and_exit; + } + dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !"); + break; + case CA_APP_INFO_ENQUIRY: // only for debugging + dprintk(verbose, DST_CA_INFO, 1, " Getting Cam Application information"); + + if ((ca_get_app_info(state)) < 0) { + dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !"); + result = -1; + goto free_mem_and_exit; } + dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !"); + break; + case CA_INFO_ENQUIRY: + dprintk(verbose, DST_CA_INFO, 1, " Getting CA Information"); + + if ((ca_get_ca_info(state)) < 0) { + dprintk(verbose, DST_CA_ERROR, 1, " -->CA_INFO_ENQUIRY Failed !"); + result = -1; + goto free_mem_and_exit; + } + dprintk(verbose, DST_CA_INFO, 1, " -->CA_INFO_ENQUIRY Success !"); + break; } + free_mem_and_exit: kfree (hw_buffer); -- cgit v1.2.3-59-g8ed1b From 5cbe9f3acffb9fd16391b5abf16f947c7d7833da Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 5 Jun 2015 09:08:09 -0300 Subject: [media] ivtv: fix two smatch warnings Smatch currently produces two warnings: drivers/media/pci/ivtv/ivtv-fileops.c:901 ivtv_v4l2_close() warn: suspicious bitop condition drivers/media/pci/ivtv/ivtv-fileops.c:1026 ivtv_open() warn: suspicious bitop condition Those are false positives, but it is not hard to get rid of them by using a different way to evaluate the macro, splitting the logical boolean evaluation from the bitmap one. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ivtv/ivtv-driver.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/ivtv/ivtv-driver.h b/drivers/media/pci/ivtv/ivtv-driver.h index e8b6c7ad2ba9..ee0ef6e48c7d 100644 --- a/drivers/media/pci/ivtv/ivtv-driver.h +++ b/drivers/media/pci/ivtv/ivtv-driver.h @@ -830,7 +830,8 @@ static inline int ivtv_raw_vbi(const struct ivtv *itv) do { \ struct v4l2_subdev *__sd; \ __v4l2_device_call_subdevs_p(&(itv)->v4l2_dev, __sd, \ - !(hw) || (__sd->grp_id & (hw)), o, f , ##args); \ + !(hw) ? true : (__sd->grp_id & (hw)), \ + o, f, ##args); \ } while (0) #define ivtv_call_all(itv, o, f, args...) ivtv_call_hw(itv, 0, o, f , ##args) -- cgit v1.2.3-59-g8ed1b From 485bdbb6b83309505654379153d55746d5996917 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 5 Jun 2015 09:33:44 -0300 Subject: [media] tm6000: remove needless check Smatch reports a warning: drivers/media/usb/tm6000/tm6000-video.c:646 tm6000_prepare_isoc() error: we previously assumed 'dev->urb_buffer' could be null (see line 624) This is not really a problem, but it actually shows that the check if urb_buffer is NULL is being done twice: at the if and at tm6000_alloc_urb_buffers(). We don't need to do it twice. So, remove the extra check. The code become cleaner, and, as a collateral effect, smatch becomes happy. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/tm6000/tm6000-video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c index 77ce9efe1f24..5287d2960282 100644 --- a/drivers/media/usb/tm6000/tm6000-video.c +++ b/drivers/media/usb/tm6000/tm6000-video.c @@ -621,7 +621,7 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev) dev->isoc_in.maxsize, size); - if (!dev->urb_buffer && tm6000_alloc_urb_buffers(dev) < 0) { + if (tm6000_alloc_urb_buffers(dev) < 0) { tm6000_err("cannot allocate memory for urb buffers\n"); /* call free, as some buffers might have been allocated */ -- cgit v1.2.3-59-g8ed1b From 95cf60aa55d5395a10d0e67a711e42693b89fb1c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 5 Jun 2015 10:25:24 -0300 Subject: [media] ir: Fix IR_MAX_DURATION enforcement Don't assume that IR_MAX_DURATION is a bitmask. It isn't. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/redrat3.c | 5 +++-- drivers/media/rc/streamzap.c | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index c83292ad1b34..ec74244a3853 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -322,7 +322,7 @@ static u32 redrat3_us_to_len(u32 microsec) u32 result; u32 divisor; - microsec &= IR_MAX_DURATION; + microsec = (microsec > IR_MAX_DURATION) ? IR_MAX_DURATION : microsec; divisor = (RR3_CLK_CONV_FACTOR / 1000); result = (u32)(microsec * divisor) / 1000; @@ -380,7 +380,8 @@ static void redrat3_process_ir_data(struct redrat3_dev *rr3) if (i == 0) trailer = rawir.duration; /* cap the value to IR_MAX_DURATION */ - rawir.duration &= IR_MAX_DURATION; + rawir.duration = (rawir.duration > IR_MAX_DURATION) ? + IR_MAX_DURATION : rawir.duration; dev_dbg(dev, "storing %s with duration %d (i: %d)\n", rawir.pulse ? "pulse" : "space", rawir.duration, i); diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c index bf4a44272f0e..5a17cb88ff27 100644 --- a/drivers/media/rc/streamzap.c +++ b/drivers/media/rc/streamzap.c @@ -152,7 +152,8 @@ static void sz_push_full_pulse(struct streamzap_ir *sz, sz->signal_last.tv_usec); rawir.duration -= sz->sum; rawir.duration = US_TO_NS(rawir.duration); - rawir.duration &= IR_MAX_DURATION; + rawir.duration = (rawir.duration > IR_MAX_DURATION) ? + IR_MAX_DURATION : rawir.duration; } sz_push(sz, rawir); @@ -165,7 +166,8 @@ static void sz_push_full_pulse(struct streamzap_ir *sz, rawir.duration += SZ_RESOLUTION / 2; sz->sum += rawir.duration; rawir.duration = US_TO_NS(rawir.duration); - rawir.duration &= IR_MAX_DURATION; + rawir.duration = (rawir.duration > IR_MAX_DURATION) ? + IR_MAX_DURATION : rawir.duration; sz_push(sz, rawir); } -- cgit v1.2.3-59-g8ed1b From b295e5c7d84721f76d1728f2ee4152a8cbb6ddaa Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 5 Jun 2015 10:47:36 -0300 Subject: [media] usbvision: cleanup the code There's a dead code on usbvision that makes it harder to read and produces a smatch warning about bad identation. Improve the code readability and add a FIXME to warn about the current hack there. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/usbvision/usbvision-video.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c index 12b403e78d52..1c6d31f7c1b9 100644 --- a/drivers/media/usb/usbvision/usbvision-video.c +++ b/drivers/media/usb/usbvision/usbvision-video.c @@ -1061,13 +1061,24 @@ static ssize_t usbvision_read(struct file *file, char __user *buf, __func__, (unsigned long)count, frame->bytes_read); - /* For now, forget the frame if it has not been read in one shot. */ -/* if (frame->bytes_read >= frame->scanlength) {*/ /* All data has been read */ +#if 1 + /* + * FIXME: + * For now, forget the frame if it has not been read in one shot. + */ + frame->bytes_read = 0; + + /* Mark it as available to be used again. */ + frame->grabstate = frame_state_unused; +#else + if (frame->bytes_read >= frame->scanlength) { + /* All data has been read */ frame->bytes_read = 0; /* Mark it as available to be used again. */ frame->grabstate = frame_state_unused; -/* } */ + } +#endif return count; } -- cgit v1.2.3-59-g8ed1b From 74fdcb2ee1786a92584e89c91006e449813527ce Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 28 Apr 2015 08:49:09 -0300 Subject: [media] videodev2.h: add support for transfer functions In the past the transfer function was implied by the colorspace. However, it is an independent entity in its own right. Add support for explicitly choosing the transfer function. This change will allow us to represent linear RGB (as is used by openGL), and it will make it easier to work with decoded video material since most codecs store the transfer function as a separate property as well. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ioctl.c | 9 ++++---- include/media/v4l2-mediabus.h | 2 ++ include/uapi/linux/v4l2-mediabus.h | 4 +++- include/uapi/linux/videodev2.h | 41 +++++++++++++++++++++++++++++++++++- 4 files changed, 50 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 368bc3a973d4..691295984225 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -257,7 +257,8 @@ static void v4l_print_format(const void *arg, bool write_only) pr_cont(", width=%u, height=%u, " "pixelformat=%c%c%c%c, field=%s, " "bytesperline=%u, sizeimage=%u, colorspace=%d, " - "flags=0x%x, ycbcr_enc=%u, quantization=%u\n", + "flags=0x%x, ycbcr_enc=%u, quantization=%u, " + "xfer_func=%u\n", pix->width, pix->height, (pix->pixelformat & 0xff), (pix->pixelformat >> 8) & 0xff, @@ -266,7 +267,7 @@ static void v4l_print_format(const void *arg, bool write_only) prt_names(pix->field, v4l2_field_names), pix->bytesperline, pix->sizeimage, pix->colorspace, pix->flags, pix->ycbcr_enc, - pix->quantization); + pix->quantization, pix->xfer_func); break; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: @@ -274,7 +275,7 @@ static void v4l_print_format(const void *arg, bool write_only) pr_cont(", width=%u, height=%u, " "format=%c%c%c%c, field=%s, " "colorspace=%d, num_planes=%u, flags=0x%x, " - "ycbcr_enc=%u, quantization=%u\n", + "ycbcr_enc=%u, quantization=%u, xfer_func=%u\n", mp->width, mp->height, (mp->pixelformat & 0xff), (mp->pixelformat >> 8) & 0xff, @@ -282,7 +283,7 @@ static void v4l_print_format(const void *arg, bool write_only) (mp->pixelformat >> 24) & 0xff, prt_names(mp->field, v4l2_field_names), mp->colorspace, mp->num_planes, mp->flags, - mp->ycbcr_enc, mp->quantization); + mp->ycbcr_enc, mp->quantization, mp->xfer_func); for (i = 0; i < mp->num_planes; i++) printk(KERN_DEBUG "plane %u: bytesperline=%u sizeimage=%u\n", i, mp->plane_fmt[i].bytesperline, diff --git a/include/media/v4l2-mediabus.h b/include/media/v4l2-mediabus.h index 38d960d8dccd..73069e4c2796 100644 --- a/include/media/v4l2-mediabus.h +++ b/include/media/v4l2-mediabus.h @@ -96,6 +96,7 @@ static inline void v4l2_fill_pix_format(struct v4l2_pix_format *pix_fmt, pix_fmt->colorspace = mbus_fmt->colorspace; pix_fmt->ycbcr_enc = mbus_fmt->ycbcr_enc; pix_fmt->quantization = mbus_fmt->quantization; + pix_fmt->xfer_func = mbus_fmt->xfer_func; } static inline void v4l2_fill_mbus_format(struct v4l2_mbus_framefmt *mbus_fmt, @@ -108,6 +109,7 @@ static inline void v4l2_fill_mbus_format(struct v4l2_mbus_framefmt *mbus_fmt, mbus_fmt->colorspace = pix_fmt->colorspace; mbus_fmt->ycbcr_enc = pix_fmt->ycbcr_enc; mbus_fmt->quantization = pix_fmt->quantization; + mbus_fmt->xfer_func = pix_fmt->xfer_func; mbus_fmt->code = code; } diff --git a/include/uapi/linux/v4l2-mediabus.h b/include/uapi/linux/v4l2-mediabus.h index 26db20647e6f..9cac6325cc7e 100644 --- a/include/uapi/linux/v4l2-mediabus.h +++ b/include/uapi/linux/v4l2-mediabus.h @@ -24,6 +24,7 @@ * @colorspace: colorspace of the data (from enum v4l2_colorspace) * @ycbcr_enc: YCbCr encoding of the data (from enum v4l2_ycbcr_encoding) * @quantization: quantization of the data (from enum v4l2_quantization) + * @xfer_func: transfer function of the data (from enum v4l2_xfer_func) */ struct v4l2_mbus_framefmt { __u32 width; @@ -33,7 +34,8 @@ struct v4l2_mbus_framefmt { __u32 colorspace; __u16 ycbcr_enc; __u16 quantization; - __u32 reserved[6]; + __u16 xfer_func; + __u16 reserved[11]; }; #ifndef __KERNEL__ diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 003a91292a4f..3d5fc72d53a7 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -240,6 +240,42 @@ enum v4l2_colorspace { ((is_sdtv) ? V4L2_COLORSPACE_SMPTE170M : \ ((is_hdtv) ? V4L2_COLORSPACE_REC709 : V4L2_COLORSPACE_SRGB)) +enum v4l2_xfer_func { + /* + * Mapping of V4L2_XFER_FUNC_DEFAULT to actual transfer functions + * for the various colorspaces: + * + * V4L2_COLORSPACE_SMPTE170M, V4L2_COLORSPACE_470_SYSTEM_M, + * V4L2_COLORSPACE_470_SYSTEM_BG, V4L2_COLORSPACE_REC709 and + * V4L2_COLORSPACE_BT2020: V4L2_XFER_FUNC_709 + * + * V4L2_COLORSPACE_SRGB, V4L2_COLORSPACE_JPEG: V4L2_XFER_FUNC_SRGB + * + * V4L2_COLORSPACE_ADOBERGB: V4L2_XFER_FUNC_ADOBERGB + * + * V4L2_COLORSPACE_SMPTE240M: V4L2_XFER_FUNC_SMPTE240M + * + * V4L2_COLORSPACE_RAW: V4L2_XFER_FUNC_NONE + */ + V4L2_XFER_FUNC_DEFAULT = 0, + V4L2_XFER_FUNC_709 = 1, + V4L2_XFER_FUNC_SRGB = 2, + V4L2_XFER_FUNC_ADOBERGB = 3, + V4L2_XFER_FUNC_SMPTE240M = 4, + V4L2_XFER_FUNC_NONE = 5, +}; + +/* + * Determine how XFER_FUNC_DEFAULT should map to a proper transfer function. + * This depends on the colorspace. + */ +#define V4L2_MAP_XFER_FUNC_DEFAULT(colsp) \ + ((colsp) == V4L2_XFER_FUNC_ADOBERGB ? V4L2_XFER_FUNC_ADOBERGB : \ + ((colsp) == V4L2_COLORSPACE_SMPTE240M ? V4L2_XFER_FUNC_SMPTE240M : \ + ((colsp) == V4L2_COLORSPACE_RAW ? V4L2_XFER_FUNC_NONE : \ + ((colsp) == V4L2_COLORSPACE_SRGB || (colsp) == V4L2_COLORSPACE_JPEG ? \ + V4L2_XFER_FUNC_SRGB : V4L2_XFER_FUNC_709)))) + enum v4l2_ycbcr_encoding { /* * Mapping of V4L2_YCBCR_ENC_DEFAULT to actual encodings for the @@ -409,6 +445,7 @@ struct v4l2_pix_format { __u32 flags; /* format flags (V4L2_PIX_FMT_FLAG_*) */ __u32 ycbcr_enc; /* enum v4l2_ycbcr_encoding */ __u32 quantization; /* enum v4l2_quantization */ + __u32 xfer_func; /* enum v4l2_xfer_func */ }; /* Pixel format FOURCC depth Description */ @@ -1907,6 +1944,7 @@ struct v4l2_plane_pix_format { * @flags: format flags (V4L2_PIX_FMT_FLAG_*) * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding * @quantization: enum v4l2_quantization, colorspace quantization + * @xfer_func: enum v4l2_xfer_func, colorspace transfer function */ struct v4l2_pix_format_mplane { __u32 width; @@ -1920,7 +1958,8 @@ struct v4l2_pix_format_mplane { __u8 flags; __u8 ycbcr_enc; __u8 quantization; - __u8 reserved[8]; + __u8 xfer_func; + __u8 reserved[7]; } __attribute__ ((packed)); /** -- cgit v1.2.3-59-g8ed1b From e719a51a46f8e3a3278f160ea29ed5d8e2c23a5d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 28 Apr 2015 09:40:30 -0300 Subject: [media] adv7511: add xfer_func support Still preliminary, but the information is at least there. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7511.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c index 12d93203d405..90325676fca5 100644 --- a/drivers/media/i2c/adv7511.c +++ b/drivers/media/i2c/adv7511.c @@ -101,6 +101,7 @@ struct adv7511_state { u32 colorspace; u32 ycbcr_enc; u32 quantization; + u32 xfer_func; /* controls */ struct v4l2_ctrl *hdmi_mode_ctrl; struct v4l2_ctrl *hotplug_ctrl; @@ -861,11 +862,13 @@ static int adv7511_get_fmt(struct v4l2_subdev *sd, format->format.colorspace = fmt->colorspace; format->format.ycbcr_enc = fmt->ycbcr_enc; format->format.quantization = fmt->quantization; + format->format.xfer_func = fmt->xfer_func; } else { format->format.code = state->fmt_code; format->format.colorspace = state->colorspace; format->format.ycbcr_enc = state->ycbcr_enc; format->format.quantization = state->quantization; + format->format.xfer_func = state->xfer_func; } return 0; @@ -912,6 +915,7 @@ static int adv7511_set_fmt(struct v4l2_subdev *sd, fmt->colorspace = format->format.colorspace; fmt->ycbcr_enc = format->format.ycbcr_enc; fmt->quantization = format->format.quantization; + fmt->xfer_func = format->format.xfer_func; return 0; } @@ -936,6 +940,7 @@ static int adv7511_set_fmt(struct v4l2_subdev *sd, state->colorspace = format->format.colorspace; state->ycbcr_enc = format->format.ycbcr_enc; state->quantization = format->format.quantization; + state->xfer_func = format->format.xfer_func; switch (format->format.colorspace) { case V4L2_COLORSPACE_ADOBERGB: -- cgit v1.2.3-59-g8ed1b From c62cda97c81309aa77fd2d32820f3f5b925e0ce3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 28 Apr 2015 09:41:03 -0300 Subject: [media] am437x-vpfe: add support for xfer_func Make this part of the format check. Signed-off-by: Hans Verkuil Cc: Prabhakar Lad Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/am437x/am437x-vpfe.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c index ea971bb0d9c6..1fba339cddc1 100644 --- a/drivers/media/platform/am437x/am437x-vpfe.c +++ b/drivers/media/platform/am437x/am437x-vpfe.c @@ -288,7 +288,8 @@ cmp_v4l2_format(const struct v4l2_format *lhs, const struct v4l2_format *rhs) lhs->fmt.pix.field == rhs->fmt.pix.field && lhs->fmt.pix.colorspace == rhs->fmt.pix.colorspace && lhs->fmt.pix.ycbcr_enc == rhs->fmt.pix.ycbcr_enc && - lhs->fmt.pix.quantization == rhs->fmt.pix.quantization; + lhs->fmt.pix.quantization == rhs->fmt.pix.quantization && + lhs->fmt.pix.xfer_func == rhs->fmt.pix.xfer_func; } static inline u32 vpfe_reg_read(struct vpfe_ccdc *ccdc, u32 offset) -- cgit v1.2.3-59-g8ed1b From ca5316db08199124bf72b0ed16dc1a83fe0609e2 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 28 Apr 2015 09:41:37 -0300 Subject: [media] vivid: add xfer_func support Add support for the transfer function: create a new control for it, and support it for both capture and output sides. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-core.h | 1 + drivers/media/platform/vivid/vivid-ctrls.c | 58 ++++++++++++++++++------- drivers/media/platform/vivid/vivid-tpg.c | 7 +++ drivers/media/platform/vivid/vivid-tpg.h | 19 ++++++++ drivers/media/platform/vivid/vivid-vid-cap.c | 9 ++++ drivers/media/platform/vivid/vivid-vid-common.c | 2 + drivers/media/platform/vivid/vivid-vid-out.c | 4 ++ 7 files changed, 85 insertions(+), 15 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h index aa1b5232a963..3755b1858426 100644 --- a/drivers/media/platform/vivid/vivid-core.h +++ b/drivers/media/platform/vivid/vivid-core.h @@ -332,6 +332,7 @@ struct vivid_dev { u32 colorspace_out; u32 ycbcr_enc_out; u32 quantization_out; + u32 xfer_func_out; u32 service_set_out; unsigned bytesperline_out[TPG_MAX_PLANES]; unsigned tv_field_out; diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c index 2b9070098b08..1898751c20c8 100644 --- a/drivers/media/platform/vivid/vivid-ctrls.c +++ b/drivers/media/platform/vivid/vivid-ctrls.c @@ -62,21 +62,22 @@ #define VIVID_CID_DV_TIMINGS_ASPECT_RATIO (VIVID_CID_VIVID_BASE + 23) #define VIVID_CID_TSTAMP_SRC (VIVID_CID_VIVID_BASE + 24) #define VIVID_CID_COLORSPACE (VIVID_CID_VIVID_BASE + 25) -#define VIVID_CID_YCBCR_ENC (VIVID_CID_VIVID_BASE + 26) -#define VIVID_CID_QUANTIZATION (VIVID_CID_VIVID_BASE + 27) -#define VIVID_CID_LIMITED_RGB_RANGE (VIVID_CID_VIVID_BASE + 28) -#define VIVID_CID_ALPHA_MODE (VIVID_CID_VIVID_BASE + 29) -#define VIVID_CID_HAS_CROP_CAP (VIVID_CID_VIVID_BASE + 30) -#define VIVID_CID_HAS_COMPOSE_CAP (VIVID_CID_VIVID_BASE + 31) -#define VIVID_CID_HAS_SCALER_CAP (VIVID_CID_VIVID_BASE + 32) -#define VIVID_CID_HAS_CROP_OUT (VIVID_CID_VIVID_BASE + 33) -#define VIVID_CID_HAS_COMPOSE_OUT (VIVID_CID_VIVID_BASE + 34) -#define VIVID_CID_HAS_SCALER_OUT (VIVID_CID_VIVID_BASE + 35) -#define VIVID_CID_LOOP_VIDEO (VIVID_CID_VIVID_BASE + 36) -#define VIVID_CID_SEQ_WRAP (VIVID_CID_VIVID_BASE + 37) -#define VIVID_CID_TIME_WRAP (VIVID_CID_VIVID_BASE + 38) -#define VIVID_CID_MAX_EDID_BLOCKS (VIVID_CID_VIVID_BASE + 39) -#define VIVID_CID_PERCENTAGE_FILL (VIVID_CID_VIVID_BASE + 40) +#define VIVID_CID_XFER_FUNC (VIVID_CID_VIVID_BASE + 26) +#define VIVID_CID_YCBCR_ENC (VIVID_CID_VIVID_BASE + 27) +#define VIVID_CID_QUANTIZATION (VIVID_CID_VIVID_BASE + 28) +#define VIVID_CID_LIMITED_RGB_RANGE (VIVID_CID_VIVID_BASE + 29) +#define VIVID_CID_ALPHA_MODE (VIVID_CID_VIVID_BASE + 30) +#define VIVID_CID_HAS_CROP_CAP (VIVID_CID_VIVID_BASE + 31) +#define VIVID_CID_HAS_COMPOSE_CAP (VIVID_CID_VIVID_BASE + 32) +#define VIVID_CID_HAS_SCALER_CAP (VIVID_CID_VIVID_BASE + 33) +#define VIVID_CID_HAS_CROP_OUT (VIVID_CID_VIVID_BASE + 34) +#define VIVID_CID_HAS_COMPOSE_OUT (VIVID_CID_VIVID_BASE + 35) +#define VIVID_CID_HAS_SCALER_OUT (VIVID_CID_VIVID_BASE + 36) +#define VIVID_CID_LOOP_VIDEO (VIVID_CID_VIVID_BASE + 37) +#define VIVID_CID_SEQ_WRAP (VIVID_CID_VIVID_BASE + 38) +#define VIVID_CID_TIME_WRAP (VIVID_CID_VIVID_BASE + 39) +#define VIVID_CID_MAX_EDID_BLOCKS (VIVID_CID_VIVID_BASE + 40) +#define VIVID_CID_PERCENTAGE_FILL (VIVID_CID_VIVID_BASE + 41) #define VIVID_CID_STD_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 60) #define VIVID_CID_STANDARD (VIVID_CID_VIVID_BASE + 61) @@ -360,6 +361,13 @@ static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl) vivid_send_source_change(dev, HDMI); vivid_send_source_change(dev, WEBCAM); break; + case VIVID_CID_XFER_FUNC: + tpg_s_xfer_func(&dev->tpg, ctrl->val); + vivid_send_source_change(dev, TV); + vivid_send_source_change(dev, SVID); + vivid_send_source_change(dev, HDMI); + vivid_send_source_change(dev, WEBCAM); + break; case VIVID_CID_YCBCR_ENC: tpg_s_ycbcr_enc(&dev->tpg, ctrl->val); vivid_send_source_change(dev, TV); @@ -709,6 +717,25 @@ static const struct v4l2_ctrl_config vivid_ctrl_colorspace = { .qmenu = vivid_ctrl_colorspace_strings, }; +static const char * const vivid_ctrl_xfer_func_strings[] = { + "Default", + "Rec. 709", + "sRGB", + "AdobeRGB", + "SMPTE 240M", + "None", + NULL, +}; + +static const struct v4l2_ctrl_config vivid_ctrl_xfer_func = { + .ops = &vivid_vid_cap_ctrl_ops, + .id = VIVID_CID_XFER_FUNC, + .name = "Transfer Function", + .type = V4L2_CTRL_TYPE_MENU, + .max = 5, + .qmenu = vivid_ctrl_xfer_func_strings, +}; + static const char * const vivid_ctrl_ycbcr_enc_strings[] = { "Default", "ITU-R 601", @@ -1365,6 +1392,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_tstamp_src, NULL); dev->colorspace = v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_colorspace, NULL); + v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_xfer_func, NULL); v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_ycbcr_enc, NULL); v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_quantization, NULL); v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_alpha_mode, NULL); diff --git a/drivers/media/platform/vivid/vivid-tpg.c b/drivers/media/platform/vivid/vivid-tpg.c index 7a3ed580626a..c1883a8533c5 100644 --- a/drivers/media/platform/vivid/vivid-tpg.c +++ b/drivers/media/platform/vivid/vivid-tpg.c @@ -1651,8 +1651,14 @@ static void tpg_recalc(struct tpg_data *tpg) if (tpg->recalc_colors) { tpg->recalc_colors = false; tpg->recalc_lines = true; + tpg->real_xfer_func = tpg->xfer_func; tpg->real_ycbcr_enc = tpg->ycbcr_enc; tpg->real_quantization = tpg->quantization; + + if (tpg->xfer_func == V4L2_XFER_FUNC_DEFAULT) + tpg->real_xfer_func = + V4L2_MAP_XFER_FUNC_DEFAULT(tpg->colorspace); + if (tpg->ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT) tpg->real_ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(tpg->colorspace); @@ -1716,6 +1722,7 @@ void tpg_log_status(struct tpg_data *tpg) pr_info("tpg compose: %ux%u@%dx%d\n", tpg->compose.width, tpg->compose.height, tpg->compose.left, tpg->compose.top); pr_info("tpg colorspace: %d\n", tpg->colorspace); + pr_info("tpg transfer function: %d/%d\n", tpg->xfer_func, tpg->real_xfer_func); pr_info("tpg Y'CbCr encoding: %d/%d\n", tpg->ycbcr_enc, tpg->real_ycbcr_enc); pr_info("tpg quantization: %d/%d\n", tpg->quantization, tpg->real_quantization); pr_info("tpg RGB range: %d/%d\n", tpg->rgb_range, tpg->real_rgb_range); diff --git a/drivers/media/platform/vivid/vivid-tpg.h b/drivers/media/platform/vivid/vivid-tpg.h index ef8638f945be..9baed6a10334 100644 --- a/drivers/media/platform/vivid/vivid-tpg.h +++ b/drivers/media/platform/vivid/vivid-tpg.h @@ -122,7 +122,13 @@ struct tpg_data { u32 fourcc; bool is_yuv; u32 colorspace; + u32 xfer_func; u32 ycbcr_enc; + /* + * Stores the actual transfer function, i.e. will never be + * V4L2_XFER_FUNC_DEFAULT. + */ + u32 real_xfer_func; /* * Stores the actual Y'CbCr encoding, i.e. will never be * V4L2_YCBCR_ENC_DEFAULT. @@ -329,6 +335,19 @@ static inline u32 tpg_g_ycbcr_enc(const struct tpg_data *tpg) return tpg->ycbcr_enc; } +static inline void tpg_s_xfer_func(struct tpg_data *tpg, u32 xfer_func) +{ + if (tpg->xfer_func == xfer_func) + return; + tpg->xfer_func = xfer_func; + tpg->recalc_colors = true; +} + +static inline u32 tpg_g_xfer_func(const struct tpg_data *tpg) +{ + return tpg->xfer_func; +} + static inline void tpg_s_quantization(struct tpg_data *tpg, u32 quantization) { if (tpg->quantization == quantization) diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c index fd7adc43f63d..7b80bda4c34c 100644 --- a/drivers/media/platform/vivid/vivid-vid-cap.c +++ b/drivers/media/platform/vivid/vivid-vid-cap.c @@ -501,6 +501,13 @@ static unsigned vivid_colorspace_cap(struct vivid_dev *dev) return dev->colorspace_out; } +static unsigned vivid_xfer_func_cap(struct vivid_dev *dev) +{ + if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev)) + return tpg_g_xfer_func(&dev->tpg); + return dev->xfer_func_out; +} + static unsigned vivid_ycbcr_enc_cap(struct vivid_dev *dev) { if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev)) @@ -527,6 +534,7 @@ int vivid_g_fmt_vid_cap(struct file *file, void *priv, mp->field = dev->field_cap; mp->pixelformat = dev->fmt_cap->fourcc; mp->colorspace = vivid_colorspace_cap(dev); + mp->xfer_func = vivid_xfer_func_cap(dev); mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev); mp->quantization = vivid_quantization_cap(dev); mp->num_planes = dev->fmt_cap->buffers; @@ -616,6 +624,7 @@ int vivid_try_fmt_vid_cap(struct file *file, void *priv, } mp->colorspace = vivid_colorspace_cap(dev); mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev); + mp->xfer_func = vivid_xfer_func_cap(dev); mp->quantization = vivid_quantization_cap(dev); memset(mp->reserved, 0, sizeof(mp->reserved)); return 0; diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c index 45f10a7f9b46..fc73927a4abc 100644 --- a/drivers/media/platform/vivid/vivid-vid-common.c +++ b/drivers/media/platform/vivid/vivid-vid-common.c @@ -524,6 +524,7 @@ void fmt_sp2mp(const struct v4l2_format *sp_fmt, struct v4l2_format *mp_fmt) mp->pixelformat = pix->pixelformat; mp->field = pix->field; mp->colorspace = pix->colorspace; + mp->xfer_func = pix->xfer_func; mp->ycbcr_enc = pix->ycbcr_enc; mp->quantization = pix->quantization; mp->num_planes = 1; @@ -552,6 +553,7 @@ int fmt_sp2mp_func(struct file *file, void *priv, pix->pixelformat = mp->pixelformat; pix->field = mp->field; pix->colorspace = mp->colorspace; + pix->xfer_func = mp->xfer_func; pix->ycbcr_enc = mp->ycbcr_enc; pix->quantization = mp->quantization; pix->sizeimage = ppix->sizeimage; diff --git a/drivers/media/platform/vivid/vivid-vid-out.c b/drivers/media/platform/vivid/vivid-vid-out.c index 00f42df947c0..0862c1f24f57 100644 --- a/drivers/media/platform/vivid/vivid-vid-out.c +++ b/drivers/media/platform/vivid/vivid-vid-out.c @@ -258,6 +258,7 @@ void vivid_update_format_out(struct vivid_dev *dev) } break; } + dev->xfer_func_out = V4L2_XFER_FUNC_DEFAULT; dev->ycbcr_enc_out = V4L2_YCBCR_ENC_DEFAULT; dev->quantization_out = V4L2_QUANTIZATION_DEFAULT; dev->compose_out = dev->sink_rect; @@ -320,6 +321,7 @@ int vivid_g_fmt_vid_out(struct file *file, void *priv, mp->field = dev->field_out; mp->pixelformat = fmt->fourcc; mp->colorspace = dev->colorspace_out; + mp->xfer_func = dev->xfer_func_out; mp->ycbcr_enc = dev->ycbcr_enc_out; mp->quantization = dev->quantization_out; mp->num_planes = fmt->buffers; @@ -407,6 +409,7 @@ int vivid_try_fmt_vid_out(struct file *file, void *priv, for (p = fmt->buffers; p < fmt->planes; p++) pfmt[0].sizeimage += (pfmt[0].bytesperline * fmt->bit_depth[p]) / (fmt->bit_depth[0] * fmt->vdownsampling[p]); + mp->xfer_func = V4L2_XFER_FUNC_DEFAULT; mp->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; mp->quantization = V4L2_QUANTIZATION_DEFAULT; if (vivid_is_svid_out(dev)) { @@ -546,6 +549,7 @@ int vivid_s_fmt_vid_out(struct file *file, void *priv, set_colorspace: dev->colorspace_out = mp->colorspace; + dev->xfer_func_out = mp->xfer_func; dev->ycbcr_enc_out = mp->ycbcr_enc; dev->quantization_out = mp->quantization; if (dev->loop_video) { -- cgit v1.2.3-59-g8ed1b From 78aad7f81aa6dfccdb2804ac35db6fc371d265cf Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 28 Apr 2015 10:08:43 -0300 Subject: [media] vivid-tpg: precalculate colorspace/xfer_func combinations Precalculate all the colorspace/transfer function combinations in order to easily generate the correct colors. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-tpg-colors.c | 478 ++++++++++++++++++------ drivers/media/platform/vivid/vivid-tpg-colors.h | 4 +- drivers/media/platform/vivid/vivid-tpg.c | 6 +- 3 files changed, 371 insertions(+), 117 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/vivid/vivid-tpg-colors.c b/drivers/media/platform/vivid/vivid-tpg-colors.c index 424aa7abc723..8f231a6e68c9 100644 --- a/drivers/media/platform/vivid/vivid-tpg-colors.c +++ b/drivers/media/platform/vivid/vivid-tpg-colors.c @@ -598,71 +598,327 @@ const unsigned short tpg_linear_to_rec709[255 * 16 + 1] = { }; /* Generated table */ -const struct color16 tpg_csc_colors[V4L2_COLORSPACE_BT2020 + 1][TPG_COLOR_CSC_BLACK + 1] = { - [V4L2_COLORSPACE_SMPTE170M][0] = { 2939, 2939, 2939 }, - [V4L2_COLORSPACE_SMPTE170M][1] = { 2953, 2963, 586 }, - [V4L2_COLORSPACE_SMPTE170M][2] = { 0, 2967, 2937 }, - [V4L2_COLORSPACE_SMPTE170M][3] = { 88, 2990, 575 }, - [V4L2_COLORSPACE_SMPTE170M][4] = { 3016, 259, 2933 }, - [V4L2_COLORSPACE_SMPTE170M][5] = { 3030, 405, 558 }, - [V4L2_COLORSPACE_SMPTE170M][6] = { 478, 428, 2931 }, - [V4L2_COLORSPACE_SMPTE170M][7] = { 547, 547, 547 }, - [V4L2_COLORSPACE_SMPTE240M][0] = { 2926, 2926, 2926 }, - [V4L2_COLORSPACE_SMPTE240M][1] = { 2941, 2950, 546 }, - [V4L2_COLORSPACE_SMPTE240M][2] = { 0, 2954, 2924 }, - [V4L2_COLORSPACE_SMPTE240M][3] = { 78, 2978, 536 }, - [V4L2_COLORSPACE_SMPTE240M][4] = { 3004, 230, 2920 }, - [V4L2_COLORSPACE_SMPTE240M][5] = { 3018, 363, 518 }, - [V4L2_COLORSPACE_SMPTE240M][6] = { 437, 387, 2918 }, - [V4L2_COLORSPACE_SMPTE240M][7] = { 507, 507, 507 }, - [V4L2_COLORSPACE_REC709][0] = { 2939, 2939, 2939 }, - [V4L2_COLORSPACE_REC709][1] = { 2939, 2939, 547 }, - [V4L2_COLORSPACE_REC709][2] = { 547, 2939, 2939 }, - [V4L2_COLORSPACE_REC709][3] = { 547, 2939, 547 }, - [V4L2_COLORSPACE_REC709][4] = { 2939, 547, 2939 }, - [V4L2_COLORSPACE_REC709][5] = { 2939, 547, 547 }, - [V4L2_COLORSPACE_REC709][6] = { 547, 547, 2939 }, - [V4L2_COLORSPACE_REC709][7] = { 547, 547, 547 }, - [V4L2_COLORSPACE_470_SYSTEM_M][0] = { 2892, 2988, 2807 }, - [V4L2_COLORSPACE_470_SYSTEM_M][1] = { 2846, 3070, 843 }, - [V4L2_COLORSPACE_470_SYSTEM_M][2] = { 1656, 2962, 2783 }, - [V4L2_COLORSPACE_470_SYSTEM_M][3] = { 1572, 3045, 763 }, - [V4L2_COLORSPACE_470_SYSTEM_M][4] = { 2476, 229, 2742 }, - [V4L2_COLORSPACE_470_SYSTEM_M][5] = { 2420, 672, 614 }, - [V4L2_COLORSPACE_470_SYSTEM_M][6] = { 725, 63, 2718 }, - [V4L2_COLORSPACE_470_SYSTEM_M][7] = { 534, 561, 509 }, - [V4L2_COLORSPACE_470_SYSTEM_BG][0] = { 2939, 2939, 2939 }, - [V4L2_COLORSPACE_470_SYSTEM_BG][1] = { 2939, 2939, 464 }, - [V4L2_COLORSPACE_470_SYSTEM_BG][2] = { 786, 2939, 2939 }, - [V4L2_COLORSPACE_470_SYSTEM_BG][3] = { 786, 2939, 464 }, - [V4L2_COLORSPACE_470_SYSTEM_BG][4] = { 2879, 547, 2956 }, - [V4L2_COLORSPACE_470_SYSTEM_BG][5] = { 2879, 547, 547 }, - [V4L2_COLORSPACE_470_SYSTEM_BG][6] = { 547, 547, 2956 }, - [V4L2_COLORSPACE_470_SYSTEM_BG][7] = { 547, 547, 547 }, - [V4L2_COLORSPACE_SRGB][0] = { 3056, 3056, 3056 }, - [V4L2_COLORSPACE_SRGB][1] = { 3056, 3056, 800 }, - [V4L2_COLORSPACE_SRGB][2] = { 800, 3056, 3056 }, - [V4L2_COLORSPACE_SRGB][3] = { 800, 3056, 800 }, - [V4L2_COLORSPACE_SRGB][4] = { 3056, 800, 3056 }, - [V4L2_COLORSPACE_SRGB][5] = { 3056, 800, 800 }, - [V4L2_COLORSPACE_SRGB][6] = { 800, 800, 3056 }, - [V4L2_COLORSPACE_SRGB][7] = { 800, 800, 800 }, - [V4L2_COLORSPACE_ADOBERGB][0] = { 3033, 3033, 3033 }, - [V4L2_COLORSPACE_ADOBERGB][1] = { 3033, 3033, 1063 }, - [V4L2_COLORSPACE_ADOBERGB][2] = { 1828, 3033, 3033 }, - [V4L2_COLORSPACE_ADOBERGB][3] = { 1828, 3033, 1063 }, - [V4L2_COLORSPACE_ADOBERGB][4] = { 2633, 851, 2979 }, - [V4L2_COLORSPACE_ADOBERGB][5] = { 2633, 851, 851 }, - [V4L2_COLORSPACE_ADOBERGB][6] = { 851, 851, 2979 }, - [V4L2_COLORSPACE_ADOBERGB][7] = { 851, 851, 851 }, - [V4L2_COLORSPACE_BT2020][0] = { 2939, 2939, 2939 }, - [V4L2_COLORSPACE_BT2020][1] = { 2877, 2923, 1058 }, - [V4L2_COLORSPACE_BT2020][2] = { 1837, 2840, 2916 }, - [V4L2_COLORSPACE_BT2020][3] = { 1734, 2823, 993 }, - [V4L2_COLORSPACE_BT2020][4] = { 2427, 961, 2812 }, - [V4L2_COLORSPACE_BT2020][5] = { 2351, 912, 648 }, - [V4L2_COLORSPACE_BT2020][6] = { 792, 618, 2788 }, - [V4L2_COLORSPACE_BT2020][7] = { 547, 547, 547 }, +const struct color16 tpg_csc_colors[V4L2_COLORSPACE_BT2020 + 1][V4L2_XFER_FUNC_NONE + 1][TPG_COLOR_CSC_BLACK + 1] = { + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_709][1] = { 2953, 2963, 586 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_709][2] = { 0, 2967, 2937 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_709][3] = { 88, 2990, 575 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_709][4] = { 3016, 259, 2933 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_709][5] = { 3030, 405, 558 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_709][6] = { 478, 428, 2931 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_709][7] = { 547, 547, 547 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SRGB][0] = { 3056, 3056, 3056 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SRGB][1] = { 3068, 3077, 838 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SRGB][2] = { 0, 3081, 3053 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SRGB][3] = { 241, 3102, 828 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SRGB][4] = { 3126, 504, 3050 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SRGB][5] = { 3138, 657, 810 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SRGB][6] = { 731, 680, 3048 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SRGB][7] = { 800, 799, 800 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][1] = { 3046, 3054, 886 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][2] = { 0, 3058, 3031 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][3] = { 360, 3079, 877 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][4] = { 3103, 587, 3027 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][5] = { 3116, 723, 861 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][6] = { 789, 744, 3025 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE240M][1] = { 2941, 2950, 546 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE240M][2] = { 0, 2954, 2924 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE240M][3] = { 78, 2978, 536 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE240M][4] = { 3004, 230, 2920 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE240M][5] = { 3018, 363, 518 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE240M][6] = { 437, 387, 2918 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE240M][7] = { 507, 507, 507 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_NONE][0] = { 2125, 2125, 2125 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_NONE][1] = { 2145, 2159, 142 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_NONE][2] = { 0, 2164, 2122 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_NONE][3] = { 19, 2198, 138 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_NONE][4] = { 2236, 57, 2116 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_NONE][5] = { 2256, 90, 133 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_NONE][6] = { 110, 96, 2113 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_NONE][7] = { 130, 130, 130 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_709][1] = { 2953, 2963, 586 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_709][2] = { 0, 2967, 2937 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_709][3] = { 88, 2990, 575 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_709][4] = { 3016, 259, 2933 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_709][5] = { 3030, 405, 558 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_709][6] = { 478, 428, 2931 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_709][7] = { 547, 547, 547 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SRGB][0] = { 3056, 3056, 3056 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SRGB][1] = { 3068, 3077, 838 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SRGB][2] = { 0, 3081, 3053 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SRGB][3] = { 241, 3102, 828 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SRGB][4] = { 3126, 504, 3050 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SRGB][5] = { 3138, 657, 810 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SRGB][6] = { 731, 680, 3048 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SRGB][7] = { 800, 799, 800 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][1] = { 3046, 3054, 886 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][2] = { 0, 3058, 3031 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][3] = { 360, 3079, 877 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][4] = { 3103, 587, 3027 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][5] = { 3116, 723, 861 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][6] = { 789, 744, 3025 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE240M][1] = { 2941, 2950, 546 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE240M][2] = { 0, 2954, 2924 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE240M][3] = { 78, 2978, 536 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE240M][4] = { 3004, 230, 2920 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE240M][5] = { 3018, 363, 518 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE240M][6] = { 437, 387, 2918 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE240M][7] = { 507, 507, 507 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_NONE][0] = { 2125, 2125, 2125 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_NONE][1] = { 2145, 2159, 142 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_NONE][2] = { 0, 2164, 2122 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_NONE][3] = { 19, 2198, 138 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_NONE][4] = { 2236, 57, 2116 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_NONE][5] = { 2256, 90, 133 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_NONE][6] = { 110, 96, 2113 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_NONE][7] = { 130, 130, 130 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_709][1] = { 2939, 2939, 547 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_709][2] = { 547, 2939, 2939 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_709][3] = { 547, 2939, 547 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_709][4] = { 2939, 547, 2939 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_709][5] = { 2939, 547, 547 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_709][6] = { 547, 547, 2939 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_709][7] = { 547, 547, 547 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SRGB][0] = { 3056, 3056, 3056 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SRGB][1] = { 3056, 3056, 800 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SRGB][2] = { 800, 3056, 3056 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SRGB][3] = { 800, 3056, 800 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SRGB][4] = { 3056, 800, 3056 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SRGB][5] = { 3056, 800, 800 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SRGB][6] = { 800, 800, 3056 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 800 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][1] = { 3033, 3033, 851 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][2] = { 851, 3033, 3033 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][3] = { 851, 3033, 851 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][4] = { 3033, 851, 3033 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][5] = { 3033, 851, 851 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][6] = { 851, 851, 3033 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE240M][1] = { 2926, 2926, 507 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE240M][2] = { 507, 2926, 2926 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE240M][3] = { 507, 2926, 507 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE240M][4] = { 2926, 507, 2926 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE240M][5] = { 2926, 507, 507 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE240M][6] = { 507, 507, 2926 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE240M][7] = { 507, 507, 507 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_NONE][0] = { 2125, 2125, 2125 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_NONE][1] = { 2125, 2125, 130 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_NONE][2] = { 130, 2125, 2125 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_NONE][3] = { 130, 2125, 130 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_NONE][4] = { 2125, 130, 2125 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_NONE][5] = { 2125, 130, 130 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_NONE][6] = { 130, 130, 2125 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_NONE][7] = { 130, 130, 130 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][0] = { 2892, 2988, 2807 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][1] = { 2846, 3070, 843 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][2] = { 1656, 2962, 2783 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][3] = { 1572, 3045, 763 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][4] = { 2476, 229, 2742 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][5] = { 2420, 672, 614 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][6] = { 725, 63, 2718 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][7] = { 534, 561, 509 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][0] = { 3013, 3099, 2935 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][1] = { 2970, 3174, 1091 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][2] = { 1871, 3076, 2913 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][3] = { 1791, 3152, 1013 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][4] = { 2632, 468, 2876 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][5] = { 2581, 924, 866 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][6] = { 976, 180, 2854 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][7] = { 786, 813, 762 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][0] = { 2990, 3077, 2912 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][1] = { 2947, 3153, 1119 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][2] = { 1859, 3053, 2889 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][3] = { 1782, 3130, 1047 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][4] = { 2608, 556, 2852 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][5] = { 2557, 964, 912 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][6] = { 1013, 309, 2830 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][7] = { 839, 864, 817 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][0] = { 2879, 2975, 2793 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][1] = { 2832, 3059, 806 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][2] = { 1629, 2949, 2768 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][3] = { 1543, 3033, 725 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][4] = { 2457, 203, 2727 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][5] = { 2401, 633, 574 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][6] = { 687, 56, 2702 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][7] = { 493, 521, 469 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_NONE][0] = { 2060, 2194, 1943 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_NONE][1] = { 1995, 2314, 237 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_NONE][2] = { 725, 2157, 1911 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_NONE][3] = { 660, 2278, 205 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_NONE][4] = { 1525, 50, 1857 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_NONE][5] = { 1461, 171, 151 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_NONE][6] = { 190, 14, 1825 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_NONE][7] = { 126, 134, 118 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_709][1] = { 2939, 2939, 464 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_709][2] = { 786, 2939, 2939 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_709][3] = { 786, 2939, 464 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_709][4] = { 2879, 547, 2956 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_709][5] = { 2879, 547, 547 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_709][6] = { 547, 547, 2956 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_709][7] = { 547, 547, 547 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SRGB][0] = { 3056, 3056, 3056 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SRGB][1] = { 3056, 3056, 717 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SRGB][2] = { 1036, 3056, 3056 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SRGB][3] = { 1036, 3056, 717 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SRGB][4] = { 3001, 800, 3071 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SRGB][5] = { 3001, 800, 799 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SRGB][6] = { 800, 800, 3071 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 799 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][1] = { 3033, 3033, 776 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][2] = { 1068, 3033, 3033 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][3] = { 1068, 3033, 776 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][4] = { 2977, 851, 3048 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][5] = { 2977, 851, 851 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][6] = { 851, 851, 3048 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE240M][1] = { 2926, 2926, 423 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE240M][2] = { 749, 2926, 2926 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE240M][3] = { 749, 2926, 423 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE240M][4] = { 2865, 507, 2943 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE240M][5] = { 2865, 507, 507 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE240M][6] = { 507, 507, 2943 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE240M][7] = { 507, 507, 507 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_NONE][0] = { 2125, 2125, 2125 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_NONE][1] = { 2125, 2125, 106 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_NONE][2] = { 214, 2125, 2125 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_NONE][3] = { 214, 2125, 106 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_NONE][4] = { 2041, 130, 2149 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_NONE][5] = { 2041, 130, 130 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_NONE][6] = { 130, 130, 2149 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_NONE][7] = { 130, 130, 130 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_709][1] = { 2939, 2939, 547 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_709][2] = { 547, 2939, 2939 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_709][3] = { 547, 2939, 547 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_709][4] = { 2939, 547, 2939 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_709][5] = { 2939, 547, 547 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_709][6] = { 547, 547, 2939 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_709][7] = { 547, 547, 547 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SRGB][0] = { 3056, 3056, 3056 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SRGB][1] = { 3056, 3056, 800 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SRGB][2] = { 800, 3056, 3056 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SRGB][3] = { 800, 3056, 800 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SRGB][4] = { 3056, 800, 3056 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SRGB][5] = { 3056, 800, 800 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SRGB][6] = { 800, 800, 3056 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 800 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][1] = { 3033, 3033, 851 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][2] = { 851, 3033, 3033 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][3] = { 851, 3033, 851 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][4] = { 3033, 851, 3033 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][5] = { 3033, 851, 851 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][6] = { 851, 851, 3033 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE240M][1] = { 2926, 2926, 507 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE240M][2] = { 507, 2926, 2926 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE240M][3] = { 507, 2926, 507 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE240M][4] = { 2926, 507, 2926 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE240M][5] = { 2926, 507, 507 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE240M][6] = { 507, 507, 2926 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE240M][7] = { 507, 507, 507 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_NONE][0] = { 2125, 2125, 2125 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_NONE][1] = { 2125, 2125, 130 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_NONE][2] = { 130, 2125, 2125 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_NONE][3] = { 130, 2125, 130 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_NONE][4] = { 2125, 130, 2125 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_NONE][5] = { 2125, 130, 130 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_NONE][6] = { 130, 130, 2125 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_NONE][7] = { 130, 130, 130 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][1] = { 2939, 2939, 781 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][2] = { 1622, 2939, 2939 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][3] = { 1622, 2939, 781 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][4] = { 2502, 547, 2881 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][5] = { 2502, 547, 547 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][6] = { 547, 547, 2881 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][7] = { 547, 547, 547 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][0] = { 3056, 3056, 3056 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][1] = { 3056, 3056, 1031 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][2] = { 1838, 3056, 3056 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][3] = { 1838, 3056, 1031 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][4] = { 2657, 800, 3002 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][5] = { 2657, 800, 800 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][6] = { 800, 800, 3002 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 800 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][1] = { 3033, 3033, 1063 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][2] = { 1828, 3033, 3033 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][3] = { 1828, 3033, 1063 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][4] = { 2633, 851, 2979 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][5] = { 2633, 851, 851 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][6] = { 851, 851, 2979 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][1] = { 2926, 2926, 744 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][2] = { 1594, 2926, 2926 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][3] = { 1594, 2926, 744 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][4] = { 2484, 507, 2867 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][5] = { 2484, 507, 507 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][6] = { 507, 507, 2867 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][7] = { 507, 507, 507 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][0] = { 2125, 2125, 2125 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][1] = { 2125, 2125, 212 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][2] = { 698, 2125, 2125 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][3] = { 698, 2125, 212 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][4] = { 1557, 130, 2043 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][5] = { 1557, 130, 130 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][6] = { 130, 130, 2043 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][7] = { 130, 130, 130 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][1] = { 2877, 2923, 1058 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][2] = { 1837, 2840, 2916 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][3] = { 1734, 2823, 993 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][4] = { 2427, 961, 2812 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][5] = { 2351, 912, 648 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][6] = { 792, 618, 2788 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][7] = { 547, 547, 547 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SRGB][0] = { 3056, 3056, 3056 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SRGB][1] = { 2999, 3041, 1301 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SRGB][2] = { 2040, 2965, 3034 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SRGB][3] = { 1944, 2950, 1238 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SRGB][4] = { 2587, 1207, 2940 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SRGB][5] = { 2517, 1159, 900 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SRGB][6] = { 1042, 870, 2917 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 800 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][1] = { 2976, 3018, 1315 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][2] = { 2024, 2942, 3011 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][3] = { 1930, 2926, 1256 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][4] = { 2563, 1227, 2916 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][5] = { 2494, 1183, 943 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][6] = { 1073, 916, 2894 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE240M][1] = { 2864, 2910, 1024 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE240M][2] = { 1811, 2826, 2903 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE240M][3] = { 1707, 2809, 958 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE240M][4] = { 2408, 926, 2798 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE240M][5] = { 2331, 876, 609 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE240M][6] = { 755, 579, 2773 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE240M][7] = { 507, 507, 507 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_NONE][0] = { 2125, 2125, 2125 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_NONE][1] = { 2039, 2102, 338 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_NONE][2] = { 873, 1987, 2092 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_NONE][3] = { 787, 1965, 305 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_NONE][4] = { 1468, 290, 1949 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_NONE][5] = { 1382, 268, 162 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_NONE][6] = { 216, 152, 1917 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_NONE][7] = { 130, 130, 130 }, }; #else @@ -764,50 +1020,38 @@ static double transfer_srgb_to_rec709(double v) return transfer_rgb_to_rec709(transfer_srgb_to_rgb(v)); } -static void csc(enum v4l2_colorspace colorspace, double *r, double *g, double *b) +static void csc(enum v4l2_colorspace colorspace, enum v4l2_xfer_func xfer_func, + double *r, double *g, double *b) { int clamp = 1; + *r = transfer_srgb_to_rgb(*r); + *g = transfer_srgb_to_rgb(*g); + *b = transfer_srgb_to_rgb(*b); + /* Convert the primaries of Rec. 709 Linear RGB */ switch (colorspace) { case V4L2_COLORSPACE_SMPTE240M: - *r = transfer_srgb_to_rgb(*r); - *g = transfer_srgb_to_rgb(*g); - *b = transfer_srgb_to_rgb(*b); mult_matrix(r, g, b, rec709_to_240m); break; case V4L2_COLORSPACE_SMPTE170M: - *r = transfer_srgb_to_rgb(*r); - *g = transfer_srgb_to_rgb(*g); - *b = transfer_srgb_to_rgb(*b); mult_matrix(r, g, b, rec709_to_170m); break; case V4L2_COLORSPACE_470_SYSTEM_BG: - *r = transfer_srgb_to_rgb(*r); - *g = transfer_srgb_to_rgb(*g); - *b = transfer_srgb_to_rgb(*b); mult_matrix(r, g, b, rec709_to_ebu); break; case V4L2_COLORSPACE_470_SYSTEM_M: - *r = transfer_srgb_to_rgb(*r); - *g = transfer_srgb_to_rgb(*g); - *b = transfer_srgb_to_rgb(*b); mult_matrix(r, g, b, rec709_to_ntsc1953); break; case V4L2_COLORSPACE_ADOBERGB: - *r = transfer_srgb_to_rgb(*r); - *g = transfer_srgb_to_rgb(*g); - *b = transfer_srgb_to_rgb(*b); mult_matrix(r, g, b, rec709_to_adobergb); break; case V4L2_COLORSPACE_BT2020: - *r = transfer_srgb_to_rgb(*r); - *g = transfer_srgb_to_rgb(*g); - *b = transfer_srgb_to_rgb(*b); mult_matrix(r, g, b, rec709_to_bt2020); break; case V4L2_COLORSPACE_SRGB: case V4L2_COLORSPACE_REC709: + break; default: break; } @@ -818,33 +1062,28 @@ static void csc(enum v4l2_colorspace colorspace, double *r, double *g, double *b *b = ((*b) < 0) ? 0 : (((*b) > 1) ? 1 : (*b)); } - /* Encode to gamma corrected colorspace */ - switch (colorspace) { - case V4L2_COLORSPACE_SMPTE240M: - *r = transfer_rgb_to_smpte240m(*r); - *g = transfer_rgb_to_smpte240m(*g); - *b = transfer_rgb_to_smpte240m(*b); - break; - case V4L2_COLORSPACE_SMPTE170M: - case V4L2_COLORSPACE_470_SYSTEM_M: - case V4L2_COLORSPACE_470_SYSTEM_BG: - case V4L2_COLORSPACE_BT2020: + switch (xfer_func) { + case V4L2_XFER_FUNC_709: *r = transfer_rgb_to_rec709(*r); *g = transfer_rgb_to_rec709(*g); *b = transfer_rgb_to_rec709(*b); break; - case V4L2_COLORSPACE_SRGB: + case V4L2_XFER_FUNC_SRGB: + *r = transfer_rgb_to_srgb(*r); + *g = transfer_rgb_to_srgb(*g); + *b = transfer_rgb_to_srgb(*b); break; - case V4L2_COLORSPACE_ADOBERGB: + case V4L2_XFER_FUNC_ADOBERGB: *r = transfer_rgb_to_adobergb(*r); *g = transfer_rgb_to_adobergb(*g); *b = transfer_rgb_to_adobergb(*b); break; - case V4L2_COLORSPACE_REC709: - default: - *r = transfer_srgb_to_rec709(*r); - *g = transfer_srgb_to_rec709(*g); - *b = transfer_srgb_to_rec709(*b); + case V4L2_XFER_FUNC_SMPTE240M: + *r = transfer_rgb_to_smpte240m(*r); + *g = transfer_rgb_to_smpte240m(*g); + *b = transfer_rgb_to_smpte240m(*b); + break; + case V4L2_XFER_FUNC_NONE: break; } } @@ -877,7 +1116,16 @@ int main(int argc, char **argv) "V4L2_COLORSPACE_ADOBERGB", "V4L2_COLORSPACE_BT2020", }; + static const char * const xfer_func_names[] = { + "", + "V4L2_XFER_FUNC_709", + "V4L2_XFER_FUNC_SRGB", + "V4L2_XFER_FUNC_ADOBERGB", + "V4L2_XFER_FUNC_SMPTE240M", + "V4L2_XFER_FUNC_NONE", + }; int i; + int x; int c; printf("/* Generated table */\n"); @@ -905,22 +1153,26 @@ int main(int argc, char **argv) printf("\n};\n\n"); printf("/* Generated table */\n"); - printf("const struct color16 tpg_csc_colors[V4L2_COLORSPACE_BT2020 + 1][TPG_COLOR_CSC_BLACK + 1] = {\n"); + printf("const struct color16 tpg_csc_colors[V4L2_COLORSPACE_BT2020 + 1][V4L2_XFER_FUNC_NONE + 1][TPG_COLOR_CSC_BLACK + 1] = {\n"); for (c = 0; c <= V4L2_COLORSPACE_BT2020; c++) { - for (i = 0; i <= TPG_COLOR_CSC_BLACK; i++) { - double r, g, b; + for (x = 1; x <= V4L2_XFER_FUNC_NONE; x++) { + for (i = 0; i <= TPG_COLOR_CSC_BLACK; i++) { + double r, g, b; - if (colorspaces[c] == 0) - continue; + if (colorspaces[c] == 0) + continue; - r = tpg_colors[i].r / 255.0; - g = tpg_colors[i].g / 255.0; - b = tpg_colors[i].b / 255.0; + r = tpg_colors[i].r / 255.0; + g = tpg_colors[i].g / 255.0; + b = tpg_colors[i].b / 255.0; - csc(c, &r, &g, &b); + csc(c, x, &r, &g, &b); - printf("\t[%s][%d] = { %d, %d, %d },\n", colorspace_names[c], i, - (int)(r * 4080), (int)(g * 4080), (int)(b * 4080)); + printf("\t[%s][%s][%d] = { %d, %d, %d },\n", + colorspace_names[c], + xfer_func_names[x], i, + (int)(r * 4080), (int)(g * 4080), (int)(b * 4080)); + } } } printf("};\n\n"); diff --git a/drivers/media/platform/vivid/vivid-tpg-colors.h b/drivers/media/platform/vivid/vivid-tpg-colors.h index 2c333356451c..86b8bf3fe745 100644 --- a/drivers/media/platform/vivid/vivid-tpg-colors.h +++ b/drivers/media/platform/vivid/vivid-tpg-colors.h @@ -61,6 +61,8 @@ enum tpg_color { extern const struct color tpg_colors[TPG_COLOR_MAX]; extern const unsigned short tpg_rec709_to_linear[255 * 16 + 1]; extern const unsigned short tpg_linear_to_rec709[255 * 16 + 1]; -extern const struct color16 tpg_csc_colors[V4L2_COLORSPACE_BT2020 + 1][TPG_COLOR_CSC_BLACK + 1]; +extern const struct color16 tpg_csc_colors[V4L2_COLORSPACE_BT2020 + 1] + [V4L2_XFER_FUNC_NONE + 1] + [TPG_COLOR_CSC_BLACK + 1]; #endif diff --git a/drivers/media/platform/vivid/vivid-tpg.c b/drivers/media/platform/vivid/vivid-tpg.c index c1883a8533c5..c86c8ffcf9c7 100644 --- a/drivers/media/platform/vivid/vivid-tpg.c +++ b/drivers/media/platform/vivid/vivid-tpg.c @@ -706,9 +706,9 @@ static void precalculate_color(struct tpg_data *tpg, int k) } if (tpg->pattern == TPG_PAT_CSC_COLORBAR && col <= TPG_COLOR_CSC_BLACK) { - r = tpg_csc_colors[tpg->colorspace][col].r; - g = tpg_csc_colors[tpg->colorspace][col].g; - b = tpg_csc_colors[tpg->colorspace][col].b; + r = tpg_csc_colors[tpg->colorspace][tpg->real_xfer_func][col].r; + g = tpg_csc_colors[tpg->colorspace][tpg->real_xfer_func][col].g; + b = tpg_csc_colors[tpg->colorspace][tpg->real_xfer_func][col].b; } else { r <<= 4; g <<= 4; -- cgit v1.2.3-59-g8ed1b From 136a5e9e01ed89d8891845027b3ee731bb662926 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 31 May 2015 06:48:00 -0300 Subject: [media] cobalt: support transfer function Add support for the transfer function to the cobalt driver: make sure it is passed on to/retrieved from the sub-device correctly. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cobalt/cobalt-driver.h | 1 + drivers/media/pci/cobalt/cobalt-v4l2.c | 6 ++++++ 2 files changed, 7 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/pci/cobalt/cobalt-driver.h b/drivers/media/pci/cobalt/cobalt-driver.h index f63ce193a65d..c206df930669 100644 --- a/drivers/media/pci/cobalt/cobalt-driver.h +++ b/drivers/media/pci/cobalt/cobalt-driver.h @@ -231,6 +231,7 @@ struct cobalt_stream { u32 pixfmt; u32 sequence; u32 colorspace; + u32 xfer_func; u32 ycbcr_enc; u32 quantization; diff --git a/drivers/media/pci/cobalt/cobalt-v4l2.c b/drivers/media/pci/cobalt/cobalt-v4l2.c index 8b14bec123eb..72b081f9cde3 100644 --- a/drivers/media/pci/cobalt/cobalt-v4l2.c +++ b/drivers/media/pci/cobalt/cobalt-v4l2.c @@ -170,6 +170,7 @@ static void cobalt_enable_output(struct cobalt_stream *s) } sd_fmt.format.colorspace = s->colorspace; + sd_fmt.format.xfer_func = s->xfer_func; sd_fmt.format.ycbcr_enc = s->ycbcr_enc; sd_fmt.format.quantization = s->quantization; sd_fmt.format.width = bt->width; @@ -737,6 +738,7 @@ static int cobalt_g_fmt_vid_cap(struct file *file, void *priv_fh, v4l2_subdev_call(s->sd, pad, get_fmt, NULL, &sd_fmt); v4l2_fill_pix_format(pix, &sd_fmt.format); pix->colorspace = sd_fmt.format.colorspace; + pix->xfer_func = sd_fmt.format.xfer_func; pix->ycbcr_enc = sd_fmt.format.ycbcr_enc; pix->quantization = sd_fmt.format.quantization; } @@ -782,6 +784,7 @@ static int cobalt_try_fmt_vid_cap(struct file *file, void *priv_fh, v4l2_subdev_call(s->sd, pad, get_fmt, NULL, &sd_fmt); v4l2_fill_pix_format(pix, &sd_fmt.format); pix->colorspace = sd_fmt.format.colorspace; + pix->xfer_func = sd_fmt.format.xfer_func; pix->ycbcr_enc = sd_fmt.format.ycbcr_enc; pix->quantization = sd_fmt.format.quantization; } @@ -897,6 +900,7 @@ static int cobalt_g_fmt_vid_out(struct file *file, void *priv_fh, pix->field = V4L2_FIELD_NONE; pix->pixelformat = s->pixfmt; pix->colorspace = s->colorspace; + pix->xfer_func = s->xfer_func; pix->ycbcr_enc = s->ycbcr_enc; pix->quantization = s->quantization; pix->sizeimage = pix->bytesperline * pix->height; @@ -953,11 +957,13 @@ static int cobalt_s_fmt_vid_out(struct file *file, void *priv_fh, s->stride = pix->bytesperline; s->pixfmt = pix->pixelformat; s->colorspace = pix->colorspace; + s->xfer_func = pix->xfer_func; s->ycbcr_enc = pix->ycbcr_enc; s->quantization = pix->quantization; sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; v4l2_subdev_call(s->sd, pad, get_fmt, NULL, &sd_fmt); sd_fmt.format.colorspace = pix->colorspace; + sd_fmt.format.xfer_func = pix->xfer_func; sd_fmt.format.ycbcr_enc = pix->ycbcr_enc; sd_fmt.format.quantization = pix->quantization; v4l2_subdev_call(s->sd, pad, set_fmt, NULL, &sd_fmt); -- cgit v1.2.3-59-g8ed1b From e1dedcfff1bbaa6b56a40116ee402b6d222e20c9 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 31 May 2015 07:51:51 -0300 Subject: [media] cobalt: simplify colorspace code Simplify cobalt_g/try_fmt_vid_cap by not setting the colorspace fields in pix again (since v4l2_fill_pix_format does that already), and by using v4l2_fill_mbus_format in cobalt_s_fmt_vid_out which allows the get_fmt call to be dropped as well. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cobalt/cobalt-v4l2.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/cobalt/cobalt-v4l2.c b/drivers/media/pci/cobalt/cobalt-v4l2.c index 72b081f9cde3..6fb8812990f4 100644 --- a/drivers/media/pci/cobalt/cobalt-v4l2.c +++ b/drivers/media/pci/cobalt/cobalt-v4l2.c @@ -737,10 +737,6 @@ static int cobalt_g_fmt_vid_cap(struct file *file, void *priv_fh, sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; v4l2_subdev_call(s->sd, pad, get_fmt, NULL, &sd_fmt); v4l2_fill_pix_format(pix, &sd_fmt.format); - pix->colorspace = sd_fmt.format.colorspace; - pix->xfer_func = sd_fmt.format.xfer_func; - pix->ycbcr_enc = sd_fmt.format.ycbcr_enc; - pix->quantization = sd_fmt.format.quantization; } pix->pixelformat = s->pixfmt; @@ -783,10 +779,6 @@ static int cobalt_try_fmt_vid_cap(struct file *file, void *priv_fh, sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; v4l2_subdev_call(s->sd, pad, get_fmt, NULL, &sd_fmt); v4l2_fill_pix_format(pix, &sd_fmt.format); - pix->colorspace = sd_fmt.format.colorspace; - pix->xfer_func = sd_fmt.format.xfer_func; - pix->ycbcr_enc = sd_fmt.format.ycbcr_enc; - pix->quantization = sd_fmt.format.quantization; } switch (pix->pixelformat) { @@ -933,6 +925,7 @@ static int cobalt_s_fmt_vid_out(struct file *file, void *priv_fh, struct cobalt_stream *s = video_drvdata(file); struct v4l2_pix_format *pix = &f->fmt.pix; struct v4l2_subdev_format sd_fmt = { 0 }; + u32 code; if (cobalt_try_fmt_vid_out(file, priv_fh, f)) return -EINVAL; @@ -945,9 +938,11 @@ static int cobalt_s_fmt_vid_out(struct file *file, void *priv_fh, switch (pix->pixelformat) { case V4L2_PIX_FMT_YUYV: s->bpp = COBALT_BYTES_PER_PIXEL_YUYV; + code = MEDIA_BUS_FMT_UYVY8_1X16; break; case V4L2_PIX_FMT_BGR32: s->bpp = COBALT_BYTES_PER_PIXEL_RGB32; + code = MEDIA_BUS_FMT_RGB888_1X24; break; default: return -EINVAL; @@ -961,11 +956,7 @@ static int cobalt_s_fmt_vid_out(struct file *file, void *priv_fh, s->ycbcr_enc = pix->ycbcr_enc; s->quantization = pix->quantization; sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; - v4l2_subdev_call(s->sd, pad, get_fmt, NULL, &sd_fmt); - sd_fmt.format.colorspace = pix->colorspace; - sd_fmt.format.xfer_func = pix->xfer_func; - sd_fmt.format.ycbcr_enc = pix->ycbcr_enc; - sd_fmt.format.quantization = pix->quantization; + v4l2_fill_mbus_format(&sd_fmt.format, pix, code); v4l2_subdev_call(s->sd, pad, set_fmt, NULL, &sd_fmt); return 0; } -- cgit v1.2.3-59-g8ed1b From c70316f2a193fcd62232cddc1b2d44997ca2c930 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 5 Jun 2015 13:09:31 -0300 Subject: [media] vivid: move PRINTSTR to separate functions Commit 84cb7be43cec12868e94163c99fdc34c0297c3b8 broke vivid-tpg (uninitialized variable p). This patch takes a different approach: four different functions are created, one for each PRINTSTR version. In order to avoid the 'the frame size of 1308 bytes is larger than 1024 bytes' warning I had to mark those functions with 'noinline'. For whatever reason gcc seems to inline this aggressively and it is doing weird things with the stack. I tried to read the assembly code, but I couldn't see what exactly it was doing on the stack. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-tpg.c | 128 +++++++++++++++++++------------ 1 file changed, 81 insertions(+), 47 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/vivid/vivid-tpg.c b/drivers/media/platform/vivid/vivid-tpg.c index c86c8ffcf9c7..32ebf0d90d10 100644 --- a/drivers/media/platform/vivid/vivid-tpg.c +++ b/drivers/media/platform/vivid/vivid-tpg.c @@ -1462,40 +1462,10 @@ static void tpg_precalculate_line(struct tpg_data *tpg) /* need this to do rgb24 rendering */ typedef struct { u16 __; u8 _; } __packed x24; -void tpg_gen_text(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2], - int y, int x, char *text) -{ - int line; - unsigned step = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1; - unsigned div = step; - unsigned first = 0; - unsigned len = strlen(text); - unsigned p; - - if (font8x16 == NULL || basep == NULL) - return; - - /* Checks if it is possible to show string */ - if (y + 16 >= tpg->compose.height || x + 8 >= tpg->compose.width) - return; - - if (len > (tpg->compose.width - x) / 8) - len = (tpg->compose.width - x) / 8; - if (tpg->vflip) - y = tpg->compose.height - y - 16; - if (tpg->hflip) - x = tpg->compose.width - x - 8; - y += tpg->compose.top; - x += tpg->compose.left; - if (tpg->field == V4L2_FIELD_BOTTOM) - first = 1; - else if (tpg->field == V4L2_FIELD_SEQ_TB || tpg->field == V4L2_FIELD_SEQ_BT) - div = 2; - - /* Print text */ -#define PRINTSTR(PIXTYPE) for (p = 0; p < tpg->planes; p++) { \ - unsigned vdiv = tpg->vdownsampling[p]; \ - unsigned hdiv = tpg->hdownsampling[p]; \ +#define PRINTSTR(PIXTYPE) do { \ + unsigned vdiv = tpg->vdownsampling[p]; \ + unsigned hdiv = tpg->hdownsampling[p]; \ + int line; \ PIXTYPE fg; \ PIXTYPE bg; \ memcpy(&fg, tpg->textfg[p], sizeof(PIXTYPE)); \ @@ -1546,19 +1516,83 @@ void tpg_gen_text(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2], } \ } while (0) - switch (tpg->twopixelsize[p]) { - case 2: - PRINTSTR(u8); - break; - case 4: - PRINTSTR(u16); - break; - case 6: - PRINTSTR(x24); - break; - case 8: - PRINTSTR(u32); - break; +static noinline void tpg_print_str_2(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2], + unsigned p, unsigned first, unsigned div, unsigned step, + int y, int x, char *text, unsigned len) +{ + PRINTSTR(u8); +} + +static noinline void tpg_print_str_4(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2], + unsigned p, unsigned first, unsigned div, unsigned step, + int y, int x, char *text, unsigned len) +{ + PRINTSTR(u16); +} + +static noinline void tpg_print_str_6(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2], + unsigned p, unsigned first, unsigned div, unsigned step, + int y, int x, char *text, unsigned len) +{ + PRINTSTR(x24); +} + +static noinline void tpg_print_str_8(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2], + unsigned p, unsigned first, unsigned div, unsigned step, + int y, int x, char *text, unsigned len) +{ + PRINTSTR(u32); +} + +void tpg_gen_text(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2], + int y, int x, char *text) +{ + unsigned step = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1; + unsigned div = step; + unsigned first = 0; + unsigned len = strlen(text); + unsigned p; + + if (font8x16 == NULL || basep == NULL) + return; + + /* Checks if it is possible to show string */ + if (y + 16 >= tpg->compose.height || x + 8 >= tpg->compose.width) + return; + + if (len > (tpg->compose.width - x) / 8) + len = (tpg->compose.width - x) / 8; + if (tpg->vflip) + y = tpg->compose.height - y - 16; + if (tpg->hflip) + x = tpg->compose.width - x - 8; + y += tpg->compose.top; + x += tpg->compose.left; + if (tpg->field == V4L2_FIELD_BOTTOM) + first = 1; + else if (tpg->field == V4L2_FIELD_SEQ_TB || tpg->field == V4L2_FIELD_SEQ_BT) + div = 2; + + for (p = 0; p < tpg->planes; p++) { + /* Print text */ + switch (tpg->twopixelsize[p]) { + case 2: + tpg_print_str_2(tpg, basep, p, first, div, step, y, x, + text, len); + break; + case 4: + tpg_print_str_4(tpg, basep, p, first, div, step, y, x, + text, len); + break; + case 6: + tpg_print_str_6(tpg, basep, p, first, div, step, y, x, + text, len); + break; + case 8: + tpg_print_str_8(tpg, basep, p, first, div, step, y, x, + text, len); + break; + } } } -- cgit v1.2.3-59-g8ed1b From d69abb79e123c111966fb41fe3c21533e2162f1a Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 16 Apr 2015 11:46:24 -0300 Subject: [media] tda10071: implement I2C client bindings Implement I2C client bindings. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/tda10071.c | 95 +++++++++++++++++++++++++++++ drivers/media/dvb-frontends/tda10071.h | 29 +++++++++ drivers/media/dvb-frontends/tda10071_priv.h | 1 + 3 files changed, 125 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/tda10071.c b/drivers/media/dvb-frontends/tda10071.c index 4a19b85995f1..31328540e5c4 100644 --- a/drivers/media/dvb-frontends/tda10071.c +++ b/drivers/media/dvb-frontends/tda10071.c @@ -1313,6 +1313,101 @@ static struct dvb_frontend_ops tda10071_ops = { .set_voltage = tda10071_set_voltage, }; +static struct dvb_frontend *tda10071_get_dvb_frontend(struct i2c_client *client) +{ + struct tda10071_priv *dev = i2c_get_clientdata(client); + + dev_dbg(&client->dev, "\n"); + + return &dev->fe; +} + +static int tda10071_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct tda10071_priv *dev; + struct tda10071_platform_data *pdata = client->dev.platform_data; + int ret; + u8 u8tmp; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) { + ret = -ENOMEM; + goto err; + } + + dev->client = client; + dev->i2c = client->adapter; + dev->cfg.demod_i2c_addr = client->addr; + dev->cfg.i2c_wr_max = pdata->i2c_wr_max; + dev->cfg.ts_mode = pdata->ts_mode; + dev->cfg.spec_inv = pdata->spec_inv; + dev->cfg.xtal = pdata->clk; + dev->cfg.pll_multiplier = pdata->pll_multiplier; + dev->cfg.tuner_i2c_addr = pdata->tuner_i2c_addr; + + /* chip ID */ + ret = tda10071_rd_reg(dev, 0xff, &u8tmp); + if (ret || u8tmp != 0x0f) + goto err_kfree; + + /* chip type */ + ret = tda10071_rd_reg(dev, 0xdd, &u8tmp); + if (ret || u8tmp != 0x00) + goto err_kfree; + + /* chip version */ + ret = tda10071_rd_reg(dev, 0xfe, &u8tmp); + if (ret || u8tmp != 0x01) + goto err_kfree; + + /* create dvb_frontend */ + memcpy(&dev->fe.ops, &tda10071_ops, sizeof(struct dvb_frontend_ops)); + dev->fe.ops.release = NULL; + dev->fe.demodulator_priv = dev; + i2c_set_clientdata(client, dev); + + /* setup callbacks */ + pdata->get_dvb_frontend = tda10071_get_dvb_frontend; + + dev_info(&client->dev, "NXP TDA10071 successfully identified\n"); + return 0; +err_kfree: + kfree(dev); +err: + dev_dbg(&client->dev, "failed=%d\n", ret); + return ret; +} + +static int tda10071_remove(struct i2c_client *client) +{ + struct tda10071_dev *dev = i2c_get_clientdata(client); + + dev_dbg(&client->dev, "\n"); + + kfree(dev); + return 0; +} + +static const struct i2c_device_id tda10071_id_table[] = { + {"tda10071_cx24118", 0}, + {} +}; +MODULE_DEVICE_TABLE(i2c, tda10071_id_table); + +static struct i2c_driver tda10071_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "tda10071", + .suppress_bind_attrs = true, + }, + .probe = tda10071_probe, + .remove = tda10071_remove, + .id_table = tda10071_id_table, +}; + +module_i2c_driver(tda10071_driver); + MODULE_AUTHOR("Antti Palosaari "); MODULE_DESCRIPTION("NXP TDA10071 DVB-S/S2 demodulator driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb-frontends/tda10071.h b/drivers/media/dvb-frontends/tda10071.h index da89f4249846..0ffbfa5b2dfb 100644 --- a/drivers/media/dvb-frontends/tda10071.h +++ b/drivers/media/dvb-frontends/tda10071.h @@ -24,6 +24,35 @@ #include #include +/* + * I2C address + * 0x55, + */ + +/** + * struct tda10071_platform_data - Platform data for the tda10071 driver + * @clk: Clock frequency. + * @i2c_wr_max: Max bytes I2C adapter can write at once. + * @ts_mode: TS mode. + * @spec_inv: Input spectrum inversion. + * @pll_multiplier: PLL multiplier. + * @tuner_i2c_addr: CX24118A tuner I2C address (0x14, 0x54, ...). + * @get_dvb_frontend: Get DVB frontend. + */ + +struct tda10071_platform_data { + u32 clk; + u16 i2c_wr_max; +#define TDA10071_TS_SERIAL 0 +#define TDA10071_TS_PARALLEL 1 + u8 ts_mode; + bool spec_inv; + u8 pll_multiplier; + u8 tuner_i2c_addr; + + struct dvb_frontend* (*get_dvb_frontend)(struct i2c_client *); +}; + struct tda10071_config { /* Demodulator I2C address. * Default: none, must set diff --git a/drivers/media/dvb-frontends/tda10071_priv.h b/drivers/media/dvb-frontends/tda10071_priv.h index 03f839c431e9..7ec69ac510d7 100644 --- a/drivers/media/dvb-frontends/tda10071_priv.h +++ b/drivers/media/dvb-frontends/tda10071_priv.h @@ -28,6 +28,7 @@ struct tda10071_priv { struct i2c_adapter *i2c; struct dvb_frontend fe; + struct i2c_client *client; struct tda10071_config cfg; u8 meas_count[2]; -- cgit v1.2.3-59-g8ed1b From b561baec11a49b557530736c2a7604a0232f281b Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 16 Apr 2015 13:28:39 -0300 Subject: [media] a8293: implement I2C client bindings Implement I2C client bindings. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/a8293.c | 87 +++++++++++++++++++++++++++++++++++-- drivers/media/dvb-frontends/a8293.h | 15 +++++++ 2 files changed, 99 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/a8293.c b/drivers/media/dvb-frontends/a8293.c index 780da58132f1..3f0cf9ee6672 100644 --- a/drivers/media/dvb-frontends/a8293.c +++ b/drivers/media/dvb-frontends/a8293.c @@ -22,8 +22,9 @@ #include "a8293.h" struct a8293_priv { + u8 i2c_addr; struct i2c_adapter *i2c; - const struct a8293_config *cfg; + struct i2c_client *client; u8 reg[2]; }; @@ -32,7 +33,7 @@ static int a8293_i2c(struct a8293_priv *priv, u8 *val, int len, bool rd) int ret; struct i2c_msg msg[1] = { { - .addr = priv->cfg->i2c_addr, + .addr = priv->i2c_addr, .len = len, .buf = val, } @@ -128,7 +129,7 @@ struct dvb_frontend *a8293_attach(struct dvb_frontend *fe, /* setup the priv */ priv->i2c = i2c; - priv->cfg = cfg; + priv->i2c_addr = cfg->i2c_addr; fe->sec_priv = priv; /* check if the SEC is there */ @@ -164,6 +165,86 @@ err: } EXPORT_SYMBOL(a8293_attach); +static int a8293_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct a8293_priv *dev; + struct a8293_platform_data *pdata = client->dev.platform_data; + struct dvb_frontend *fe = pdata->dvb_frontend; + int ret; + u8 buf[2]; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) { + ret = -ENOMEM; + goto err; + } + + dev->client = client; + dev->i2c = client->adapter; + dev->i2c_addr = client->addr; + + /* check if the SEC is there */ + ret = a8293_rd(dev, buf, 2); + if (ret) + goto err_kfree; + + /* ENB=0 */ + dev->reg[0] = 0x10; + ret = a8293_wr(dev, &dev->reg[0], 1); + if (ret) + goto err_kfree; + + /* TMODE=0, TGATE=1 */ + dev->reg[1] = 0x82; + ret = a8293_wr(dev, &dev->reg[1], 1); + if (ret) + goto err_kfree; + + /* override frontend ops */ + fe->ops.set_voltage = a8293_set_voltage; + + fe->sec_priv = dev; + i2c_set_clientdata(client, dev); + + dev_info(&client->dev, "Allegro A8293 SEC successfully attached\n"); + return 0; +err_kfree: + kfree(dev); +err: + dev_dbg(&client->dev, "failed=%d\n", ret); + return ret; +} + +static int a8293_remove(struct i2c_client *client) +{ + struct a8293_dev *dev = i2c_get_clientdata(client); + + dev_dbg(&client->dev, "\n"); + + kfree(dev); + return 0; +} + +static const struct i2c_device_id a8293_id_table[] = { + {"a8293", 0}, + {} +}; +MODULE_DEVICE_TABLE(i2c, a8293_id_table); + +static struct i2c_driver a8293_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "a8293", + .suppress_bind_attrs = true, + }, + .probe = a8293_probe, + .remove = a8293_remove, + .id_table = a8293_id_table, +}; + +module_i2c_driver(a8293_driver); + MODULE_AUTHOR("Antti Palosaari "); MODULE_DESCRIPTION("Allegro A8293 SEC driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb-frontends/a8293.h b/drivers/media/dvb-frontends/a8293.h index 5f0411939ffc..aff36538f582 100644 --- a/drivers/media/dvb-frontends/a8293.h +++ b/drivers/media/dvb-frontends/a8293.h @@ -21,8 +21,23 @@ #ifndef A8293_H #define A8293_H +#include "dvb_frontend.h" #include +/* + * I2C address + * 0x08, 0x09, 0x0a, 0x0b + */ + +/** + * struct a8293_platform_data - Platform data for the a8293 driver + * @dvb_frontend: DVB frontend. + */ +struct a8293_platform_data { + struct dvb_frontend *dvb_frontend; +}; + + struct a8293_config { u8 i2c_addr; }; -- cgit v1.2.3-59-g8ed1b From 7098f582e07b8cc976a0168cf19ce2219cf76d80 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 16 Apr 2015 13:33:07 -0300 Subject: [media] em28xx: add support for DVB SEC I2C client Add support for DVB SEC (satellite equipment controller) I2C client. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-dvb.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index 5b7c7c888274..ef1bfa2606fc 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -96,6 +96,7 @@ struct em28xx_dvb { int lna_gpio; struct i2c_client *i2c_client_demod; struct i2c_client *i2c_client_tuner; + struct i2c_client *i2c_client_sec; }; static inline void print_err_status(struct em28xx *dev, @@ -1729,7 +1730,6 @@ static int em28xx_dvb_fini(struct em28xx *dev) em28xx_info("Closing DVB extension\n"); dvb = dev->dvb; - client = dvb->i2c_client_tuner; em28xx_uninit_usb_xfer(dev, EM28XX_DIGITAL_MODE); @@ -1746,7 +1746,15 @@ static int em28xx_dvb_fini(struct em28xx *dev) } } + /* remove I2C SEC */ + client = dvb->i2c_client_sec; + if (client) { + module_put(client->dev.driver->owner); + i2c_unregister_device(client); + } + /* remove I2C tuner */ + client = dvb->i2c_client_tuner; if (client) { module_put(client->dev.driver->owner); i2c_unregister_device(client); -- cgit v1.2.3-59-g8ed1b From 8022f9afcd876c54252d2d1ef5c59769adb2c2b1 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 16 Apr 2015 13:43:30 -0300 Subject: [media] em28xx: bind PCTV 460e using I2C client Load PCTV 460e tda10071 demod and a8293 SEC using I2C client bindings. Remove old unused tda10071 config struct. We are using I2C platform data now. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-dvb.c | 68 ++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 17 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index ef1bfa2606fc..be0abca04fb4 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -808,16 +808,6 @@ static struct tda18271_config em28xx_cxd2820r_tda18271_config = { .gate = TDA18271_GATE_DIGITAL, }; -static const struct tda10071_config em28xx_tda10071_config = { - .demod_i2c_addr = 0x55, /* (0xaa >> 1) */ - .tuner_i2c_addr = 0x14, - .i2c_wr_max = 64, - .ts_mode = TDA10071_TS_SERIAL, - .spec_inv = 0, - .xtal = 40444000, /* 40.444 MHz */ - .pll_multiplier = 20, -}; - static const struct a8293_config em28xx_a8293_config = { .i2c_addr = 0x08, /* (0x10 >> 1) */ }; @@ -1332,16 +1322,60 @@ static int em28xx_dvb_init(struct em28xx *dev) &dev->i2c_adap[dev->def_i2c_bus], &c3tech_duo_tda18271_config); break; - case EM28174_BOARD_PCTV_460E: - /* attach demod */ - dvb->fe[0] = dvb_attach(tda10071_attach, - &em28xx_tda10071_config, &dev->i2c_adap[dev->def_i2c_bus]); + case EM28174_BOARD_PCTV_460E: { + struct i2c_client *client; + struct i2c_board_info board_info; + struct tda10071_platform_data tda10071_pdata = {}; + struct a8293_platform_data a8293_pdata = {}; + + /* attach demod + tuner combo */ + tda10071_pdata.clk = 40444000, /* 40.444 MHz */ + tda10071_pdata.i2c_wr_max = 64, + tda10071_pdata.ts_mode = TDA10071_TS_SERIAL, + tda10071_pdata.pll_multiplier = 20, + tda10071_pdata.tuner_i2c_addr = 0x14, + memset(&board_info, 0, sizeof(board_info)); + strlcpy(board_info.type, "tda10071_cx24118", I2C_NAME_SIZE); + board_info.addr = 0x55; + board_info.platform_data = &tda10071_pdata; + request_module("tda10071"); + client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info); + if (client == NULL || client->dev.driver == NULL) { + result = -ENODEV; + goto out_free; + } + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + result = -ENODEV; + goto out_free; + } + dvb->fe[0] = tda10071_pdata.get_dvb_frontend(client); + dvb->i2c_client_demod = client; /* attach SEC */ - if (dvb->fe[0]) - dvb_attach(a8293_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus], - &em28xx_a8293_config); + a8293_pdata.dvb_frontend = dvb->fe[0]; + memset(&board_info, 0, sizeof(board_info)); + strlcpy(board_info.type, "a8293", I2C_NAME_SIZE); + board_info.addr = 0x08; + board_info.platform_data = &a8293_pdata; + request_module("a8293"); + client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info); + if (client == NULL || client->dev.driver == NULL) { + module_put(dvb->i2c_client_demod->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_demod); + result = -ENODEV; + goto out_free; + } + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + module_put(dvb->i2c_client_demod->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_demod); + result = -ENODEV; + goto out_free; + } + dvb->i2c_client_sec = client; break; + } case EM2874_BOARD_DELOCK_61959: case EM2874_BOARD_MAXMEDIA_UB425_TC: /* attach demodulator */ -- cgit v1.2.3-59-g8ed1b From bf5e3ef0ccf241ab85be9fa99cc26893249a94e5 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 16 Apr 2015 13:59:46 -0300 Subject: [media] cx23885: add support for DVB I2C SEC client Add support for I2C SEC (satellite equipment controller) client. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-dvb.c | 16 ++++++++++++++++ drivers/media/pci/cx23885/cx23885.h | 1 + 2 files changed, 17 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 37fd013c385b..ac062a50286c 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -1190,6 +1190,7 @@ static int dvb_register(struct cx23885_tsport *port) struct i2c_board_info info; struct i2c_adapter *adapter; struct i2c_client *client_demod = NULL, *client_tuner = NULL; + struct i2c_client *client_sec = NULL; const struct m88ds3103_config *p_m88ds3103_config = NULL; int (*p_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage) = NULL; int mfe_shared = 0; /* bus not shared by default */ @@ -2242,6 +2243,14 @@ static int dvb_register(struct cx23885_tsport *port) return 0; frontend_detach: + /* remove I2C client for SEC */ + client_sec = port->i2c_client_sec; + if (client_sec) { + module_put(client_sec->dev.driver->owner); + i2c_unregister_device(client_sec); + port->i2c_client_sec = NULL; + } + /* remove I2C client for tuner */ client_tuner = port->i2c_client_tuner; if (client_tuner) { @@ -2343,6 +2352,13 @@ int cx23885_dvb_unregister(struct cx23885_tsport *port) i2c_unregister_device(client); } + /* remove I2C client for SEC */ + client = port->i2c_client_sec; + if (client) { + module_put(client->dev.driver->owner); + i2c_unregister_device(client); + } + /* remove I2C client for tuner */ client = port->i2c_client_tuner; if (client) { diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h index aeda8d3990ae..81e25194986b 100644 --- a/drivers/media/pci/cx23885/cx23885.h +++ b/drivers/media/pci/cx23885/cx23885.h @@ -304,6 +304,7 @@ struct cx23885_tsport { struct i2c_client *i2c_client_demod; struct i2c_client *i2c_client_tuner; + struct i2c_client *i2c_client_sec; struct i2c_client *i2c_client_ci; int (*set_frontend)(struct dvb_frontend *fe); -- cgit v1.2.3-59-g8ed1b From 49bf0e67382a9ece55b9693bf0d7c6c64afbbc8e Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 20 Apr 2015 14:48:33 -0300 Subject: [media] cx23885: Hauppauge WinTV Starburst bind I2C demod and SEC Bind tda10071 demod and a8293 SEC using I2C binding. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-dvb.c | 52 ++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index ac062a50286c..4c41e1130f98 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -866,6 +866,14 @@ static const struct tda10071_config hauppauge_tda10071_config = { .pll_multiplier = 20, }; +static const struct tda10071_platform_data hauppauge_tda10071_pdata = { + .clk = 40444000, /* 40.444 MHz */ + .i2c_wr_max = 64, + .ts_mode = TDA10071_TS_SERIAL, + .pll_multiplier = 20, + .tuner_i2c_addr = 0x54, +}; + static const struct a8293_config hauppauge_a8293_config = { .i2c_addr = 0x0b, }; @@ -1830,17 +1838,45 @@ static int dvb_register(struct cx23885_tsport *port) break; } break; - case CX23885_BOARD_HAUPPAUGE_STARBURST: + case CX23885_BOARD_HAUPPAUGE_STARBURST: { + struct tda10071_platform_data tda10071_pdata = hauppauge_tda10071_pdata; + struct a8293_platform_data a8293_pdata = {}; + i2c_bus = &dev->i2c_bus[0]; - fe0->dvb.frontend = dvb_attach(tda10071_attach, - &hauppauge_tda10071_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(a8293_attach, fe0->dvb.frontend, - &i2c_bus->i2c_adap, - &hauppauge_a8293_config); + + /* attach demod + tuner combo */ + memset(&info, 0, sizeof(info)); + strlcpy(info.type, "tda10071_cx24118", I2C_NAME_SIZE); + info.addr = 0x05; + info.platform_data = &tda10071_pdata; + request_module("tda10071"); + client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info); + if (!client_demod || !client_demod->dev.driver) + goto frontend_detach; + if (!try_module_get(client_demod->dev.driver->owner)) { + i2c_unregister_device(client_demod); + goto frontend_detach; } + fe0->dvb.frontend = tda10071_pdata.get_dvb_frontend(client_demod); + port->i2c_client_demod = client_demod; + + /* attach SEC */ + a8293_pdata.dvb_frontend = fe0->dvb.frontend; + memset(&info, 0, sizeof(info)); + strlcpy(info.type, "a8293", I2C_NAME_SIZE); + info.addr = 0x0b; + info.platform_data = &a8293_pdata; + request_module("a8293"); + client_sec = i2c_new_device(&i2c_bus->i2c_adap, &info); + if (!client_sec || !client_sec->dev.driver) + goto frontend_detach; + if (!try_module_get(client_sec->dev.driver->owner)) { + i2c_unregister_device(client_sec); + goto frontend_detach; + } + port->i2c_client_sec = client_sec; break; + } case CX23885_BOARD_DVBSKY_T9580: case CX23885_BOARD_DVBSKY_S950: i2c_bus = &dev->i2c_bus[0]; -- cgit v1.2.3-59-g8ed1b From a4569507039ba5bebe8fdfb9e9b0358b38b17588 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 20 Apr 2015 15:01:51 -0300 Subject: [media] cx23885: Hauppauge WinTV-HVR4400/HVR5500 bind I2C demod and SEC Bind tda10071 demod and a8293 SEC using I2C binding. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-dvb.c | 54 +++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 19 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 4c41e1130f98..ef1ebcb0420b 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -856,16 +856,6 @@ static struct mt2063_config terratec_mt2063_config[] = { }, }; -static const struct tda10071_config hauppauge_tda10071_config = { - .demod_i2c_addr = 0x05, - .tuner_i2c_addr = 0x54, - .i2c_wr_max = 64, - .ts_mode = TDA10071_TS_SERIAL, - .spec_inv = 0, - .xtal = 40444000, /* 40.444 MHz */ - .pll_multiplier = 20, -}; - static const struct tda10071_platform_data hauppauge_tda10071_pdata = { .clk = 40444000, /* 40.444 MHz */ .i2c_wr_max = 64, @@ -1806,21 +1796,46 @@ static int dvb_register(struct cx23885_tsport *port) fe0->dvb.frontend->ops.set_voltage = p8000_set_voltage; break; - case CX23885_BOARD_HAUPPAUGE_HVR4400: + case CX23885_BOARD_HAUPPAUGE_HVR4400: { + struct tda10071_platform_data tda10071_pdata = hauppauge_tda10071_pdata; + struct a8293_platform_data a8293_pdata = {}; + i2c_bus = &dev->i2c_bus[0]; i2c_bus2 = &dev->i2c_bus[1]; switch (port->nr) { /* port b */ case 1: - fe0->dvb.frontend = dvb_attach(tda10071_attach, - &hauppauge_tda10071_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend == NULL) - break; - if (!dvb_attach(a8293_attach, fe0->dvb.frontend, - &i2c_bus->i2c_adap, - &hauppauge_a8293_config)) + /* attach demod + tuner combo */ + memset(&info, 0, sizeof(info)); + strlcpy(info.type, "tda10071_cx24118", I2C_NAME_SIZE); + info.addr = 0x05; + info.platform_data = &tda10071_pdata; + request_module("tda10071"); + client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info); + if (!client_demod || !client_demod->dev.driver) + goto frontend_detach; + if (!try_module_get(client_demod->dev.driver->owner)) { + i2c_unregister_device(client_demod); + goto frontend_detach; + } + fe0->dvb.frontend = tda10071_pdata.get_dvb_frontend(client_demod); + port->i2c_client_demod = client_demod; + + /* attach SEC */ + a8293_pdata.dvb_frontend = fe0->dvb.frontend; + memset(&info, 0, sizeof(info)); + strlcpy(info.type, "a8293", I2C_NAME_SIZE); + info.addr = 0x0b; + info.platform_data = &a8293_pdata; + request_module("a8293"); + client_sec = i2c_new_device(&i2c_bus->i2c_adap, &info); + if (!client_sec || !client_sec->dev.driver) goto frontend_detach; + if (!try_module_get(client_sec->dev.driver->owner)) { + i2c_unregister_device(client_sec); + goto frontend_detach; + } + port->i2c_client_sec = client_sec; break; /* port c */ case 2: @@ -1838,6 +1853,7 @@ static int dvb_register(struct cx23885_tsport *port) break; } break; + } case CX23885_BOARD_HAUPPAUGE_STARBURST: { struct tda10071_platform_data tda10071_pdata = hauppauge_tda10071_pdata; struct a8293_platform_data a8293_pdata = {}; -- cgit v1.2.3-59-g8ed1b From 49b7cb5da1867511f10ca9fb7be44c0b2c6a79ee Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 20 Apr 2015 17:08:01 -0300 Subject: [media] cx23885: Hauppauge WinTV-HVR5525 bind I2C SEC Bind a8293 SEC using I2C binding. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-dvb.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index ef1ebcb0420b..9f377ad5e845 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -864,10 +864,6 @@ static const struct tda10071_platform_data hauppauge_tda10071_pdata = { .tuner_i2c_addr = 0x54, }; -static const struct a8293_config hauppauge_a8293_config = { - .i2c_addr = 0x0b, -}; - static const struct si2165_config hauppauge_hvr4400_si2165_config = { .i2c_addr = 0x64, .chip_mode = SI2165_MODE_PLL_XTAL, @@ -2167,6 +2163,7 @@ static int dvb_register(struct cx23885_tsport *port) case CX23885_BOARD_HAUPPAUGE_HVR5525: switch (port->nr) { struct m88rs6000t_config m88rs6000t_config; + struct a8293_platform_data a8293_pdata = {}; /* port b - satellite */ case 1: @@ -2178,10 +2175,20 @@ static int dvb_register(struct cx23885_tsport *port) break; /* attach SEC */ - if (!dvb_attach(a8293_attach, fe0->dvb.frontend, - &dev->i2c_bus[0].i2c_adap, - &hauppauge_a8293_config)) + a8293_pdata.dvb_frontend = fe0->dvb.frontend; + memset(&info, 0, sizeof(info)); + strlcpy(info.type, "a8293", I2C_NAME_SIZE); + info.addr = 0x0b; + info.platform_data = &a8293_pdata; + request_module("a8293"); + client_sec = i2c_new_device(&dev->i2c_bus[0].i2c_adap, &info); + if (!client_sec || !client_sec->dev.driver) goto frontend_detach; + if (!try_module_get(client_sec->dev.driver->owner)) { + i2c_unregister_device(client_sec); + goto frontend_detach; + } + port->i2c_client_sec = client_sec; /* attach tuner */ memset(&m88rs6000t_config, 0, sizeof(m88rs6000t_config)); -- cgit v1.2.3-59-g8ed1b From 7a60743f347c9d03811c5a2b9aa92431be19e512 Mon Sep 17 00:00:00 2001 From: Nikhil Devshatwar Date: Tue, 5 May 2015 10:49:59 -0300 Subject: [media] v4l: of: Correct pclk-sample for BT656 bus Current v4l2_of_parse_parallel_bus function attempts to parse the DT properties for the parallel bus as well as BT656 bus. If the pclk-sample property is defined for the BT656 bus, it is still marked as a parallel bus. Fix this by parsing the pclk after the bus_type is selected. Only when hsync or vsync properties are specified, the bus_type should be set to V4L2_MBUS_PARALLEL. Signed-off-by: Nikhil Devshatwar Acked-by: Sylwester Nawrocki Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-of.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/v4l2-of.c b/drivers/media/v4l2-core/v4l2-of.c index c52fb9620e11..b27cbb1f5afe 100644 --- a/drivers/media/v4l2-core/v4l2-of.c +++ b/drivers/media/v4l2-core/v4l2-of.c @@ -93,10 +93,6 @@ static void v4l2_of_parse_parallel_bus(const struct device_node *node, flags |= v ? V4L2_MBUS_VSYNC_ACTIVE_HIGH : V4L2_MBUS_VSYNC_ACTIVE_LOW; - if (!of_property_read_u32(node, "pclk-sample", &v)) - flags |= v ? V4L2_MBUS_PCLK_SAMPLE_RISING : - V4L2_MBUS_PCLK_SAMPLE_FALLING; - if (!of_property_read_u32(node, "field-even-active", &v)) flags |= v ? V4L2_MBUS_FIELD_EVEN_HIGH : V4L2_MBUS_FIELD_EVEN_LOW; @@ -105,6 +101,10 @@ static void v4l2_of_parse_parallel_bus(const struct device_node *node, else endpoint->bus_type = V4L2_MBUS_BT656; + if (!of_property_read_u32(node, "pclk-sample", &v)) + flags |= v ? V4L2_MBUS_PCLK_SAMPLE_RISING : + V4L2_MBUS_PCLK_SAMPLE_FALLING; + if (!of_property_read_u32(node, "data-active", &v)) flags |= v ? V4L2_MBUS_DATA_ACTIVE_HIGH : V4L2_MBUS_DATA_ACTIVE_LOW; -- cgit v1.2.3-59-g8ed1b From 4aed283c0f7c2b60dc211d2ab8966b3e8c0dddf7 Mon Sep 17 00:00:00 2001 From: Juergen Gier Date: Thu, 14 May 2015 08:55:04 -0300 Subject: [media] saa7134: switch tuner FMD1216ME_MK3 to analog The tuner FMD1216ME_MK3 suffers the same problem as FMD1216MEX_MK3, as described in saa7134-cards.c (disabled IF, enabled DVB-T). The card does work under MS Windows, after soft reboot into Linux it continues to work, only then tda9887 is loaded as well. I copied the relevant code from the BEHOLD_H6 section to MD7134. The CTX946 TV card doesn't detect a signal after cold boot, seems Signed-off-by: Juergen Gier Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-cards.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c index 9fac6a9b7937..c52032940af6 100644 --- a/drivers/media/pci/saa7134/saa7134-cards.c +++ b/drivers/media/pci/saa7134/saa7134-cards.c @@ -7798,10 +7798,11 @@ int saa7134_board_init2(struct saa7134_dev *dev) case SAA7134_BOARD_MD7134: { u8 subaddr; - u8 data[3]; + u8 data[3], data1[] = { 0x09, 0x9f, 0x86, 0x11}; int ret, tuner_t; - struct i2c_msg msg[] = {{.addr=0x50, .flags=0, .buf=&subaddr, .len = 1}, - {.addr=0x50, .flags=I2C_M_RD, .buf=data, .len = 3}}; + struct i2c_msg msg[] = {{.addr = 0x50, .flags = 0, .buf = &subaddr, .len = 1}, + {.addr = 0x50, .flags = I2C_M_RD, .buf = data, .len = 3}}, + msg1 = {.addr = 0x61, .flags = 0, .buf = data1, .len = sizeof(data1)}; subaddr= 0x14; tuner_t = 0; @@ -7856,6 +7857,16 @@ int saa7134_board_init2(struct saa7134_dev *dev) } pr_info("%s Tuner type is %d\n", dev->name, dev->tuner_type); + + /* The tuner TUNER_PHILIPS_FMD1216ME_MK3 after hardware */ + /* start has disabled IF and enabled DVB-T. When saa7134 */ + /* scan I2C devices it will not detect IF tda9887 and can`t*/ + /* watch TV without software reboot. To solve this problem */ + /* switch the tuner to analog TV mode manually. */ + if (dev->tuner_type == TUNER_PHILIPS_FMD1216ME_MK3) { + if (i2c_transfer(&dev->i2c_adap, &msg1, 1) != 1) + printk(KERN_WARNING "%s: Unable to enable IF of the tuner.\n", dev->name); + } break; } case SAA7134_BOARD_PHILIPS_EUROPA: -- cgit v1.2.3-59-g8ed1b From cc1821964d122c39a80e653163513f11ccc39524 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Mon, 18 May 2015 14:54:17 -0300 Subject: [media] omap_vout: use swap() in omapvid_init() Use kernel.h macro definition. Signed-off-by: Fabian Frederick Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap/omap_vout.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c index 17b189a81ec5..f09c5f17a42f 100644 --- a/drivers/media/platform/omap/omap_vout.c +++ b/drivers/media/platform/omap/omap_vout.c @@ -445,7 +445,7 @@ static int omapvid_init(struct omap_vout_device *vout, u32 addr) int ret = 0, i; struct v4l2_window *win; struct omap_overlay *ovl; - int posx, posy, outw, outh, temp; + int posx, posy, outw, outh; struct omap_video_timings *timing; struct omapvideo_info *ovid = &vout->vid_info; @@ -468,9 +468,7 @@ static int omapvid_init(struct omap_vout_device *vout, u32 addr) /* Invert the height and width for 90 * and 270 degree rotation */ - temp = outw; - outw = outh; - outh = temp; + swap(outw, outh); posy = (timing->y_res - win->w.width) - win->w.left; posx = win->w.top; break; @@ -481,9 +479,7 @@ static int omapvid_init(struct omap_vout_device *vout, u32 addr) break; case dss_rotation_270_degree: - temp = outw; - outw = outh; - outh = temp; + swap(outw, outh); posy = win->w.left; posx = (timing->x_res - win->w.height) - win->w.top; break; -- cgit v1.2.3-59-g8ed1b From 63344b6592f1d69e13d0e32d8b213137ab6b663e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 1 Jun 2015 07:15:53 -0300 Subject: [media] vivid: move video loopback control to the capture device This has been on my TODO list for some time now: the control that enables the video loopback was part of the controls of the video output device instead of the video capture device. In practice this was quite annoying since you expect it at the capture side since that's where you want to make the decision whether to use the TPG or looped video. This patch moves the control from the output to the capture side. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/vivid.txt | 2 +- drivers/media/platform/vivid/vivid-core.h | 2 +- drivers/media/platform/vivid/vivid-ctrls.c | 81 +++++++++++++++--------------- 3 files changed, 42 insertions(+), 43 deletions(-) (limited to 'drivers/media') diff --git a/Documentation/video4linux/vivid.txt b/Documentation/video4linux/vivid.txt index 0c1b3a6ba6be..e35d376b7f64 100644 --- a/Documentation/video4linux/vivid.txt +++ b/Documentation/video4linux/vivid.txt @@ -895,7 +895,7 @@ Section 10.1: Video and Sliced VBI looping The way to enable video/VBI looping is currently fairly crude. A 'Loop Video' control is available in the "Vivid" control class of the video -output and VBI output devices. When checked the video looping will be enabled. +capture and VBI capture devices. When checked the video looping will be enabled. Once enabled any video S-Video or HDMI input will show a static test pattern until the video output has started. At that time the video output will be looped to the video input provided that: diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h index 3755b1858426..c72349c83fab 100644 --- a/drivers/media/platform/vivid/vivid-core.h +++ b/drivers/media/platform/vivid/vivid-core.h @@ -139,7 +139,7 @@ struct vivid_dev { struct v4l2_ctrl_handler ctrl_hdl_user_aud; struct v4l2_ctrl_handler ctrl_hdl_streaming; struct v4l2_ctrl_handler ctrl_hdl_sdtv_cap; - struct v4l2_ctrl_handler ctrl_hdl_loop_out; + struct v4l2_ctrl_handler ctrl_hdl_loop_cap; struct video_device vid_cap_dev; struct v4l2_ctrl_handler ctrl_hdl_vid_cap; struct video_device vid_out_dev; diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c index 1898751c20c8..339c8b7e53c8 100644 --- a/drivers/media/platform/vivid/vivid-ctrls.c +++ b/drivers/media/platform/vivid/vivid-ctrls.c @@ -793,6 +793,37 @@ static const struct v4l2_ctrl_config vivid_ctrl_limited_rgb_range = { }; +/* Video Loop Control */ + +static int vivid_loop_cap_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_loop_cap); + + switch (ctrl->id) { + case VIVID_CID_LOOP_VIDEO: + dev->loop_video = ctrl->val; + vivid_update_quality(dev); + vivid_send_source_change(dev, SVID); + vivid_send_source_change(dev, HDMI); + break; + } + return 0; +} + +static const struct v4l2_ctrl_ops vivid_loop_cap_ctrl_ops = { + .s_ctrl = vivid_loop_cap_s_ctrl, +}; + +static const struct v4l2_ctrl_config vivid_ctrl_loop_video = { + .ops = &vivid_loop_cap_ctrl_ops, + .id = VIVID_CID_LOOP_VIDEO, + .name = "Loop Video", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .max = 1, + .step = 1, +}; + + /* VBI Capture Control */ static int vivid_vbi_cap_s_ctrl(struct v4l2_ctrl *ctrl) @@ -1226,38 +1257,6 @@ static const struct v4l2_ctrl_config vivid_ctrl_radio_tx_rds_blockio = { }; - -/* Video Loop Control */ - -static int vivid_loop_out_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_loop_out); - - switch (ctrl->id) { - case VIVID_CID_LOOP_VIDEO: - dev->loop_video = ctrl->val; - vivid_update_quality(dev); - vivid_send_source_change(dev, SVID); - vivid_send_source_change(dev, HDMI); - break; - } - return 0; -} - -static const struct v4l2_ctrl_ops vivid_loop_out_ctrl_ops = { - .s_ctrl = vivid_loop_out_s_ctrl, -}; - -static const struct v4l2_ctrl_config vivid_ctrl_loop_video = { - .ops = &vivid_loop_out_ctrl_ops, - .id = VIVID_CID_LOOP_VIDEO, - .name = "Loop Video", - .type = V4L2_CTRL_TYPE_BOOLEAN, - .max = 1, - .step = 1, -}; - - static const struct v4l2_ctrl_config vivid_ctrl_class = { .ops = &vivid_user_gen_ctrl_ops, .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY, @@ -1275,7 +1274,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, struct v4l2_ctrl_handler *hdl_user_aud = &dev->ctrl_hdl_user_aud; struct v4l2_ctrl_handler *hdl_streaming = &dev->ctrl_hdl_streaming; struct v4l2_ctrl_handler *hdl_sdtv_cap = &dev->ctrl_hdl_sdtv_cap; - struct v4l2_ctrl_handler *hdl_loop_out = &dev->ctrl_hdl_loop_out; + struct v4l2_ctrl_handler *hdl_loop_cap = &dev->ctrl_hdl_loop_cap; struct v4l2_ctrl_handler *hdl_vid_cap = &dev->ctrl_hdl_vid_cap; struct v4l2_ctrl_handler *hdl_vid_out = &dev->ctrl_hdl_vid_out; struct v4l2_ctrl_handler *hdl_vbi_cap = &dev->ctrl_hdl_vbi_cap; @@ -1301,8 +1300,8 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_class, NULL); v4l2_ctrl_handler_init(hdl_sdtv_cap, 2); v4l2_ctrl_new_custom(hdl_sdtv_cap, &vivid_ctrl_class, NULL); - v4l2_ctrl_handler_init(hdl_loop_out, 1); - v4l2_ctrl_new_custom(hdl_loop_out, &vivid_ctrl_class, NULL); + v4l2_ctrl_handler_init(hdl_loop_cap, 1); + v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_class, NULL); v4l2_ctrl_handler_init(hdl_vid_cap, 55); v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_class, NULL); v4l2_ctrl_handler_init(hdl_vid_out, 26); @@ -1473,7 +1472,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, } if ((dev->has_vid_cap && dev->has_vid_out) || (dev->has_vbi_cap && dev->has_vbi_out)) - v4l2_ctrl_new_custom(hdl_loop_out, &vivid_ctrl_loop_video, NULL); + v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_loop_video, NULL); if (dev->has_fb) v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_clear_fb, NULL); @@ -1556,8 +1555,8 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, return hdl_streaming->error; if (hdl_sdr_cap->error) return hdl_sdr_cap->error; - if (hdl_loop_out->error) - return hdl_loop_out->error; + if (hdl_loop_cap->error) + return hdl_loop_cap->error; if (dev->autogain) v4l2_ctrl_auto_cluster(2, &dev->autogain, 0, true); @@ -1568,6 +1567,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_aud, NULL); v4l2_ctrl_add_handler(hdl_vid_cap, hdl_streaming, NULL); v4l2_ctrl_add_handler(hdl_vid_cap, hdl_sdtv_cap, NULL); + v4l2_ctrl_add_handler(hdl_vid_cap, hdl_loop_cap, NULL); if (hdl_vid_cap->error) return hdl_vid_cap->error; dev->vid_cap_dev.ctrl_handler = hdl_vid_cap; @@ -1576,7 +1576,6 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_gen, NULL); v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_aud, NULL); v4l2_ctrl_add_handler(hdl_vid_out, hdl_streaming, NULL); - v4l2_ctrl_add_handler(hdl_vid_out, hdl_loop_out, NULL); if (hdl_vid_out->error) return hdl_vid_out->error; dev->vid_out_dev.ctrl_handler = hdl_vid_out; @@ -1585,6 +1584,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_user_gen, NULL); v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_streaming, NULL); v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_sdtv_cap, NULL); + v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_loop_cap, NULL); if (hdl_vbi_cap->error) return hdl_vbi_cap->error; dev->vbi_cap_dev.ctrl_handler = hdl_vbi_cap; @@ -1592,7 +1592,6 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, if (dev->has_vbi_out) { v4l2_ctrl_add_handler(hdl_vbi_out, hdl_user_gen, NULL); v4l2_ctrl_add_handler(hdl_vbi_out, hdl_streaming, NULL); - v4l2_ctrl_add_handler(hdl_vbi_out, hdl_loop_out, NULL); if (hdl_vbi_out->error) return hdl_vbi_out->error; dev->vbi_out_dev.ctrl_handler = hdl_vbi_out; @@ -1635,5 +1634,5 @@ void vivid_free_controls(struct vivid_dev *dev) v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_aud); v4l2_ctrl_handler_free(&dev->ctrl_hdl_streaming); v4l2_ctrl_handler_free(&dev->ctrl_hdl_sdtv_cap); - v4l2_ctrl_handler_free(&dev->ctrl_hdl_loop_out); + v4l2_ctrl_handler_free(&dev->ctrl_hdl_loop_cap); } -- cgit v1.2.3-59-g8ed1b From ebbb5637558e6ff087f6f4cc74e1847bb6992f02 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 1 Jun 2015 08:18:31 -0300 Subject: [media] stk1160: add DMABUF support Implement DMABUF exporting and importing. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/stk1160/stk1160-v4l.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/stk1160/stk1160-v4l.c b/drivers/media/usb/stk1160/stk1160-v4l.c index 749ad5603c9e..4d313ed4c32e 100644 --- a/drivers/media/usb/stk1160/stk1160-v4l.c +++ b/drivers/media/usb/stk1160/stk1160-v4l.c @@ -500,6 +500,7 @@ static const struct v4l2_ioctl_ops stk1160_ioctl_ops = { .vidioc_dqbuf = vb2_ioctl_dqbuf, .vidioc_streamon = vb2_ioctl_streamon, .vidioc_streamoff = vb2_ioctl_streamoff, + .vidioc_expbuf = vb2_ioctl_expbuf, .vidioc_log_status = v4l2_ctrl_log_status, .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, @@ -645,7 +646,7 @@ int stk1160_vb2_setup(struct stk1160 *dev) q = &dev->vb_vidq; q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - q->io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR; + q->io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR | VB2_DMABUF; q->drv_priv = dev; q->buf_struct_size = sizeof(struct stk1160_buffer); q->ops = &stk1160_video_qops; -- cgit v1.2.3-59-g8ed1b From 4d38cde776185a78b96f5e3a3e653450050600bd Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 1 Jun 2015 14:14:07 -0300 Subject: [media] radio-si470x-i2c: Pass the IRQF_ONESHOT flag Since commit 1c6c69525b40 ("genirq: Reject bogus threaded irq requests") threaded IRQs without a primary handler need to be requested with IRQF_ONESHOT, otherwise the request will fail. So pass the IRQF_ONESHOT flag in this case. The semantic patch that makes this change is available in scripts/coccinelle/misc/irqf_oneshot.cocci. Signed-off-by: Fabio Estevam Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/si470x/radio-si470x-i2c.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c index 2a497c80c77f..49fe8453e218 100644 --- a/drivers/media/radio/si470x/radio-si470x-i2c.c +++ b/drivers/media/radio/si470x/radio-si470x-i2c.c @@ -421,7 +421,8 @@ static int si470x_i2c_probe(struct i2c_client *client, init_waitqueue_head(&radio->read_queue); retval = request_threaded_irq(client->irq, NULL, si470x_i2c_interrupt, - IRQF_TRIGGER_FALLING, DRIVER_NAME, radio); + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, DRIVER_NAME, + radio); if (retval) { dev_err(&client->dev, "Failed to register interrupt\n"); goto err_rds; -- cgit v1.2.3-59-g8ed1b From afeef4ee23b4865d6c3bf294b5ac9d55dbff5b82 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 5 Jun 2015 03:45:38 -0300 Subject: [media] vivid-tpg: improve Y16 color setup Currently the colors for the Y16 and Y16_BE pixelformats are in the range 0x0000-0xff00. So pure white (0xffff) is never created. Improve this by making white really white. For other colors the lsb remains 0 so vivid can be used to detect endian problems. Signed-off-by: Hans Verkuil Reviewed-by: Ricardo Ribalda Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-tpg.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/vivid/vivid-tpg.c b/drivers/media/platform/vivid/vivid-tpg.c index 32ebf0d90d10..1458c7955547 100644 --- a/drivers/media/platform/vivid/vivid-tpg.c +++ b/drivers/media/platform/vivid/vivid-tpg.c @@ -900,12 +900,19 @@ static void gen_twopix(struct tpg_data *tpg, buf[0][offset] = r_y; break; case V4L2_PIX_FMT_Y16: - buf[0][offset] = 0; + /* + * Ideally both bytes should be set to r_y, but then you won't + * be able to detect endian problems. So keep it 0 except for + * the corner case where r_y is 0xff so white really will be + * white (0xffff). + */ + buf[0][offset] = r_y == 0xff ? r_y : 0; buf[0][offset+1] = r_y; break; case V4L2_PIX_FMT_Y16_BE: + /* See comment for V4L2_PIX_FMT_Y16 above */ buf[0][offset] = r_y; - buf[0][offset+1] = 0; + buf[0][offset+1] = r_y == 0xff ? r_y : 0; break; case V4L2_PIX_FMT_YUV422P: case V4L2_PIX_FMT_YUV420: -- cgit v1.2.3-59-g8ed1b From 5d3512514ae7e21e869ea306f902b6be428e2578 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 5 Jun 2015 05:11:14 -0300 Subject: [media] v4l2-ioctl: clear the reserved field of v4l2_create_buffers This field was never cleared by the kernel making future extensions hard to implement. Clear it now. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ioctl.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 691295984225..bbeb9ffd5e92 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1805,6 +1805,8 @@ static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops, if (ret) return ret; + CLEAR_AFTER_FIELD(create, format); + v4l_sanitize_format(&create->format); ret = ops->vidioc_create_bufs(file, fh, create); -- cgit v1.2.3-59-g8ed1b From 839aa56d077972170a074bcbe31bf0d7eba37b24 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 5 Jun 2015 11:28:51 -0300 Subject: [media] v4l2-ioctl: log buffer type 0 correctly If userspace passed the invalid buffer type 0 to the kernel, then the kernel log would show 'type=(null)' since there was no string defined for type 0. Fix this. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ioctl.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index bbeb9ffd5e92..85de4557f696 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -142,6 +142,7 @@ const char *v4l2_field_names[] = { EXPORT_SYMBOL(v4l2_field_names); const char *v4l2_type_names[] = { + [0] = "0", [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "vid-cap", [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "vid-overlay", [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "vid-out", -- cgit v1.2.3-59-g8ed1b From 4347df6a7f7d6d0641523e595df93ddb63990bd1 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 2 Jun 2015 07:20:00 -0300 Subject: [media] m88ds3103: a couple missing error codes We need to set some error codes here. Fixes: f01919e8f54f ('[media] m88ds3103: add I2C client binding') Signed-off-by: Dan Carpenter Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/m88ds3103.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index 01b9dedff3d1..7b21f1ad4542 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -1563,6 +1563,7 @@ static int m88ds3103_probe(struct i2c_client *client, u8tmp = 0x10; break; default: + ret = -EINVAL; goto err_kfree; } @@ -1590,8 +1591,10 @@ static int m88ds3103_probe(struct i2c_client *client, dev->i2c_adapter = i2c_add_mux_adapter(client->adapter, &client->dev, dev, 0, 0, 0, m88ds3103_select, m88ds3103_deselect); - if (dev->i2c_adapter == NULL) + if (dev->i2c_adapter == NULL) { + ret = -ENOMEM; goto err_kfree; + } /* create dvb_frontend */ memcpy(&dev->fe.ops, &m88ds3103_ops, sizeof(struct dvb_frontend_ops)); -- cgit v1.2.3-59-g8ed1b From ab80b19bb99933df415817370a64ac7e7c688896 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sat, 6 Jun 2015 08:11:16 -0300 Subject: [media] tda10071: add missing error status when probe() fails We must return -ENODEV error on case probe() fails to detect chip. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/tda10071.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/tda10071.c b/drivers/media/dvb-frontends/tda10071.c index 31328540e5c4..1470a5d63f58 100644 --- a/drivers/media/dvb-frontends/tda10071.c +++ b/drivers/media/dvb-frontends/tda10071.c @@ -1348,18 +1348,30 @@ static int tda10071_probe(struct i2c_client *client, /* chip ID */ ret = tda10071_rd_reg(dev, 0xff, &u8tmp); - if (ret || u8tmp != 0x0f) + if (ret) + goto err_kfree; + if (u8tmp != 0x0f) { + ret = -ENODEV; goto err_kfree; + } /* chip type */ ret = tda10071_rd_reg(dev, 0xdd, &u8tmp); - if (ret || u8tmp != 0x00) + if (ret) + goto err_kfree; + if (u8tmp != 0x00) { + ret = -ENODEV; goto err_kfree; + } /* chip version */ ret = tda10071_rd_reg(dev, 0xfe, &u8tmp); - if (ret || u8tmp != 0x01) + if (ret) goto err_kfree; + if (u8tmp != 0x01) { + ret = -ENODEV; + goto err_kfree; + } /* create dvb_frontend */ memcpy(&dev->fe.ops, &tda10071_ops, sizeof(struct dvb_frontend_ops)); -- cgit v1.2.3-59-g8ed1b From f00245c2e8cf18b37d26674c88915c5238c2815e Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sat, 6 Jun 2015 08:15:34 -0300 Subject: [media] fc2580: add missing error status when probe() fails We must return -ENODEV error on case probe() fails to detect chip. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/fc2580.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/tuners/fc2580.c b/drivers/media/tuners/fc2580.c index db21902b6e63..12f916e53150 100644 --- a/drivers/media/tuners/fc2580.c +++ b/drivers/media/tuners/fc2580.c @@ -571,6 +571,7 @@ static int fc2580_probe(struct i2c_client *client, case 0x5a: break; default: + ret = -ENODEV; goto err_kfree; } -- cgit v1.2.3-59-g8ed1b From e68cf471e71d1e91c5661e1bb7595985158d59ae Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 5 Jun 2015 11:28:50 -0300 Subject: [media] v4l2-mem2mem: add support for prepare_buf This was never added for some reason, so add it now. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-mem2mem.c | 28 ++++++++++++++++++++++++++++ include/media/v4l2-mem2mem.h | 4 ++++ 2 files changed, 32 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index cbef15c07e53..dc853e57f91f 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -426,6 +426,25 @@ int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, } EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf); +/** + * v4l2_m2m_prepare_buf() - prepare a source or destination buffer, depending on + * the type + */ +int v4l2_m2m_prepare_buf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, + struct v4l2_buffer *buf) +{ + struct vb2_queue *vq; + int ret; + + vq = v4l2_m2m_get_vq(m2m_ctx, buf->type); + ret = vb2_prepare_buf(vq, buf); + if (!ret) + v4l2_m2m_try_schedule(m2m_ctx); + + return ret; +} +EXPORT_SYMBOL_GPL(v4l2_m2m_prepare_buf); + /** * v4l2_m2m_create_bufs() - create a source or destination buffer, depending * on the type @@ -811,6 +830,15 @@ int v4l2_m2m_ioctl_dqbuf(struct file *file, void *priv, } EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_dqbuf); +int v4l2_m2m_ioctl_prepare_buf(struct file *file, void *priv, + struct v4l2_buffer *buf) +{ + struct v4l2_fh *fh = file->private_data; + + return v4l2_m2m_prepare_buf(file, fh->m2m_ctx, buf); +} +EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_prepare_buf); + int v4l2_m2m_ioctl_expbuf(struct file *file, void *priv, struct v4l2_exportbuffer *eb) { diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h index c5f3914bc4d8..3bbd96da25c9 100644 --- a/include/media/v4l2-mem2mem.h +++ b/include/media/v4l2-mem2mem.h @@ -116,6 +116,8 @@ int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_buffer *buf); int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_buffer *buf); +int v4l2_m2m_prepare_buf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, + struct v4l2_buffer *buf); int v4l2_m2m_create_bufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_create_buffers *create); @@ -248,6 +250,8 @@ int v4l2_m2m_ioctl_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf); int v4l2_m2m_ioctl_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf); +int v4l2_m2m_ioctl_prepare_buf(struct file *file, void *fh, + struct v4l2_buffer *buf); int v4l2_m2m_ioctl_streamon(struct file *file, void *fh, enum v4l2_buf_type type); int v4l2_m2m_ioctl_streamoff(struct file *file, void *fh, -- cgit v1.2.3-59-g8ed1b From 7bcff1c242475ffc47e413ac7b1d7a3e3529b109 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 5 Jun 2015 11:28:52 -0300 Subject: [media] vim2m: add create_bufs and prepare_buf support Add support for the missing VIDIOC_CREATE_BUFS and VIDIOC_PREPARE_BUF ioctls. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vim2m.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c index cecfd75b58d7..295fde5fdb75 100644 --- a/drivers/media/platform/vim2m.c +++ b/drivers/media/platform/vim2m.c @@ -693,6 +693,8 @@ static const struct v4l2_ioctl_ops vim2m_ioctl_ops = { .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, + .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, + .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, .vidioc_streamon = v4l2_m2m_ioctl_streamon, @@ -720,6 +722,12 @@ static int vim2m_queue_setup(struct vb2_queue *vq, size = q_data->width * q_data->height * q_data->fmt->depth >> 3; + if (fmt) { + if (fmt->fmt.pix.sizeimage < size) + return -EINVAL; + size = fmt->fmt.pix.sizeimage; + } + while (size * count > MEM2MEM_VID_MEM_LIMIT) (count)--; -- cgit v1.2.3-59-g8ed1b From 5be50ef1ef45d749c17e98b9483730331ee8c49c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 7 Jun 2015 07:32:30 -0300 Subject: [media] adv7511: replace uintX_t by uX for consistency Currently this driver mixes u8/u16 and uint8_t/uint16_t. Standardize on u8/u16. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7511.c | 32 ++++++++++++++++---------------- include/media/adv7511.h | 6 +++--- 2 files changed, 19 insertions(+), 19 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c index 90325676fca5..d9bb90b383fb 100644 --- a/drivers/media/i2c/adv7511.c +++ b/drivers/media/i2c/adv7511.c @@ -77,7 +77,7 @@ struct adv7511_state_edid { u32 blocks; /* Number of segments read */ u32 segments; - uint8_t data[EDID_MAX_SEGM * 256]; + u8 data[EDID_MAX_SEGM * 256]; /* Number of EDID read retries left */ unsigned read_retries; bool complete; @@ -89,8 +89,8 @@ struct adv7511_state { struct media_pad pad; struct v4l2_ctrl_handler hdl; int chip_revision; - uint8_t i2c_edid_addr; - uint8_t i2c_cec_addr; + u8 i2c_edid_addr; + u8 i2c_cec_addr; /* Is the adv7511 powered on? */ bool power_on; /* Did we receive hotplug and rx-sense signals? */ @@ -201,7 +201,7 @@ static int adv7511_wr(struct v4l2_subdev *sd, u8 reg, u8 val) /* To set specific bits in the register, a clear-mask is given (to be AND-ed), and then the value-mask (to be OR-ed). */ -static inline void adv7511_wr_and_or(struct v4l2_subdev *sd, u8 reg, uint8_t clr_mask, uint8_t val_mask) +static inline void adv7511_wr_and_or(struct v4l2_subdev *sd, u8 reg, u8 clr_mask, u8 val_mask) { adv7511_wr(sd, reg, (adv7511_rd(sd, reg) & clr_mask) | val_mask); } @@ -223,7 +223,7 @@ static int adv_smbus_read_i2c_block_data(struct i2c_client *client, return ret; } -static inline void adv7511_edid_rd(struct v4l2_subdev *sd, uint16_t len, uint8_t *buf) +static inline void adv7511_edid_rd(struct v4l2_subdev *sd, u16 len, u8 *buf) { struct adv7511_state *state = get_adv7511_state(sd); int i; @@ -248,7 +248,7 @@ static inline bool adv7511_have_rx_sense(struct v4l2_subdev *sd) return adv7511_rd(sd, 0x42) & MASK_ADV7511_MSEN_DETECT; } -static void adv7511_csc_conversion_mode(struct v4l2_subdev *sd, uint8_t mode) +static void adv7511_csc_conversion_mode(struct v4l2_subdev *sd, u8 mode) { adv7511_wr_and_or(sd, 0x18, 0x9f, (mode & 0x3)<<5); } @@ -292,7 +292,7 @@ static void adv7511_csc_coeff(struct v4l2_subdev *sd, static void adv7511_csc_rgb_full2limit(struct v4l2_subdev *sd, bool enable) { if (enable) { - uint8_t csc_mode = 0; + u8 csc_mode = 0; adv7511_csc_conversion_mode(sd, csc_mode); adv7511_csc_coeff(sd, 4096-564, 0, 0, 256, @@ -546,8 +546,8 @@ static int adv7511_s_power(struct v4l2_subdev *sd, int on) /* Enable interrupts */ static void adv7511_set_isr(struct v4l2_subdev *sd, bool enable) { - uint8_t irqs = MASK_ADV7511_HPD_INT | MASK_ADV7511_MSEN_INT; - uint8_t irqs_rd; + u8 irqs = MASK_ADV7511_HPD_INT | MASK_ADV7511_MSEN_INT; + u8 irqs_rd; int retries = 100; v4l2_dbg(2, debug, sd, "%s: %s\n", __func__, enable ? "enable" : "disable"); @@ -580,7 +580,7 @@ static void adv7511_set_isr(struct v4l2_subdev *sd, bool enable) /* Interrupt handler */ static int adv7511_isr(struct v4l2_subdev *sd, u32 status, bool *handled) { - uint8_t irq_status; + u8 irq_status; /* disable interrupts to prevent a race condition */ adv7511_set_isr(sd, false); @@ -1033,7 +1033,7 @@ static const struct v4l2_subdev_ops adv7511_ops = { }; /* ----------------------------------------------------------------------- */ -static void adv7511_dbg_dump_edid(int lvl, int debug, struct v4l2_subdev *sd, int segment, uint8_t *buf) +static void adv7511_dbg_dump_edid(int lvl, int debug, struct v4l2_subdev *sd, int segment, u8 *buf) { if (debug >= lvl) { int i, j; @@ -1145,7 +1145,7 @@ static void adv7511_check_monitor_present_status(struct v4l2_subdev *sd) { struct adv7511_state *state = get_adv7511_state(sd); /* read hotplug and rx-sense state */ - uint8_t status = adv7511_rd(sd, 0x42); + u8 status = adv7511_rd(sd, 0x42); v4l2_dbg(1, debug, sd, "%s: status: 0x%x%s%s\n", __func__, @@ -1189,9 +1189,9 @@ static void adv7511_check_monitor_present_status(struct v4l2_subdev *sd) } } -static bool edid_block_verify_crc(uint8_t *edid_block) +static bool edid_block_verify_crc(u8 *edid_block) { - uint8_t sum = 0; + u8 sum = 0; int i; for (i = 0; i < 128; i++) @@ -1203,7 +1203,7 @@ static bool edid_verify_crc(struct v4l2_subdev *sd, u32 segment) { struct adv7511_state *state = get_adv7511_state(sd); u32 blocks = state->edid.blocks; - uint8_t *data = state->edid.data; + u8 *data = state->edid.data; if (!edid_block_verify_crc(&data[segment * 256])) return false; @@ -1228,7 +1228,7 @@ static bool edid_verify_header(struct v4l2_subdev *sd, u32 segment) static bool adv7511_check_edid_status(struct v4l2_subdev *sd) { struct adv7511_state *state = get_adv7511_state(sd); - uint8_t edidRdy = adv7511_rd(sd, 0xc5); + u8 edidRdy = adv7511_rd(sd, 0xc5); v4l2_dbg(1, debug, sd, "%s: edid ready (retries: %d)\n", __func__, EDID_MAX_RETRIES - state->edid.read_retries); diff --git a/include/media/adv7511.h b/include/media/adv7511.h index bb78bed9a5b8..f351eff404d6 100644 --- a/include/media/adv7511.h +++ b/include/media/adv7511.h @@ -40,9 +40,9 @@ struct adv7511_cec_arg { }; struct adv7511_platform_data { - uint8_t i2c_edid; - uint8_t i2c_cec; - uint32_t cec_clk; + u8 i2c_edid; + u8 i2c_cec; + u32 cec_clk; }; #endif -- cgit v1.2.3-59-g8ed1b From 28a769f1abfe8f6958c14b3b4163360e3c931133 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 7 Jun 2015 07:32:31 -0300 Subject: [media] adv7842: replace uintX_t by uX for consistency Currently this driver mixes u8/u32 and uint8_t/uint32_t. Standardize on u8/u32. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7842.c | 22 ++++++++++---------- include/media/adv7842.h | 50 ++++++++++++++++++++++----------------------- 2 files changed, 36 insertions(+), 36 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index f5248baeb59e..f14ea78a7c9c 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -1556,7 +1556,7 @@ static int adv7842_query_dv_timings(struct v4l2_subdev *sd, V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT; if (is_digital_input(sd)) { - uint32_t freq; + u32 freq; timings->type = V4L2_DV_BT_656_1120; @@ -2334,7 +2334,7 @@ struct adv7842_cfg_read_infoframe { static void log_infoframe(struct v4l2_subdev *sd, struct adv7842_cfg_read_infoframe *cri) { int i; - uint8_t buffer[32]; + u8 buffer[32]; union hdmi_infoframe frame; u8 len; struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -2407,7 +2407,7 @@ static const char * const prim_mode_txt[] = { static int adv7842_sdp_log_status(struct v4l2_subdev *sd) { /* SDP (Standard definition processor) block */ - uint8_t sdp_signal_detected = sdp_read(sd, 0x5A) & 0x01; + u8 sdp_signal_detected = sdp_read(sd, 0x5A) & 0x01; v4l2_info(sd, "Chip powered %s\n", no_power(sd) ? "off" : "on"); v4l2_info(sd, "Prim-mode = 0x%x, video std = 0x%x\n", @@ -2451,10 +2451,10 @@ static int adv7842_cp_log_status(struct v4l2_subdev *sd) /* CP block */ struct adv7842_state *state = to_state(sd); struct v4l2_dv_timings timings; - uint8_t reg_io_0x02 = io_read(sd, 0x02); - uint8_t reg_io_0x21 = io_read(sd, 0x21); - uint8_t reg_rep_0x77 = rep_read(sd, 0x77); - uint8_t reg_rep_0x7d = rep_read(sd, 0x7d); + u8 reg_io_0x02 = io_read(sd, 0x02); + u8 reg_io_0x21 = io_read(sd, 0x21); + u8 reg_rep_0x77 = rep_read(sd, 0x77); + u8 reg_rep_0x7d = rep_read(sd, 0x7d); bool audio_pll_locked = hdmi_read(sd, 0x04) & 0x01; bool audio_sample_packet_detect = hdmi_read(sd, 0x18) & 0x01; bool audio_mute = io_read(sd, 0x65) & 0x40; @@ -2526,10 +2526,10 @@ static int adv7842_cp_log_status(struct v4l2_subdev *sd) if (no_cp_signal(sd)) { v4l2_info(sd, "STDI: not locked\n"); } else { - uint32_t bl = ((cp_read(sd, 0xb1) & 0x3f) << 8) | cp_read(sd, 0xb2); - uint32_t lcf = ((cp_read(sd, 0xb3) & 0x7) << 8) | cp_read(sd, 0xb4); - uint32_t lcvs = cp_read(sd, 0xb3) >> 3; - uint32_t fcl = ((cp_read(sd, 0xb8) & 0x1f) << 8) | cp_read(sd, 0xb9); + u32 bl = ((cp_read(sd, 0xb1) & 0x3f) << 8) | cp_read(sd, 0xb2); + u32 lcf = ((cp_read(sd, 0xb3) & 0x7) << 8) | cp_read(sd, 0xb4); + u32 lcvs = cp_read(sd, 0xb3) >> 3; + u32 fcl = ((cp_read(sd, 0xb8) & 0x1f) << 8) | cp_read(sd, 0xb9); char hs_pol = ((cp_read(sd, 0xb5) & 0x10) ? ((cp_read(sd, 0xb5) & 0x08) ? '+' : '-') : 'x'); char vs_pol = ((cp_read(sd, 0xb5) & 0x40) ? diff --git a/include/media/adv7842.h b/include/media/adv7842.h index 1f38db8d3c21..bc249709bf35 100644 --- a/include/media/adv7842.h +++ b/include/media/adv7842.h @@ -103,35 +103,35 @@ enum adv7842_drive_strength { struct adv7842_sdp_csc_coeff { bool manual; - uint16_t scaling; - uint16_t A1; - uint16_t A2; - uint16_t A3; - uint16_t A4; - uint16_t B1; - uint16_t B2; - uint16_t B3; - uint16_t B4; - uint16_t C1; - uint16_t C2; - uint16_t C3; - uint16_t C4; + u16 scaling; + u16 A1; + u16 A2; + u16 A3; + u16 A4; + u16 B1; + u16 B2; + u16 B3; + u16 B4; + u16 C1; + u16 C2; + u16 C3; + u16 C4; }; struct adv7842_sdp_io_sync_adjustment { bool adjust; - uint16_t hs_beg; - uint16_t hs_width; - uint16_t de_beg; - uint16_t de_end; - uint8_t vs_beg_o; - uint8_t vs_beg_e; - uint8_t vs_end_o; - uint8_t vs_end_e; - uint8_t de_v_beg_o; - uint8_t de_v_beg_e; - uint8_t de_v_end_o; - uint8_t de_v_end_e; + u16 hs_beg; + u16 hs_width; + u16 de_beg; + u16 de_end; + u8 vs_beg_o; + u8 vs_beg_e; + u8 vs_end_o; + u8 vs_end_e; + u8 de_v_beg_o; + u8 de_v_beg_e; + u8 de_v_end_o; + u8 de_v_end_e; }; /* Platform dependent definition */ -- cgit v1.2.3-59-g8ed1b From b4dbad8fe3b60466e0d364b34c075117757838f2 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 7 Jun 2015 07:32:32 -0300 Subject: [media] adv7511: log the currently set infoframes The adv7511 sets up InfoFrames that are used when transmitting video. Log the contents of those InfoFrames so it is possible to see exactly what the transmitter is sending. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/Kconfig | 1 + drivers/media/i2c/adv7511.c | 123 ++++++++++++++++++++++++++++++- drivers/media/pci/cobalt/cobalt-driver.c | 1 + include/media/adv7511.h | 1 + 4 files changed, 124 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 36f5563ca9cd..c92180d4036e 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -424,6 +424,7 @@ config VIDEO_ADV7393 config VIDEO_ADV7511 tristate "Analog Devices ADV7511 encoder" depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API + select HDMI ---help--- Support for the Analog Devices ADV7511 video encoder. diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c index d9bb90b383fb..95bcd4026451 100644 --- a/drivers/media/i2c/adv7511.c +++ b/drivers/media/i2c/adv7511.c @@ -91,6 +91,7 @@ struct adv7511_state { int chip_revision; u8 i2c_edid_addr; u8 i2c_cec_addr; + u8 i2c_pktmem_addr; /* Is the adv7511 powered on? */ bool power_on; /* Did we receive hotplug and rx-sense signals? */ @@ -109,6 +110,7 @@ struct adv7511_state { struct v4l2_ctrl *have_edid0_ctrl; struct v4l2_ctrl *rgb_quantization_range_ctrl; struct i2c_client *i2c_edid; + struct i2c_client *i2c_pktmem; struct adv7511_state_edid edid; /* Running counter of the number of detected EDIDs (for debugging) */ unsigned edid_detect_counter; @@ -238,6 +240,35 @@ static inline void adv7511_edid_rd(struct v4l2_subdev *sd, u16 len, u8 *buf) v4l2_err(sd, "%s: i2c read error\n", __func__); } +static int adv7511_pktmem_rd(struct v4l2_subdev *sd, u8 reg) +{ + struct adv7511_state *state = get_adv7511_state(sd); + + return adv_smbus_read_byte_data(state->i2c_pktmem, reg); +} + +static int adv7511_pktmem_wr(struct v4l2_subdev *sd, u8 reg, u8 val) +{ + struct adv7511_state *state = get_adv7511_state(sd); + int ret; + int i; + + for (i = 0; i < 3; i++) { + ret = i2c_smbus_write_byte_data(state->i2c_pktmem, reg, val); + if (ret == 0) + return 0; + } + v4l2_err(sd, "%s: i2c write error\n", __func__); + return ret; +} + +/* To set specific bits in the register, a clear-mask is given (to be AND-ed), + and then the value-mask (to be OR-ed). */ +static inline void adv7511_pktmem_wr_and_or(struct v4l2_subdev *sd, u8 reg, u8 clr_mask, u8 val_mask) +{ + adv7511_pktmem_wr(sd, reg, (adv7511_pktmem_rd(sd, reg) & clr_mask) | val_mask); +} + static inline bool adv7511_have_hotplug(struct v4l2_subdev *sd) { return adv7511_rd(sd, 0x42) & MASK_ADV7511_HPD_DETECT; @@ -415,6 +446,80 @@ static int adv7511_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_regi } #endif +struct adv7511_cfg_read_infoframe { + const char *desc; + u8 present_reg; + u8 present_mask; + u8 header[3]; + u16 payload_addr; +}; + +static u8 hdmi_infoframe_checksum(u8 *ptr, size_t size) +{ + u8 csum = 0; + size_t i; + + /* compute checksum */ + for (i = 0; i < size; i++) + csum += ptr[i]; + + return 256 - csum; +} + +static void log_infoframe(struct v4l2_subdev *sd, const struct adv7511_cfg_read_infoframe *cri) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct device *dev = &client->dev; + union hdmi_infoframe frame; + u8 buffer[32]; + u8 len; + int i; + + if (!(adv7511_rd(sd, cri->present_reg) & cri->present_mask)) { + v4l2_info(sd, "%s infoframe not transmitted\n", cri->desc); + return; + } + + memcpy(buffer, cri->header, sizeof(cri->header)); + + len = buffer[2]; + + if (len + 4 > sizeof(buffer)) { + v4l2_err(sd, "%s: invalid %s infoframe length %d\n", __func__, cri->desc, len); + return; + } + + if (cri->payload_addr >= 0x100) { + for (i = 0; i < len; i++) + buffer[i + 4] = adv7511_pktmem_rd(sd, cri->payload_addr + i - 0x100); + } else { + for (i = 0; i < len; i++) + buffer[i + 4] = adv7511_rd(sd, cri->payload_addr + i); + } + buffer[3] = 0; + buffer[3] = hdmi_infoframe_checksum(buffer, len + 4); + + if (hdmi_infoframe_unpack(&frame, buffer) < 0) { + v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__, cri->desc); + return; + } + + hdmi_infoframe_log(KERN_INFO, dev, &frame); +} + +static void adv7511_log_infoframes(struct v4l2_subdev *sd) +{ + static const struct adv7511_cfg_read_infoframe cri[] = { + { "AVI", 0x44, 0x10, { 0x82, 2, 13 }, 0x55 }, + { "Audio", 0x44, 0x08, { 0x84, 1, 10 }, 0x73 }, + { "SDP", 0x40, 0x40, { 0x83, 1, 25 }, 0x103 }, + }; + int i; + + for (i = 0; i < ARRAY_SIZE(cri); i++) + log_infoframe(sd, &cri[i]); +} + static int adv7511_log_status(struct v4l2_subdev *sd) { struct adv7511_state *state = get_adv7511_state(sd); @@ -480,6 +585,7 @@ static int adv7511_log_status(struct v4l2_subdev *sd) manual_cts ? "manual" : "automatic", N, CTS); v4l2_info(sd, "VIC: detected %d, sent %d\n", vic_detect, vic_sent); + adv7511_log_infoframes(sd); } if (state->dv_timings.type == V4L2_DV_BT_656_1120) v4l2_print_dv_timings(sd->name, "timings: ", @@ -488,6 +594,7 @@ static int adv7511_log_status(struct v4l2_subdev *sd) v4l2_info(sd, "no timings set\n"); v4l2_info(sd, "i2c edid addr: 0x%x\n", state->i2c_edid_addr); v4l2_info(sd, "i2c cec addr: 0x%x\n", state->i2c_cec_addr); + v4l2_info(sd, "i2c pktmem addr: 0x%x\n", state->i2c_pktmem_addr); return 0; } @@ -537,6 +644,7 @@ static int adv7511_s_power(struct v4l2_subdev *sd, int on) adv7511_wr(sd, 0xf9, 0x00); adv7511_wr(sd, 0x43, state->i2c_edid_addr); + adv7511_wr(sd, 0x45, state->i2c_pktmem_addr); /* Set number of attempts to read the EDID */ adv7511_wr(sd, 0xc9, 0xf); @@ -1381,6 +1489,7 @@ static int adv7511_probe(struct i2c_client *client, const struct i2c_device_id * /* EDID and CEC i2c addr */ state->i2c_edid_addr = state->pdata.i2c_edid << 1; state->i2c_cec_addr = state->pdata.i2c_cec << 1; + state->i2c_pktmem_addr = state->pdata.i2c_pktmem << 1; state->chip_revision = adv7511_rd(sd, 0x0); chip_id[0] = adv7511_rd(sd, 0xf5); @@ -1398,12 +1507,19 @@ static int adv7511_probe(struct i2c_client *client, const struct i2c_device_id * goto err_entity; } + state->i2c_pktmem = i2c_new_dummy(client->adapter, state->i2c_pktmem_addr >> 1); + if (state->i2c_pktmem == NULL) { + v4l2_err(sd, "failed to register pktmem i2c client\n"); + err = -ENOMEM; + goto err_unreg_edid; + } + adv7511_wr(sd, 0xe2, 0x01); /* power down cec section */ state->work_queue = create_singlethread_workqueue(sd->name); if (state->work_queue == NULL) { v4l2_err(sd, "could not create workqueue\n"); err = -ENOMEM; - goto err_unreg_cec; + goto err_unreg_pktmem; } INIT_DELAYED_WORK(&state->edid_handler, adv7511_edid_handler); @@ -1416,7 +1532,9 @@ static int adv7511_probe(struct i2c_client *client, const struct i2c_device_id * client->addr << 1, client->adapter->name); return 0; -err_unreg_cec: +err_unreg_pktmem: + i2c_unregister_device(state->i2c_pktmem); +err_unreg_edid: i2c_unregister_device(state->i2c_edid); err_entity: media_entity_cleanup(&sd->entity); @@ -1440,6 +1558,7 @@ static int adv7511_remove(struct i2c_client *client) adv7511_init_setup(sd); cancel_delayed_work(&state->edid_handler); i2c_unregister_device(state->i2c_edid); + i2c_unregister_device(state->i2c_pktmem); destroy_workqueue(state->work_queue); v4l2_device_unregister_subdev(sd); media_entity_cleanup(&sd->entity); diff --git a/drivers/media/pci/cobalt/cobalt-driver.c b/drivers/media/pci/cobalt/cobalt-driver.c index c2974e699ecf..b994b8efdc99 100644 --- a/drivers/media/pci/cobalt/cobalt-driver.c +++ b/drivers/media/pci/cobalt/cobalt-driver.c @@ -602,6 +602,7 @@ static int cobalt_subdevs_hsma_init(struct cobalt *cobalt) static struct adv7511_platform_data adv7511_pdata = { .i2c_edid = 0x7e >> 1, .i2c_cec = 0x7c >> 1, + .i2c_pktmem = 0x70 >> 1, .cec_clk = 12000000, }; static struct i2c_board_info adv7511_info = { diff --git a/include/media/adv7511.h b/include/media/adv7511.h index f351eff404d6..d83b91d80764 100644 --- a/include/media/adv7511.h +++ b/include/media/adv7511.h @@ -42,6 +42,7 @@ struct adv7511_cec_arg { struct adv7511_platform_data { u8 i2c_edid; u8 i2c_cec; + u8 i2c_pktmem; u32 cec_clk; }; -- cgit v1.2.3-59-g8ed1b From 516613c17747bbca6432c84ab841dd0dd8b8db83 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 7 Jun 2015 07:32:33 -0300 Subject: [media] adv7604: log infoframes Add support for logging the detected InfoFrames for the adv76xx. Helps in debugging what is actually received on the HDMI link. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/Kconfig | 1 + drivers/media/i2c/adv7604.c | 87 ++++++++++++++++++++++++++++++--------------- 2 files changed, 59 insertions(+), 29 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index c92180d4036e..71ee8f586430 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -197,6 +197,7 @@ config VIDEO_ADV7183 config VIDEO_ADV7604 tristate "Analog Devices ADV7604 decoder" depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && GPIOLIB + select HDMI ---help--- Support for the Analog Devices ADV7604 video decoder. diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index aaa37b0e9ed4..757b6b581b6d 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -95,6 +96,13 @@ struct adv76xx_format_info { u8 op_format_sel; }; +struct adv76xx_cfg_read_infoframe { + const char *desc; + u8 present_mask; + u8 head_addr; + u8 payload_addr; +}; + struct adv76xx_chip_info { enum adv76xx_type type; @@ -2127,46 +2135,67 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) /*********** avi info frame CEA-861-E **************/ -static void print_avi_infoframe(struct v4l2_subdev *sd) +static const struct adv76xx_cfg_read_infoframe adv76xx_cri[] = { + { "AVI", 0x01, 0xe0, 0x00 }, + { "Audio", 0x02, 0xe3, 0x1c }, + { "SDP", 0x04, 0xe6, 0x2a }, + { "Vendor", 0x10, 0xec, 0x54 } +}; + +static int adv76xx_read_infoframe(struct v4l2_subdev *sd, int index, + union hdmi_infoframe *frame) { + uint8_t buffer[32]; + u8 len; int i; - u8 buf[14]; - u8 avi_len; - u8 avi_ver; - if (!is_hdmi(sd)) { - v4l2_info(sd, "receive DVI-D signal (AVI infoframe not supported)\n"); - return; + if (!(io_read(sd, 0x60) & adv76xx_cri[index].present_mask)) { + v4l2_info(sd, "%s infoframe not received\n", + adv76xx_cri[index].desc); + return -ENOENT; } - if (!(io_read(sd, 0x60) & 0x01)) { - v4l2_info(sd, "AVI infoframe not received\n"); - return; + + for (i = 0; i < 3; i++) + buffer[i] = infoframe_read(sd, + adv76xx_cri[index].head_addr + i); + + len = buffer[2] + 1; + + if (len + 3 > sizeof(buffer)) { + v4l2_err(sd, "%s: invalid %s infoframe length %d\n", __func__, + adv76xx_cri[index].desc, len); + return -ENOENT; } - if (io_read(sd, 0x83) & 0x01) { - v4l2_info(sd, "AVI infoframe checksum error has occurred earlier\n"); - io_write(sd, 0x85, 0x01); /* clear AVI_INF_CKS_ERR_RAW */ - if (io_read(sd, 0x83) & 0x01) { - v4l2_info(sd, "AVI infoframe checksum error still present\n"); - io_write(sd, 0x85, 0x01); /* clear AVI_INF_CKS_ERR_RAW */ - } + for (i = 0; i < len; i++) + buffer[i + 3] = infoframe_read(sd, + adv76xx_cri[index].payload_addr + i); + + if (hdmi_infoframe_unpack(frame, buffer) < 0) { + v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__, + adv76xx_cri[index].desc); + return -ENOENT; } + return 0; +} - avi_len = infoframe_read(sd, 0xe2); - avi_ver = infoframe_read(sd, 0xe1); - v4l2_info(sd, "AVI infoframe version %d (%d byte)\n", - avi_ver, avi_len); +static void adv76xx_log_infoframes(struct v4l2_subdev *sd) +{ + int i; - if (avi_ver != 0x02) + if (!is_hdmi(sd)) { + v4l2_info(sd, "receive DVI-D signal, no infoframes\n"); return; + } - for (i = 0; i < 14; i++) - buf[i] = infoframe_read(sd, i); + for (i = 0; i < ARRAY_SIZE(adv76xx_cri); i++) { + union hdmi_infoframe frame; + struct i2c_client *client = v4l2_get_subdevdata(sd); - v4l2_info(sd, - "\t%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", - buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], - buf[8], buf[9], buf[10], buf[11], buf[12], buf[13]); + if (adv76xx_read_infoframe(sd, i, &frame)) + return; + hdmi_infoframe_log(KERN_INFO, &client->dev, &frame); + } } static int adv76xx_log_status(struct v4l2_subdev *sd) @@ -2302,7 +2331,7 @@ static int adv76xx_log_status(struct v4l2_subdev *sd) v4l2_info(sd, "Deep color mode: %s\n", deep_color_mode_txt[(hdmi_read(sd, 0x0b) & 0x60) >> 5]); - print_avi_infoframe(sd); + adv76xx_log_infoframes(sd); } return 0; -- cgit v1.2.3-59-g8ed1b From 5dd7d88a5e730491018d14a7e9ace20e225a37e6 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 7 Jun 2015 07:32:34 -0300 Subject: [media] adv7604: fix broken saturator check The logging of the saturator status was wrong due to an incorrect condition. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7604.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 757b6b581b6d..c04e0dd6a7f8 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -2292,7 +2292,7 @@ static int adv76xx_log_status(struct v4l2_subdev *sd) v4l2_info(sd, "Output color space: %s %s, saturator %s\n", (reg_io_0x02 & 0x02) ? "RGB" : "YCbCr", (reg_io_0x02 & 0x04) ? "(16-235)" : "(0-255)", - ((reg_io_0x02 & 0x04) ^ (reg_io_0x02 & 0x01)) ? + (((reg_io_0x02 >> 2) & 0x01) ^ (reg_io_0x02 & 0x01)) ? "enabled" : "disabled"); v4l2_info(sd, "Color space conversion: %s\n", csc_coeff_sel_rb[cp_read(sd, info->cp_csc) >> 4]); -- cgit v1.2.3-59-g8ed1b From 7a5d99e7c9702932c266cffb71afd4e1f2282b31 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 7 Jun 2015 07:32:35 -0300 Subject: [media] adv7604: log alt-gamma and HDMI colorspace Log the alternate gamma state and the HDMI colorspace that the adv device detected. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7604.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index c04e0dd6a7f8..daf9386a5031 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -2222,6 +2222,14 @@ static int adv76xx_log_status(struct v4l2_subdev *sd) "invalid", "invalid", "invalid", "invalid", "invalid", "invalid", "invalid", "automatic" }; + static const char * const hdmi_color_space_txt[16] = { + "RGB limited range (16-235)", "RGB full range (0-255)", + "YCbCr Bt.601 (16-235)", "YCbCr Bt.709 (16-235)", + "xvYCC Bt.601", "xvYCC Bt.709", + "YCbCr Bt.601 (0-255)", "YCbCr Bt.709 (0-255)", + "sYCC", "Adobe YCC 601", "AdobeRGB", "invalid", "invalid", + "invalid", "invalid", "invalid" + }; static const char * const rgb_quantization_range_txt[] = { "Automatic", "RGB limited range (16-235)", @@ -2289,11 +2297,12 @@ static int adv76xx_log_status(struct v4l2_subdev *sd) rgb_quantization_range_txt[state->rgb_quantization_range]); v4l2_info(sd, "Input color space: %s\n", input_color_space_txt[reg_io_0x02 >> 4]); - v4l2_info(sd, "Output color space: %s %s, saturator %s\n", + v4l2_info(sd, "Output color space: %s %s, saturator %s, alt-gamma %s\n", (reg_io_0x02 & 0x02) ? "RGB" : "YCbCr", (reg_io_0x02 & 0x04) ? "(16-235)" : "(0-255)", (((reg_io_0x02 >> 2) & 0x01) ^ (reg_io_0x02 & 0x01)) ? - "enabled" : "disabled"); + "enabled" : "disabled", + (reg_io_0x02 & 0x08) ? "enabled" : "disabled"); v4l2_info(sd, "Color space conversion: %s\n", csc_coeff_sel_rb[cp_read(sd, info->cp_csc) >> 4]); @@ -2330,6 +2339,7 @@ static int adv76xx_log_status(struct v4l2_subdev *sd) v4l2_info(sd, "AV Mute: %s\n", (hdmi_read(sd, 0x04) & 0x40) ? "on" : "off"); v4l2_info(sd, "Deep color mode: %s\n", deep_color_mode_txt[(hdmi_read(sd, 0x0b) & 0x60) >> 5]); + v4l2_info(sd, "HDMI colorspace: %s\n", hdmi_color_space_txt[hdmi_read(sd, 0x53) & 0xf]); adv76xx_log_infoframes(sd); } -- cgit v1.2.3-59-g8ed1b From dc0cf4cfed89d3a784a8d1c5897fae8f6a137fa5 Mon Sep 17 00:00:00 2001 From: Prashant Laddha Date: Fri, 5 Jun 2015 05:13:31 -0300 Subject: [media] v4l2-dv-timing: avoid rounding twice in gtf hblank calc Currently, in gtf hblank calculations, the rounding is used twice, one at intermediate division and one at final state where hblank is rounded to nearest multiple of twice cell granularity. This error got introduced in 'commit d7ed5a3ddaec ("[media] v4l2-dv-timings: fix rounding in hblank and hsync calculation"), where it missed combining the rounding step. Correcting the same in this patch. Signed-off-by: Prashant Laddha Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-dv-timings.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c index 5792192bce6c..89866100a74a 100644 --- a/drivers/media/v4l2-core/v4l2-dv-timings.c +++ b/drivers/media/v4l2-core/v4l2-dv-timings.c @@ -561,20 +561,22 @@ bool v4l2_detect_gtf(unsigned frame_height, num = ((image_width * GTF_D_C_PRIME * (u64)hfreq) - ((u64)image_width * GTF_D_M_PRIME * 1000)); - den = hfreq * (100 - GTF_D_C_PRIME) + GTF_D_M_PRIME * 1000; + den = (hfreq * (100 - GTF_D_C_PRIME) + GTF_D_M_PRIME * 1000) * + (2 * GTF_CELL_GRAN); h_blank = div_u64((num + (den >> 1)), den); + h_blank *= (2 * GTF_CELL_GRAN); } else { u64 num; u32 den; num = ((image_width * GTF_S_C_PRIME * (u64)hfreq) - ((u64)image_width * GTF_S_M_PRIME * 1000)); - den = hfreq * (100 - GTF_S_C_PRIME) + GTF_S_M_PRIME * 1000; + den = (hfreq * (100 - GTF_S_C_PRIME) + GTF_S_M_PRIME * 1000) * + (2 * GTF_CELL_GRAN); h_blank = div_u64((num + (den >> 1)), den); + h_blank *= (2 * GTF_CELL_GRAN); } - h_blank = ((h_blank + GTF_CELL_GRAN) / (2 * GTF_CELL_GRAN)) * - (2 * GTF_CELL_GRAN); frame_width = image_width + h_blank; pix_clk = (image_width + h_blank) * hfreq; -- cgit v1.2.3-59-g8ed1b From 8cf6874e84ba64488975a07fda267486a77ac5a3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 5 Jun 2015 05:30:02 -0300 Subject: [media] v4l2-dv-timings: support interlaced in v4l2_print_dv_timings The v4l2_print_dv_timings() didn't log the interlaced format correctly. The timings for the bottom field weren't logged and the fields per second value was half of what it should have been. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-dv-timings.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c index 89866100a74a..903140591269 100644 --- a/drivers/media/v4l2-core/v4l2-dv-timings.c +++ b/drivers/media/v4l2-core/v4l2-dv-timings.c @@ -262,6 +262,8 @@ void v4l2_print_dv_timings(const char *dev_prefix, const char *prefix, htot = V4L2_DV_BT_FRAME_WIDTH(bt); vtot = V4L2_DV_BT_FRAME_HEIGHT(bt); + if (bt->interlaced) + vtot /= 2; if (prefix == NULL) prefix = ""; @@ -282,6 +284,11 @@ void v4l2_print_dv_timings(const char *dev_prefix, const char *prefix, dev_prefix, bt->vfrontporch, (bt->polarities & V4L2_DV_VSYNC_POS_POL) ? "+" : "-", bt->vsync, bt->vbackporch); + if (bt->interlaced) + pr_info("%s: vertical bottom field: fp = %u, %ssync = %u, bp = %u\n", + dev_prefix, bt->il_vfrontporch, + (bt->polarities & V4L2_DV_VSYNC_POS_POL) ? "+" : "-", + bt->il_vsync, bt->il_vbackporch); pr_info("%s: pixelclock: %llu\n", dev_prefix, bt->pixelclock); pr_info("%s: flags (0x%x):%s%s%s%s%s\n", dev_prefix, bt->flags, (bt->flags & V4L2_DV_FL_REDUCED_BLANKING) ? -- cgit v1.2.3-59-g8ed1b From 061ddda681fea4a06befe1fc8e34ef2e0d14f5dc Mon Sep 17 00:00:00 2001 From: Prashant Laddha Date: Fri, 22 May 2015 02:27:34 -0300 Subject: [media] v4l2-dv-timings: add interlace support in detect cvt/gtf Extend detect_cvt/gtf API to indicate the format type (interlaced or progressive). In case of interlaced, the vertical front and back porch and vsync values for both (odd,even) fields are considered to derive image height. Populated vsync, vertical front, back porch values in bt timing structure for even and odd fields and updated the flags appropriately. Also modified the functions calling the detect_cvt/gtf(). As of now these functions are calling detect_cvt/gtf() with interlaced flag set to false. Cc: Martin Bugge Cc: Mats Randgaard Cc: Laurent Pinchart Signed-off-by: Prashant Laddha Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7604.c | 4 +-- drivers/media/i2c/adv7842.c | 4 +-- drivers/media/platform/vivid/vivid-vid-cap.c | 5 +-- drivers/media/v4l2-core/v4l2-dv-timings.c | 53 ++++++++++++++++++++++++---- include/media/v4l2-dv-timings.h | 6 ++-- 5 files changed, 58 insertions(+), 14 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index daf9386a5031..808360fd6539 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -1331,12 +1331,12 @@ static int stdi2dv_timings(struct v4l2_subdev *sd, if (v4l2_detect_cvt(stdi->lcf + 1, hfreq, stdi->lcvs, (stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) | (stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0), - timings)) + false, timings)) return 0; if (v4l2_detect_gtf(stdi->lcf + 1, hfreq, stdi->lcvs, (stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) | (stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0), - state->aspect_ratio, timings)) + false, state->aspect_ratio, timings)) return 0; v4l2_dbg(2, debug, sd, diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index f14ea78a7c9c..4cf79b2422d4 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -1445,12 +1445,12 @@ static int stdi2dv_timings(struct v4l2_subdev *sd, if (v4l2_detect_cvt(stdi->lcf + 1, hfreq, stdi->lcvs, (stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) | (stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0), - timings)) + false, timings)) return 0; if (v4l2_detect_gtf(stdi->lcf + 1, hfreq, stdi->lcvs, (stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) | (stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0), - state->aspect_ratio, timings)) + false, state->aspect_ratio, timings)) return 0; v4l2_dbg(2, debug, sd, diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c index 7b80bda4c34c..d83bdf7df194 100644 --- a/drivers/media/platform/vivid/vivid-vid-cap.c +++ b/drivers/media/platform/vivid/vivid-vid-cap.c @@ -1628,7 +1628,7 @@ static bool valid_cvt_gtf_timings(struct v4l2_dv_timings *timings) if (bt->standards == 0 || (bt->standards & V4L2_DV_BT_STD_CVT)) { if (v4l2_detect_cvt(total_v_lines, h_freq, bt->vsync, - bt->polarities, timings)) + bt->polarities, false, timings)) return true; } @@ -1639,7 +1639,8 @@ static bool valid_cvt_gtf_timings(struct v4l2_dv_timings *timings) &aspect_ratio.numerator, &aspect_ratio.denominator); if (v4l2_detect_gtf(total_v_lines, h_freq, bt->vsync, - bt->polarities, aspect_ratio, timings)) + bt->polarities, false, + aspect_ratio, timings)) return true; } return false; diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c index 903140591269..04dc71e3ebf0 100644 --- a/drivers/media/v4l2-core/v4l2-dv-timings.c +++ b/drivers/media/v4l2-core/v4l2-dv-timings.c @@ -346,6 +346,7 @@ EXPORT_SYMBOL_GPL(v4l2_print_dv_timings); * @vsync - the height of the vertical sync in lines. * @polarities - the horizontal and vertical polarities (same as struct * v4l2_bt_timings polarities). + * @interlaced - if this flag is true, it indicates interlaced format * @fmt - the resulting timings. * * This function will attempt to detect if the given values correspond to a @@ -357,7 +358,7 @@ EXPORT_SYMBOL_GPL(v4l2_print_dv_timings); * detection function. */ bool v4l2_detect_cvt(unsigned frame_height, unsigned hfreq, unsigned vsync, - u32 polarities, struct v4l2_dv_timings *fmt) + u32 polarities, bool interlaced, struct v4l2_dv_timings *fmt) { int v_fp, v_bp, h_fp, h_bp, hsync; int frame_width, image_height, image_width; @@ -392,7 +393,11 @@ bool v4l2_detect_cvt(unsigned frame_height, unsigned hfreq, unsigned vsync, if (v_bp < CVT_MIN_V_BPORCH) v_bp = CVT_MIN_V_BPORCH; } - image_height = (frame_height - v_fp - vsync - v_bp + 1) & ~0x1; + + if (interlaced) + image_height = (frame_height - 2 * v_fp - 2 * vsync - 2 * v_bp) & ~0x1; + else + image_height = (frame_height - v_fp - vsync - v_bp + 1) & ~0x1; if (image_height < 0) return false; @@ -465,11 +470,27 @@ bool v4l2_detect_cvt(unsigned frame_height, unsigned hfreq, unsigned vsync, fmt->bt.hsync = hsync; fmt->bt.vsync = vsync; fmt->bt.hbackporch = frame_width - image_width - h_fp - hsync; - fmt->bt.vbackporch = frame_height - image_height - v_fp - vsync; + + if (!interlaced) { + fmt->bt.vbackporch = frame_height - image_height - v_fp - vsync; + fmt->bt.interlaced = V4L2_DV_PROGRESSIVE; + } else { + fmt->bt.vbackporch = (frame_height - image_height - 2 * v_fp - + 2 * vsync) / 2; + fmt->bt.il_vbackporch = frame_height - image_height - 2 * v_fp - + 2 * vsync - fmt->bt.vbackporch; + fmt->bt.il_vfrontporch = v_fp; + fmt->bt.il_vsync = vsync; + fmt->bt.flags |= V4L2_DV_FL_HALF_LINE; + fmt->bt.interlaced = V4L2_DV_INTERLACED; + } + fmt->bt.pixelclock = pix_clk; fmt->bt.standards = V4L2_DV_BT_STD_CVT; + if (reduced_blanking) fmt->bt.flags |= V4L2_DV_FL_REDUCED_BLANKING; + return true; } EXPORT_SYMBOL_GPL(v4l2_detect_cvt); @@ -508,6 +529,7 @@ EXPORT_SYMBOL_GPL(v4l2_detect_cvt); * @vsync - the height of the vertical sync in lines. * @polarities - the horizontal and vertical polarities (same as struct * v4l2_bt_timings polarities). + * @interlaced - if this flag is true, it indicates interlaced format * @aspect - preferred aspect ratio. GTF has no method of determining the * aspect ratio in order to derive the image width from the * image height, so it has to be passed explicitly. Usually @@ -523,6 +545,7 @@ bool v4l2_detect_gtf(unsigned frame_height, unsigned hfreq, unsigned vsync, u32 polarities, + bool interlaced, struct v4l2_fract aspect, struct v4l2_dv_timings *fmt) { @@ -547,9 +570,11 @@ bool v4l2_detect_gtf(unsigned frame_height, /* Vertical */ v_fp = GTF_V_FP; - v_bp = (GTF_MIN_VSYNC_BP * hfreq + 500000) / 1000000 - vsync; - image_height = (frame_height - v_fp - vsync - v_bp + 1) & ~0x1; + if (interlaced) + image_height = (frame_height - 2 * v_fp - 2 * vsync - 2 * v_bp) & ~0x1; + else + image_height = (frame_height - v_fp - vsync - v_bp + 1) & ~0x1; if (image_height < 0) return false; @@ -603,11 +628,27 @@ bool v4l2_detect_gtf(unsigned frame_height, fmt->bt.hsync = hsync; fmt->bt.vsync = vsync; fmt->bt.hbackporch = frame_width - image_width - h_fp - hsync; - fmt->bt.vbackporch = frame_height - image_height - v_fp - vsync; + + if (!interlaced) { + fmt->bt.vbackporch = frame_height - image_height - v_fp - vsync; + fmt->bt.interlaced = V4L2_DV_PROGRESSIVE; + } else { + fmt->bt.vbackporch = (frame_height - image_height - 2 * v_fp - + 2 * vsync) / 2; + fmt->bt.il_vbackporch = frame_height - image_height - 2 * v_fp - + 2 * vsync - fmt->bt.vbackporch; + fmt->bt.il_vfrontporch = v_fp; + fmt->bt.il_vsync = vsync; + fmt->bt.flags |= V4L2_DV_FL_HALF_LINE; + fmt->bt.interlaced = V4L2_DV_INTERLACED; + } + fmt->bt.pixelclock = pix_clk; fmt->bt.standards = V4L2_DV_BT_STD_GTF; + if (!default_gtf) fmt->bt.flags |= V4L2_DV_FL_REDUCED_BLANKING; + return true; } EXPORT_SYMBOL_GPL(v4l2_detect_gtf); diff --git a/include/media/v4l2-dv-timings.h b/include/media/v4l2-dv-timings.h index 4becc6716393..eecd3102a618 100644 --- a/include/media/v4l2-dv-timings.h +++ b/include/media/v4l2-dv-timings.h @@ -117,6 +117,7 @@ void v4l2_print_dv_timings(const char *dev_prefix, const char *prefix, * @vsync - the height of the vertical sync in lines. * @polarities - the horizontal and vertical polarities (same as struct * v4l2_bt_timings polarities). + * @interlaced - if this flag is true, it indicates interlaced format * @fmt - the resulting timings. * * This function will attempt to detect if the given values correspond to a @@ -124,7 +125,7 @@ void v4l2_print_dv_timings(const char *dev_prefix, const char *prefix, * in with the found CVT timings. */ bool v4l2_detect_cvt(unsigned frame_height, unsigned hfreq, unsigned vsync, - u32 polarities, struct v4l2_dv_timings *fmt); + u32 polarities, bool interlaced, struct v4l2_dv_timings *fmt); /** v4l2_detect_gtf - detect if the given timings follow the GTF standard * @frame_height - the total height of the frame (including blanking) in lines. @@ -132,6 +133,7 @@ bool v4l2_detect_cvt(unsigned frame_height, unsigned hfreq, unsigned vsync, * @vsync - the height of the vertical sync in lines. * @polarities - the horizontal and vertical polarities (same as struct * v4l2_bt_timings polarities). + * @interlaced - if this flag is true, it indicates interlaced format * @aspect - preferred aspect ratio. GTF has no method of determining the * aspect ratio in order to derive the image width from the * image height, so it has to be passed explicitly. Usually @@ -144,7 +146,7 @@ bool v4l2_detect_cvt(unsigned frame_height, unsigned hfreq, unsigned vsync, * in with the found GTF timings. */ bool v4l2_detect_gtf(unsigned frame_height, unsigned hfreq, unsigned vsync, - u32 polarities, struct v4l2_fract aspect, + u32 polarities, bool interlaced, struct v4l2_fract aspect, struct v4l2_dv_timings *fmt); /** v4l2_calc_aspect_ratio - calculate the aspect ratio based on bytes -- cgit v1.2.3-59-g8ed1b From d0154d83a8ed8166411851888b92ccfd937c2515 Mon Sep 17 00:00:00 2001 From: Prashant Laddha Date: Fri, 22 May 2015 02:27:35 -0300 Subject: [media] vivid: Use interlaced info for cvt/gtf timing detection The detect_cvt/gtf() now supports timing calculations for interlaced format. Signed-off-by: Prashant Laddha Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-vid-cap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c index d83bdf7df194..c4268d1b2f82 100644 --- a/drivers/media/platform/vivid/vivid-vid-cap.c +++ b/drivers/media/platform/vivid/vivid-vid-cap.c @@ -1628,7 +1628,7 @@ static bool valid_cvt_gtf_timings(struct v4l2_dv_timings *timings) if (bt->standards == 0 || (bt->standards & V4L2_DV_BT_STD_CVT)) { if (v4l2_detect_cvt(total_v_lines, h_freq, bt->vsync, - bt->polarities, false, timings)) + bt->polarities, bt->interlaced, timings)) return true; } @@ -1639,7 +1639,7 @@ static bool valid_cvt_gtf_timings(struct v4l2_dv_timings *timings) &aspect_ratio.numerator, &aspect_ratio.denominator); if (v4l2_detect_gtf(total_v_lines, h_freq, bt->vsync, - bt->polarities, false, + bt->polarities, bt->interlaced, aspect_ratio, timings)) return true; } -- cgit v1.2.3-59-g8ed1b From 7f3c2e1d1df46a06c37c46b2c8ba66b405434e35 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 6 Jun 2015 05:02:32 -0300 Subject: [media] cx231xx: fix compiler warning Fix this compiler warning by allocating a structure to read the eeprom instead of doing it on the stack and worse: the eeprom array is static, so that can cause problems if there are multiple cx231xx instances. cx231xx-cards.c: In function 'cx231xx_card_setup': cx231xx-cards.c:1110:1: warning: the frame size of 2064 bytes is larger than 2048 bytes [-Wframe-larger-than=] } ^ I did consider removing the code altogether since the result is actually not used at the moment, but I decided against it since it is used in other drivers and someone might want to start using it in this driver as well. And then it is useful that the code is already there. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-cards.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index fe00da105e77..a4aa2851339a 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -1092,17 +1092,25 @@ void cx231xx_card_setup(struct cx231xx *dev) case CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx: case CX231XX_BOARD_HAUPPAUGE_955Q: { - struct tveeprom tvee; - static u8 eeprom[256]; - struct i2c_client client; - - memset(&client, 0, sizeof(client)); - client.adapter = cx231xx_get_i2c_adap(dev, I2C_1_MUX_1); - client.addr = 0xa0 >> 1; + struct eeprom { + struct tveeprom tvee; + u8 eeprom[256]; + struct i2c_client client; + }; + struct eeprom *e = kzalloc(sizeof(*e), GFP_KERNEL); + + if (e == NULL) { + dev_err(dev->dev, + "failed to allocate memory to read eeprom\n"); + break; + } + e->client.adapter = cx231xx_get_i2c_adap(dev, I2C_1_MUX_1); + e->client.addr = 0xa0 >> 1; - read_eeprom(dev, &client, eeprom, sizeof(eeprom)); - tveeprom_hauppauge_analog(&client, - &tvee, eeprom + 0xc0); + read_eeprom(dev, &e->client, e->eeprom, sizeof(e->eeprom)); + tveeprom_hauppauge_analog(&e->client, + &e->tvee, e->eeprom + 0xc0); + kfree(e); break; } } -- cgit v1.2.3-59-g8ed1b From 0df289a209e02f0926042ab07d7d2595ea2d2e9b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 7 Jun 2015 14:53:52 -0300 Subject: [media] dvb: Get rid of typedev usage for enums The DVB API was originally defined using typedefs. This is against Kernel CodingStyle, and there's no good usage here. While we can't remove its usage on userspace, we can avoid its usage in Kernelspace. So, let's do it. This patch was generated by this shell script: for j in $(grep typedef include/uapi/linux/dvb/frontend.h |cut -d' ' -f 3); do for i in $(find drivers/media -name '*.[ch]' -type f) $(find drivers/staging/media -name '*.[ch]' -type f); do sed "s,${j}_t,enum $j," <$i >a && mv a $i; done; done While here, make CodingStyle fixes on the affected lines. Signed-off-by: Mauro Carvalho Chehab Acked-by: Stefan Richter # for drivers/media/firewire/* --- drivers/media/common/b2c2/flexcop-fe-tuner.c | 7 ++-- drivers/media/common/siano/smsdvb-main.c | 6 +-- drivers/media/common/siano/smsdvb.h | 2 +- drivers/media/dvb-core/dvb_frontend.c | 27 +++++++----- drivers/media/dvb-core/dvb_frontend.h | 42 ++++++++++--------- drivers/media/dvb-frontends/a8293.c | 2 +- drivers/media/dvb-frontends/af9013.c | 4 +- drivers/media/dvb-frontends/af9033.c | 4 +- drivers/media/dvb-frontends/as102_fe.c | 4 +- drivers/media/dvb-frontends/atbm8830.c | 3 +- drivers/media/dvb-frontends/au8522_dig.c | 4 +- drivers/media/dvb-frontends/au8522_priv.h | 2 +- drivers/media/dvb-frontends/bcm3510.c | 2 +- drivers/media/dvb-frontends/cx22700.c | 9 ++-- drivers/media/dvb-frontends/cx22702.c | 2 +- drivers/media/dvb-frontends/cx24110.c | 19 +++++---- drivers/media/dvb-frontends/cx24116.c | 38 +++++++++-------- drivers/media/dvb-frontends/cx24117.c | 40 +++++++++--------- drivers/media/dvb-frontends/cx24120.c | 50 +++++++++++------------ drivers/media/dvb-frontends/cx24123.c | 18 ++++---- drivers/media/dvb-frontends/cxd2820r_c.c | 2 +- drivers/media/dvb-frontends/cxd2820r_core.c | 5 ++- drivers/media/dvb-frontends/cxd2820r_priv.h | 8 ++-- drivers/media/dvb-frontends/cxd2820r_t.c | 2 +- drivers/media/dvb-frontends/cxd2820r_t2.c | 2 +- drivers/media/dvb-frontends/dib3000mb.c | 7 ++-- drivers/media/dvb-frontends/dib3000mc.c | 2 +- drivers/media/dvb-frontends/dib7000m.c | 2 +- drivers/media/dvb-frontends/dib7000p.c | 6 +-- drivers/media/dvb-frontends/dib8000.c | 10 ++--- drivers/media/dvb-frontends/dib9000.c | 4 +- drivers/media/dvb-frontends/drx39xyj/drxj.c | 2 +- drivers/media/dvb-frontends/drxd_hard.c | 2 +- drivers/media/dvb-frontends/drxk_hard.c | 2 +- drivers/media/dvb-frontends/drxk_hard.h | 2 +- drivers/media/dvb-frontends/ds3000.c | 13 +++--- drivers/media/dvb-frontends/dvb_dummy_fe.c | 9 ++-- drivers/media/dvb-frontends/ec100.c | 2 +- drivers/media/dvb-frontends/hd29l2.c | 2 +- drivers/media/dvb-frontends/hd29l2_priv.h | 2 +- drivers/media/dvb-frontends/isl6405.c | 3 +- drivers/media/dvb-frontends/isl6421.c | 6 ++- drivers/media/dvb-frontends/l64781.c | 2 +- drivers/media/dvb-frontends/lg2160.c | 2 +- drivers/media/dvb-frontends/lgdt3305.c | 4 +- drivers/media/dvb-frontends/lgdt3306a.c | 9 ++-- drivers/media/dvb-frontends/lgdt330x.c | 8 ++-- drivers/media/dvb-frontends/lgs8gl5.c | 2 +- drivers/media/dvb-frontends/lgs8gxx.c | 3 +- drivers/media/dvb-frontends/lnbp21.c | 4 +- drivers/media/dvb-frontends/lnbp22.c | 3 +- drivers/media/dvb-frontends/m88ds3103.c | 9 ++-- drivers/media/dvb-frontends/m88ds3103_priv.h | 4 +- drivers/media/dvb-frontends/m88rs2000.c | 19 +++++---- drivers/media/dvb-frontends/mb86a16.c | 7 ++-- drivers/media/dvb-frontends/mb86a16.h | 3 +- drivers/media/dvb-frontends/mb86a20s.c | 6 +-- drivers/media/dvb-frontends/mt312.c | 17 ++++---- drivers/media/dvb-frontends/mt352.c | 2 +- drivers/media/dvb-frontends/nxt200x.c | 2 +- drivers/media/dvb-frontends/nxt6000.c | 12 ++++-- drivers/media/dvb-frontends/or51132.c | 6 +-- drivers/media/dvb-frontends/or51211.c | 2 +- drivers/media/dvb-frontends/rtl2830.c | 2 +- drivers/media/dvb-frontends/rtl2830_priv.h | 2 +- drivers/media/dvb-frontends/rtl2832.c | 2 +- drivers/media/dvb-frontends/rtl2832_priv.h | 2 +- drivers/media/dvb-frontends/s5h1409.c | 6 +-- drivers/media/dvb-frontends/s5h1411.c | 6 +-- drivers/media/dvb-frontends/s5h1420.c | 23 +++++++---- drivers/media/dvb-frontends/s5h1432.c | 4 +- drivers/media/dvb-frontends/s921.c | 6 +-- drivers/media/dvb-frontends/si2165.c | 2 +- drivers/media/dvb-frontends/si2168.c | 2 +- drivers/media/dvb-frontends/si2168_priv.h | 4 +- drivers/media/dvb-frontends/si21xx.c | 10 ++--- drivers/media/dvb-frontends/sp8870.c | 3 +- drivers/media/dvb-frontends/sp887x.c | 2 +- drivers/media/dvb-frontends/stb0899_drv.c | 8 ++-- drivers/media/dvb-frontends/stv0288.c | 11 ++--- drivers/media/dvb-frontends/stv0297.c | 11 +++-- drivers/media/dvb-frontends/stv0299.c | 22 ++++++---- drivers/media/dvb-frontends/stv0367.c | 12 +++--- drivers/media/dvb-frontends/stv0367_priv.h | 2 +- drivers/media/dvb-frontends/stv0900_core.c | 6 ++- drivers/media/dvb-frontends/stv090x.c | 5 ++- drivers/media/dvb-frontends/stv6110.c | 2 +- drivers/media/dvb-frontends/tc90522.c | 17 ++++---- drivers/media/dvb-frontends/tda10021.c | 7 ++-- drivers/media/dvb-frontends/tda10023.c | 3 +- drivers/media/dvb-frontends/tda10048.c | 2 +- drivers/media/dvb-frontends/tda1004x.c | 3 +- drivers/media/dvb-frontends/tda10071.c | 10 ++--- drivers/media/dvb-frontends/tda10071_priv.h | 10 ++--- drivers/media/dvb-frontends/tda10086.c | 9 ++-- drivers/media/dvb-frontends/tda8083.c | 38 ++++++++++------- drivers/media/dvb-frontends/ves1820.c | 6 ++- drivers/media/dvb-frontends/ves1x93.c | 15 ++++--- drivers/media/dvb-frontends/zl10353.c | 2 +- drivers/media/firewire/firedtv-fe.c | 8 ++-- drivers/media/firewire/firedtv.h | 4 +- drivers/media/pci/bt8xx/dst.c | 25 +++++++----- drivers/media/pci/bt8xx/dst_common.h | 12 +++--- drivers/media/pci/cx23885/cx23885-dvb.c | 10 +++-- drivers/media/pci/cx23885/cx23885-f300.c | 2 +- drivers/media/pci/cx23885/cx23885-f300.h | 2 +- drivers/media/pci/cx23885/cx23885.h | 2 +- drivers/media/pci/cx88/cx88-dvb.c | 12 +++--- drivers/media/pci/cx88/cx88.h | 5 ++- drivers/media/pci/dm1105/dm1105.c | 3 +- drivers/media/pci/mantis/mantis_vp1034.c | 2 +- drivers/media/pci/mantis/mantis_vp1034.h | 3 +- drivers/media/pci/ngene/ngene.h | 2 +- drivers/media/pci/pt1/pt1.c | 6 +-- drivers/media/pci/pt1/va1j5jf8007s.c | 4 +- drivers/media/pci/pt1/va1j5jf8007t.c | 4 +- drivers/media/pci/pt3/pt3.c | 2 +- drivers/media/pci/saa7134/saa7134-dvb.c | 6 ++- drivers/media/pci/saa7134/saa7134.h | 3 +- drivers/media/pci/ttpci/av7110.c | 18 ++++---- drivers/media/pci/ttpci/av7110.h | 27 +++++++----- drivers/media/pci/ttpci/budget-core.c | 3 +- drivers/media/pci/ttpci/budget-patch.c | 15 ++++--- drivers/media/pci/ttpci/budget.c | 12 ++++-- drivers/media/pci/ttpci/budget.h | 2 +- drivers/media/usb/dvb-usb-v2/af9015.c | 2 +- drivers/media/usb/dvb-usb-v2/af9015.h | 2 +- drivers/media/usb/dvb-usb-v2/dvbsky.c | 11 ++--- drivers/media/usb/dvb-usb-v2/lmedm04.c | 10 ++--- drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c | 14 +++---- drivers/media/usb/dvb-usb/af9005-fe.c | 5 ++- drivers/media/usb/dvb-usb/az6027.c | 3 +- drivers/media/usb/dvb-usb/cinergyT2-fe.c | 2 +- drivers/media/usb/dvb-usb/dib0700.h | 2 +- drivers/media/usb/dvb-usb/dib0700_devices.c | 2 +- drivers/media/usb/dvb-usb/dtt200u-fe.c | 7 ++-- drivers/media/usb/dvb-usb/dw2102.c | 13 +++--- drivers/media/usb/dvb-usb/friio-fe.c | 3 +- drivers/media/usb/dvb-usb/gp8psk-fe.c | 13 +++--- drivers/media/usb/dvb-usb/opera1.c | 3 +- drivers/media/usb/dvb-usb/technisat-usb2.c | 2 +- drivers/media/usb/dvb-usb/vp702x-fe.c | 17 ++++---- drivers/media/usb/dvb-usb/vp7045-fe.c | 3 +- drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c | 9 ++-- drivers/media/usb/ttusb-dec/ttusbdecfe.c | 10 +++-- drivers/staging/media/mn88472/mn88472.c | 2 +- drivers/staging/media/mn88472/mn88472_priv.h | 2 +- drivers/staging/media/mn88473/mn88473.c | 2 +- drivers/staging/media/mn88473/mn88473_priv.h | 2 +- include/uapi/linux/dvb/frontend.h | 4 +- 150 files changed, 630 insertions(+), 492 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/b2c2/flexcop-fe-tuner.c b/drivers/media/common/b2c2/flexcop-fe-tuner.c index 2426062fcb3c..5e5696729eca 100644 --- a/drivers/media/common/b2c2/flexcop-fe-tuner.c +++ b/drivers/media/common/b2c2/flexcop-fe-tuner.c @@ -39,7 +39,8 @@ static int flexcop_fe_request_firmware(struct dvb_frontend *fe, /* lnb control */ #if FE_SUPPORTED(MT312) || FE_SUPPORTED(STV0299) -static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +static int flexcop_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { struct flexcop_device *fc = fe->dvb->priv; flexcop_ibi_value v; @@ -78,7 +79,7 @@ static int flexcop_sleep(struct dvb_frontend* fe) /* SkyStar2 DVB-S rev 2.3 */ #if FE_SUPPORTED(MT312) && FE_SUPPORTED(PLL) -static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) +static int flexcop_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone) { /* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */ struct flexcop_device *fc = fe->dvb->priv; @@ -157,7 +158,7 @@ static int flexcop_diseqc_send_master_cmd(struct dvb_frontend *fe, } static int flexcop_diseqc_send_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t minicmd) + enum fe_sec_mini_cmd minicmd) { return flexcop_send_diseqc_msg(fe, 0, NULL, minicmd); } diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c index 367b8e77feb8..f4305ae800f4 100644 --- a/drivers/media/common/siano/smsdvb-main.c +++ b/drivers/media/common/siano/smsdvb-main.c @@ -753,7 +753,7 @@ static inline int led_feedback(struct smsdvb_client_t *client) SMS_LED_HI : SMS_LED_LO); } -static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) +static int smsdvb_read_status(struct dvb_frontend *fe, enum fe_status *stat) { int rc; struct smsdvb_client_t *client; @@ -900,7 +900,7 @@ static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe) /* Disable LNA, if any. An error is returned if no LNA is present */ ret = sms_board_lna_control(client->coredev, 0); if (ret == 0) { - fe_status_t status; + enum fe_status status; /* tune with LNA off at first */ ret = smsdvb_sendrequest_and_wait(client, &msg, sizeof(msg), @@ -971,7 +971,7 @@ static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe) /* Disable LNA, if any. An error is returned if no LNA is present */ ret = sms_board_lna_control(client->coredev, 0); if (ret == 0) { - fe_status_t status; + enum fe_status status; /* tune with LNA off at first */ ret = smsdvb_sendrequest_and_wait(client, &msg, sizeof(msg), diff --git a/drivers/media/common/siano/smsdvb.h b/drivers/media/common/siano/smsdvb.h index ae36d0ae0fb1..b15754d95ec0 100644 --- a/drivers/media/common/siano/smsdvb.h +++ b/drivers/media/common/siano/smsdvb.h @@ -40,7 +40,7 @@ struct smsdvb_client_t { struct dmxdev dmxdev; struct dvb_frontend frontend; - fe_status_t fe_status; + enum fe_status fe_status; struct completion tune_done; struct completion stats_done; diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index a894d4c99ee8..55a6b0500615 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -110,7 +110,7 @@ struct dvb_frontend_private { struct task_struct *thread; unsigned long release_jiffies; unsigned int wakeup; - fe_status_t status; + enum fe_status status; unsigned long tune_mode_flags; unsigned int delay; unsigned int reinitialise; @@ -198,7 +198,8 @@ static enum dvbv3_emulation_type dvbv3_type(u32 delivery_system) } } -static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status) +static void dvb_frontend_add_event(struct dvb_frontend *fe, + enum fe_status status) { struct dvb_frontend_private *fepriv = fe->frontend_priv; struct dvb_fe_events *events = &fepriv->events; @@ -429,7 +430,7 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra static void dvb_frontend_swzigzag(struct dvb_frontend *fe) { - fe_status_t s = 0; + enum fe_status s = 0; int retval = 0; struct dvb_frontend_private *fepriv = fe->frontend_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache, tmp; @@ -690,7 +691,7 @@ static int dvb_frontend_thread(void *data) { struct dvb_frontend *fe = data; struct dvb_frontend_private *fepriv = fe->frontend_priv; - fe_status_t s; + enum fe_status s; enum dvbfe_algo algo; #ifdef CONFIG_MEDIA_CONTROLLER_DVB int ret; @@ -2341,7 +2342,7 @@ static int dvb_frontend_ioctl_legacy(struct file *file, } case FE_READ_STATUS: { - fe_status_t* status = parg; + enum fe_status *status = parg; /* if retune was requested but hasn't occurred yet, prevent * that user get signal state from previous tuning */ @@ -2411,7 +2412,8 @@ static int dvb_frontend_ioctl_legacy(struct file *file, case FE_DISEQC_SEND_BURST: if (fe->ops.diseqc_send_burst) { - err = fe->ops.diseqc_send_burst(fe, (fe_sec_mini_cmd_t) parg); + err = fe->ops.diseqc_send_burst(fe, + (enum fe_sec_mini_cmd)parg); fepriv->state = FESTATE_DISEQC; fepriv->status = 0; } @@ -2419,8 +2421,9 @@ static int dvb_frontend_ioctl_legacy(struct file *file, case FE_SET_TONE: if (fe->ops.set_tone) { - err = fe->ops.set_tone(fe, (fe_sec_tone_mode_t) parg); - fepriv->tone = (fe_sec_tone_mode_t) parg; + err = fe->ops.set_tone(fe, + (enum fe_sec_tone_mode)parg); + fepriv->tone = (enum fe_sec_tone_mode)parg; fepriv->state = FESTATE_DISEQC; fepriv->status = 0; } @@ -2428,8 +2431,9 @@ static int dvb_frontend_ioctl_legacy(struct file *file, case FE_SET_VOLTAGE: if (fe->ops.set_voltage) { - err = fe->ops.set_voltage(fe, (fe_sec_voltage_t) parg); - fepriv->voltage = (fe_sec_voltage_t) parg; + err = fe->ops.set_voltage(fe, + (enum fe_sec_voltage)parg); + fepriv->voltage = (enum fe_sec_voltage)parg; fepriv->state = FESTATE_DISEQC; fepriv->status = 0; } @@ -2437,7 +2441,8 @@ static int dvb_frontend_ioctl_legacy(struct file *file, case FE_DISHNETWORK_SEND_LEGACY_CMD: if (fe->ops.dishnetwork_send_legacy_command) { - err = fe->ops.dishnetwork_send_legacy_command(fe, (unsigned long) parg); + err = fe->ops.dishnetwork_send_legacy_command(fe, + (unsigned long)parg); fepriv->state = FESTATE_DISEQC; fepriv->status = 0; } else if (fe->ops.set_voltage) { diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h index 816269e5f706..4ff82041fdfd 100644 --- a/drivers/media/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb-core/dvb_frontend.h @@ -279,7 +279,7 @@ struct dvb_frontend_ops { bool re_tune, unsigned int mode_flags, unsigned int *delay, - fe_status_t *status); + enum fe_status *status); /* get frontend tuning algorithm from the module */ enum dvbfe_algo (*get_frontend_algo)(struct dvb_frontend *fe); @@ -289,7 +289,7 @@ struct dvb_frontend_ops { int (*get_frontend)(struct dvb_frontend *fe); - int (*read_status)(struct dvb_frontend* fe, fe_status_t* status); + int (*read_status)(struct dvb_frontend *fe, enum fe_status *status); int (*read_ber)(struct dvb_frontend* fe, u32* ber); int (*read_signal_strength)(struct dvb_frontend* fe, u16* strength); int (*read_snr)(struct dvb_frontend* fe, u16* snr); @@ -298,9 +298,11 @@ struct dvb_frontend_ops { int (*diseqc_reset_overload)(struct dvb_frontend* fe); int (*diseqc_send_master_cmd)(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd); int (*diseqc_recv_slave_reply)(struct dvb_frontend* fe, struct dvb_diseqc_slave_reply* reply); - int (*diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd); - int (*set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone); - int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); + int (*diseqc_send_burst)(struct dvb_frontend *fe, + enum fe_sec_mini_cmd minicmd); + int (*set_tone)(struct dvb_frontend *fe, enum fe_sec_tone_mode tone); + int (*set_voltage)(struct dvb_frontend *fe, + enum fe_sec_voltage voltage); int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, long arg); int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd); int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable); @@ -338,24 +340,24 @@ struct dtv_frontend_properties { u32 state; u32 frequency; - fe_modulation_t modulation; + enum fe_modulation modulation; - fe_sec_voltage_t voltage; - fe_sec_tone_mode_t sectone; - fe_spectral_inversion_t inversion; - fe_code_rate_t fec_inner; - fe_transmit_mode_t transmission_mode; + enum fe_sec_voltage voltage; + enum fe_sec_tone_mode sectone; + enum fe_spectral_inversion inversion; + enum fe_code_rate fec_inner; + enum fe_transmit_mode transmission_mode; u32 bandwidth_hz; /* 0 = AUTO */ - fe_guard_interval_t guard_interval; - fe_hierarchy_t hierarchy; + enum fe_guard_interval guard_interval; + enum fe_hierarchy hierarchy; u32 symbol_rate; - fe_code_rate_t code_rate_HP; - fe_code_rate_t code_rate_LP; + enum fe_code_rate code_rate_HP; + enum fe_code_rate code_rate_LP; - fe_pilot_t pilot; - fe_rolloff_t rolloff; + enum fe_pilot pilot; + enum fe_rolloff rolloff; - fe_delivery_system_t delivery_system; + enum fe_delivery_system delivery_system; enum fe_interleaving interleaving; @@ -368,8 +370,8 @@ struct dtv_frontend_properties { u8 isdbt_layer_enabled; struct { u8 segment_count; - fe_code_rate_t fec; - fe_modulation_t modulation; + enum fe_code_rate fec; + enum fe_modulation modulation; u8 interleaving; } layer[3]; diff --git a/drivers/media/dvb-frontends/a8293.c b/drivers/media/dvb-frontends/a8293.c index 3f0cf9ee6672..97ecbe01034c 100644 --- a/drivers/media/dvb-frontends/a8293.c +++ b/drivers/media/dvb-frontends/a8293.c @@ -67,7 +67,7 @@ static int a8293_rd(struct a8293_priv *priv, u8 *val, int len) } static int a8293_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t fe_sec_voltage) + enum fe_sec_voltage fe_sec_voltage) { struct a8293_priv *priv = fe->sec_priv; int ret; diff --git a/drivers/media/dvb-frontends/af9013.c b/drivers/media/dvb-frontends/af9013.c index ba6c8f6c42a1..e23197da84af 100644 --- a/drivers/media/dvb-frontends/af9013.c +++ b/drivers/media/dvb-frontends/af9013.c @@ -39,7 +39,7 @@ struct af9013_state { u32 ucblocks; u16 snr; u32 bandwidth_hz; - fe_status_t fe_status; + enum fe_status fe_status; unsigned long set_frontend_jiffies; unsigned long read_status_jiffies; bool first_tune; @@ -983,7 +983,7 @@ err: return ret; } -static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int af9013_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct af9013_state *state = fe->demodulator_priv; int ret; diff --git a/drivers/media/dvb-frontends/af9033.c b/drivers/media/dvb-frontends/af9033.c index 82ce47bdf5dc..59018afaa95f 100644 --- a/drivers/media/dvb-frontends/af9033.c +++ b/drivers/media/dvb-frontends/af9033.c @@ -35,7 +35,7 @@ struct af9033_dev { bool ts_mode_parallel; bool ts_mode_serial; - fe_status_t fe_status; + enum fe_status fe_status; u64 post_bit_error_prev; /* for old read_ber we return (curr - prev) */ u64 post_bit_error; u64 post_bit_count; @@ -818,7 +818,7 @@ err: return ret; } -static int af9033_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int af9033_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct af9033_dev *dev = fe->demodulator_priv; int ret; diff --git a/drivers/media/dvb-frontends/as102_fe.c b/drivers/media/dvb-frontends/as102_fe.c index 493665899565..544c5f65d19a 100644 --- a/drivers/media/dvb-frontends/as102_fe.c +++ b/drivers/media/dvb-frontends/as102_fe.c @@ -32,7 +32,7 @@ struct as102_state { uint32_t ber; }; -static uint8_t as102_fe_get_code_rate(fe_code_rate_t arg) +static uint8_t as102_fe_get_code_rate(enum fe_code_rate arg) { uint8_t c; @@ -306,7 +306,7 @@ static int as102_fe_get_tune_settings(struct dvb_frontend *fe, return 0; } -static int as102_fe_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int as102_fe_read_status(struct dvb_frontend *fe, enum fe_status *status) { int ret = 0; struct as102_state *state = fe->demodulator_priv; diff --git a/drivers/media/dvb-frontends/atbm8830.c b/drivers/media/dvb-frontends/atbm8830.c index 4e11dc4b1335..8fe552e293ed 100644 --- a/drivers/media/dvb-frontends/atbm8830.c +++ b/drivers/media/dvb-frontends/atbm8830.c @@ -335,7 +335,8 @@ static int atbm8830_get_tune_settings(struct dvb_frontend *fe, return 0; } -static int atbm8830_read_status(struct dvb_frontend *fe, fe_status_t *fe_status) +static int atbm8830_read_status(struct dvb_frontend *fe, + enum fe_status *fe_status) { struct atbm_state *priv = fe->demodulator_priv; u8 locked = 0; diff --git a/drivers/media/dvb-frontends/au8522_dig.c b/drivers/media/dvb-frontends/au8522_dig.c index 5d06c99b0e97..b744a3f8d467 100644 --- a/drivers/media/dvb-frontends/au8522_dig.c +++ b/drivers/media/dvb-frontends/au8522_dig.c @@ -552,7 +552,7 @@ static struct { }; static int au8522_enable_modulation(struct dvb_frontend *fe, - fe_modulation_t m) + enum fe_modulation m) { struct au8522_state *state = fe->demodulator_priv; int i; @@ -644,7 +644,7 @@ static int au8522_set_frontend(struct dvb_frontend *fe) return 0; } -static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int au8522_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct au8522_state *state = fe->demodulator_priv; u8 reg; diff --git a/drivers/media/dvb-frontends/au8522_priv.h b/drivers/media/dvb-frontends/au8522_priv.h index b8aca1c84786..951b3847e6f6 100644 --- a/drivers/media/dvb-frontends/au8522_priv.h +++ b/drivers/media/dvb-frontends/au8522_priv.h @@ -55,7 +55,7 @@ struct au8522_state { struct dvb_frontend frontend; u32 current_frequency; - fe_modulation_t current_modulation; + enum fe_modulation current_modulation; u32 fe_status; unsigned int led_state; diff --git a/drivers/media/dvb-frontends/bcm3510.c b/drivers/media/dvb-frontends/bcm3510.c index 23bfd00d42db..d30275f27644 100644 --- a/drivers/media/dvb-frontends/bcm3510.c +++ b/drivers/media/dvb-frontends/bcm3510.c @@ -289,7 +289,7 @@ static int bcm3510_refresh_state(struct bcm3510_state *st) return 0; } -static int bcm3510_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int bcm3510_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct bcm3510_state* st = fe->demodulator_priv; bcm3510_refresh_state(st); diff --git a/drivers/media/dvb-frontends/cx22700.c b/drivers/media/dvb-frontends/cx22700.c index 86563260d0f2..fd033cca6e11 100644 --- a/drivers/media/dvb-frontends/cx22700.c +++ b/drivers/media/dvb-frontends/cx22700.c @@ -191,9 +191,10 @@ static int cx22700_set_tps(struct cx22700_state *state, static int cx22700_get_tps(struct cx22700_state *state, struct dtv_frontend_properties *p) { - static const fe_modulation_t qam_tab [3] = { QPSK, QAM_16, QAM_64 }; - static const fe_code_rate_t fec_tab [5] = { FEC_1_2, FEC_2_3, FEC_3_4, - FEC_5_6, FEC_7_8 }; + static const enum fe_modulation qam_tab[3] = { QPSK, QAM_16, QAM_64 }; + static const enum fe_code_rate fec_tab[5] = { + FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8 + }; u8 val; dprintk ("%s\n", __func__); @@ -253,7 +254,7 @@ static int cx22700_init (struct dvb_frontend* fe) return 0; } -static int cx22700_read_status(struct dvb_frontend* fe, fe_status_t* status) +static int cx22700_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct cx22700_state* state = fe->demodulator_priv; diff --git a/drivers/media/dvb-frontends/cx22702.c b/drivers/media/dvb-frontends/cx22702.c index edc8eafc5c09..d2d06dcd7683 100644 --- a/drivers/media/dvb-frontends/cx22702.c +++ b/drivers/media/dvb-frontends/cx22702.c @@ -452,7 +452,7 @@ static int cx22702_init(struct dvb_frontend *fe) return 0; } -static int cx22702_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int cx22702_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct cx22702_state *state = fe->demodulator_priv; u8 reg0A; diff --git a/drivers/media/dvb-frontends/cx24110.c b/drivers/media/dvb-frontends/cx24110.c index 7b510f2ae20f..cb36475e322b 100644 --- a/drivers/media/dvb-frontends/cx24110.c +++ b/drivers/media/dvb-frontends/cx24110.c @@ -143,7 +143,8 @@ static int cx24110_readreg (struct cx24110_state* state, u8 reg) return b1[0]; } -static int cx24110_set_inversion (struct cx24110_state* state, fe_spectral_inversion_t inversion) +static int cx24110_set_inversion(struct cx24110_state *state, + enum fe_spectral_inversion inversion) { /* fixme (low): error handling */ @@ -177,7 +178,7 @@ static int cx24110_set_inversion (struct cx24110_state* state, fe_spectral_inver return 0; } -static int cx24110_set_fec(struct cx24110_state* state, fe_code_rate_t fec) +static int cx24110_set_fec(struct cx24110_state *state, enum fe_code_rate fec) { static const int rate[FEC_AUTO] = {-1, 1, 2, 3, 5, 7, -1}; static const int g1[FEC_AUTO] = {-1, 0x01, 0x02, 0x05, 0x15, 0x45, -1}; @@ -220,7 +221,7 @@ static int cx24110_set_fec(struct cx24110_state* state, fe_code_rate_t fec) return 0; } -static fe_code_rate_t cx24110_get_fec (struct cx24110_state* state) +static enum fe_code_rate cx24110_get_fec(struct cx24110_state *state) { int i; @@ -365,7 +366,8 @@ static int cx24110_initfe(struct dvb_frontend* fe) return 0; } -static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) +static int cx24110_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { struct cx24110_state *state = fe->demodulator_priv; @@ -379,7 +381,8 @@ static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag } } -static int cx24110_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) +static int cx24110_diseqc_send_burst(struct dvb_frontend *fe, + enum fe_sec_mini_cmd burst) { int rv, bit; struct cx24110_state *state = fe->demodulator_priv; @@ -434,7 +437,8 @@ static int cx24110_send_diseqc_msg(struct dvb_frontend* fe, return 0; } -static int cx24110_read_status(struct dvb_frontend* fe, fe_status_t* status) +static int cx24110_read_status(struct dvb_frontend *fe, + enum fe_status *status) { struct cx24110_state *state = fe->demodulator_priv; @@ -574,7 +578,8 @@ static int cx24110_get_frontend(struct dvb_frontend *fe) return 0; } -static int cx24110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) +static int cx24110_set_tone(struct dvb_frontend *fe, + enum fe_sec_tone_mode tone) { struct cx24110_state *state = fe->demodulator_priv; diff --git a/drivers/media/dvb-frontends/cx24116.c b/drivers/media/dvb-frontends/cx24116.c index 7bc68b355c0b..8814f36d53fb 100644 --- a/drivers/media/dvb-frontends/cx24116.c +++ b/drivers/media/dvb-frontends/cx24116.c @@ -160,13 +160,13 @@ enum cmds { struct cx24116_tuning { u32 frequency; u32 symbol_rate; - fe_spectral_inversion_t inversion; - fe_code_rate_t fec; + enum fe_spectral_inversion inversion; + enum fe_code_rate fec; - fe_delivery_system_t delsys; - fe_modulation_t modulation; - fe_pilot_t pilot; - fe_rolloff_t rolloff; + enum fe_delivery_system delsys; + enum fe_modulation modulation; + enum fe_pilot pilot; + enum fe_rolloff rolloff; /* Demod values */ u8 fec_val; @@ -285,7 +285,7 @@ static int cx24116_readreg(struct cx24116_state *state, u8 reg) } static int cx24116_set_inversion(struct cx24116_state *state, - fe_spectral_inversion_t inversion) + enum fe_spectral_inversion inversion) { dprintk("%s(%d)\n", __func__, inversion); @@ -373,9 +373,9 @@ static int cx24116_set_inversion(struct cx24116_state *state, * a scheme are support. Especially, no auto detect when in S2 mode. */ static struct cx24116_modfec { - fe_delivery_system_t delivery_system; - fe_modulation_t modulation; - fe_code_rate_t fec; + enum fe_delivery_system delivery_system; + enum fe_modulation modulation; + enum fe_code_rate fec; u8 mask; /* In DVBS mode this is used to autodetect */ u8 val; /* Passed to the firmware to indicate mode selection */ } CX24116_MODFEC_MODES[] = { @@ -415,7 +415,7 @@ static struct cx24116_modfec { }; static int cx24116_lookup_fecmod(struct cx24116_state *state, - fe_delivery_system_t d, fe_modulation_t m, fe_code_rate_t f) + enum fe_delivery_system d, enum fe_modulation m, enum fe_code_rate f) { int i, ret = -EOPNOTSUPP; @@ -434,7 +434,9 @@ static int cx24116_lookup_fecmod(struct cx24116_state *state, } static int cx24116_set_fec(struct cx24116_state *state, - fe_delivery_system_t delsys, fe_modulation_t mod, fe_code_rate_t fec) + enum fe_delivery_system delsys, + enum fe_modulation mod, + enum fe_code_rate fec) { int ret = 0; @@ -683,7 +685,7 @@ static int cx24116_load_firmware(struct dvb_frontend *fe, return 0; } -static int cx24116_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int cx24116_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct cx24116_state *state = fe->demodulator_priv; @@ -844,7 +846,7 @@ static int cx24116_wait_for_lnb(struct dvb_frontend *fe) } static int cx24116_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) + enum fe_sec_voltage voltage) { struct cx24116_cmd cmd; int ret; @@ -872,7 +874,7 @@ static int cx24116_set_voltage(struct dvb_frontend *fe, } static int cx24116_set_tone(struct dvb_frontend *fe, - fe_sec_tone_mode_t tone) + enum fe_sec_tone_mode tone) { struct cx24116_cmd cmd; int ret; @@ -1055,7 +1057,7 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend *fe, /* Send DiSEqC burst */ static int cx24116_diseqc_send_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t burst) + enum fe_sec_mini_cmd burst) { struct cx24116_state *state = fe->demodulator_priv; int ret; @@ -1220,7 +1222,7 @@ static int cx24116_set_frontend(struct dvb_frontend *fe) struct cx24116_state *state = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct cx24116_cmd cmd; - fe_status_t tunerstat; + enum fe_status tunerstat; int i, status, ret, retune = 1; dprintk("%s()\n", __func__); @@ -1441,7 +1443,7 @@ tuned: /* Set/Reset B/W */ } static int cx24116_tune(struct dvb_frontend *fe, bool re_tune, - unsigned int mode_flags, unsigned int *delay, fe_status_t *status) + unsigned int mode_flags, unsigned int *delay, enum fe_status *status) { /* * It is safe to discard "params" here, as the DVB core will sync diff --git a/drivers/media/dvb-frontends/cx24117.c b/drivers/media/dvb-frontends/cx24117.c index af6363573efd..5f77bc80a896 100644 --- a/drivers/media/dvb-frontends/cx24117.c +++ b/drivers/media/dvb-frontends/cx24117.c @@ -171,13 +171,13 @@ static DEFINE_MUTEX(cx24117_list_mutex); struct cx24117_tuning { u32 frequency; u32 symbol_rate; - fe_spectral_inversion_t inversion; - fe_code_rate_t fec; + enum fe_spectral_inversion inversion; + enum fe_code_rate fec; - fe_delivery_system_t delsys; - fe_modulation_t modulation; - fe_pilot_t pilot; - fe_rolloff_t rolloff; + enum fe_delivery_system delsys; + enum fe_modulation modulation; + enum fe_pilot pilot; + enum fe_rolloff rolloff; /* Demod values */ u8 fec_val; @@ -220,9 +220,9 @@ struct cx24117_state { /* modfec (modulation and FEC) lookup table */ /* Check cx24116.c for a detailed description of each field */ static struct cx24117_modfec { - fe_delivery_system_t delivery_system; - fe_modulation_t modulation; - fe_code_rate_t fec; + enum fe_delivery_system delivery_system; + enum fe_modulation modulation; + enum fe_code_rate fec; u8 mask; /* In DVBS mode this is used to autodetect */ u8 val; /* Passed to the firmware to indicate mode selection */ } cx24117_modfec_modes[] = { @@ -362,7 +362,7 @@ static int cx24117_readregN(struct cx24117_state *state, } static int cx24117_set_inversion(struct cx24117_state *state, - fe_spectral_inversion_t inversion) + enum fe_spectral_inversion inversion) { dev_dbg(&state->priv->i2c->dev, "%s(%d) demod%d\n", __func__, inversion, state->demod); @@ -387,7 +387,7 @@ static int cx24117_set_inversion(struct cx24117_state *state, } static int cx24117_lookup_fecmod(struct cx24117_state *state, - fe_delivery_system_t d, fe_modulation_t m, fe_code_rate_t f) + enum fe_delivery_system d, enum fe_modulation m, enum fe_code_rate f) { int i, ret = -EINVAL; @@ -408,7 +408,9 @@ static int cx24117_lookup_fecmod(struct cx24117_state *state, } static int cx24117_set_fec(struct cx24117_state *state, - fe_delivery_system_t delsys, fe_modulation_t mod, fe_code_rate_t fec) + enum fe_delivery_system delsys, + enum fe_modulation mod, + enum fe_code_rate fec) { int ret; @@ -737,7 +739,7 @@ error: return ret; } -static int cx24117_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int cx24117_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct cx24117_state *state = fe->demodulator_priv; int lock; @@ -843,7 +845,7 @@ static int cx24117_read_snr(struct dvb_frontend *fe, u16 *snr) static int cx24117_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) { struct cx24117_state *state = fe->demodulator_priv; - fe_delivery_system_t delsys = fe->dtv_property_cache.delivery_system; + enum fe_delivery_system delsys = fe->dtv_property_cache.delivery_system; int ret; u8 buf[2]; u8 reg = (state->demod == 0) ? @@ -904,7 +906,7 @@ static int cx24117_wait_for_lnb(struct dvb_frontend *fe) } static int cx24117_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) + enum fe_sec_voltage voltage) { struct cx24117_state *state = fe->demodulator_priv; struct cx24117_cmd cmd; @@ -956,7 +958,7 @@ static int cx24117_set_voltage(struct dvb_frontend *fe, } static int cx24117_set_tone(struct dvb_frontend *fe, - fe_sec_tone_mode_t tone) + enum fe_sec_tone_mode tone) { struct cx24117_state *state = fe->demodulator_priv; struct cx24117_cmd cmd; @@ -1112,7 +1114,7 @@ static int cx24117_send_diseqc_msg(struct dvb_frontend *fe, /* Send DiSEqC burst */ static int cx24117_diseqc_send_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t burst) + enum fe_sec_mini_cmd burst) { struct cx24117_state *state = fe->demodulator_priv; @@ -1306,7 +1308,7 @@ static int cx24117_set_frontend(struct dvb_frontend *fe) struct cx24117_state *state = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct cx24117_cmd cmd; - fe_status_t tunerstat; + enum fe_status tunerstat; int i, status, ret, retune = 1; u8 reg_clkdiv, reg_ratediv; @@ -1537,7 +1539,7 @@ static int cx24117_set_frontend(struct dvb_frontend *fe) } static int cx24117_tune(struct dvb_frontend *fe, bool re_tune, - unsigned int mode_flags, unsigned int *delay, fe_status_t *status) + unsigned int mode_flags, unsigned int *delay, enum fe_status *status) { struct cx24117_state *state = fe->demodulator_priv; diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index a1d1b1c44b40..3b0ef52bb834 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -118,12 +118,12 @@ enum command_message_id { struct cx24120_tuning { u32 frequency; u32 symbol_rate; - fe_spectral_inversion_t inversion; - fe_code_rate_t fec; + enum fe_spectral_inversion inversion; + enum fe_code_rate fec; - fe_delivery_system_t delsys; - fe_modulation_t modulation; - fe_pilot_t pilot; + enum fe_delivery_system delsys; + enum fe_modulation modulation; + enum fe_pilot pilot; /* Demod values */ u8 fec_val; @@ -148,7 +148,7 @@ struct cx24120_state { struct cx24120_tuning dcur; struct cx24120_tuning dnxt; - fe_status_t fe_status; + enum fe_status fe_status; /* dvbv5 stats calculations */ u32 bitrate; @@ -491,7 +491,7 @@ static int cx24120_msg_mpeg_output_config(struct cx24120_state *state, u8 seq) } static int cx24120_diseqc_send_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t burst) + enum fe_sec_mini_cmd burst) { struct cx24120_state *state = fe->demodulator_priv; struct cx24120_cmd cmd; @@ -513,7 +513,7 @@ static int cx24120_diseqc_send_burst(struct dvb_frontend *fe, return cx24120_message_send(state, &cmd); } -static int cx24120_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) +static int cx24120_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone) { struct cx24120_state *state = fe->demodulator_priv; struct cx24120_cmd cmd; @@ -536,7 +536,7 @@ static int cx24120_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) } static int cx24120_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) + enum fe_sec_voltage voltage) { struct cx24120_state *state = fe->demodulator_priv; struct cx24120_cmd cmd; @@ -713,7 +713,7 @@ static void cx24120_get_stats(struct cx24120_state *state) static void cx24120_set_clock_ratios(struct dvb_frontend *fe); /* Read current tuning status */ -static int cx24120_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int cx24120_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct cx24120_state *state = fe->demodulator_priv; int lock; @@ -765,9 +765,9 @@ static int cx24120_read_status(struct dvb_frontend *fe, fe_status_t *status) * once tuned in. */ struct cx24120_modfec { - fe_delivery_system_t delsys; - fe_modulation_t mod; - fe_code_rate_t fec; + enum fe_delivery_system delsys; + enum fe_modulation mod; + enum fe_code_rate fec; u8 val; }; @@ -871,10 +871,10 @@ static void cx24120_calculate_ber_window(struct cx24120_state *state, u32 rate) * can't determine the pattern */ struct cx24120_clock_ratios_table { - fe_delivery_system_t delsys; - fe_pilot_t pilot; - fe_modulation_t mod; - fe_code_rate_t fec; + enum fe_delivery_system delsys; + enum fe_pilot pilot; + enum fe_modulation mod; + enum fe_code_rate fec; u32 m_rat; u32 n_rat; u32 rate; @@ -988,7 +988,7 @@ static void cx24120_set_clock_ratios(struct dvb_frontend *fe) /* Set inversion value */ static int cx24120_set_inversion(struct cx24120_state *state, - fe_spectral_inversion_t inversion) + enum fe_spectral_inversion inversion) { dev_dbg(&state->i2c->dev, "(%d)\n", inversion); @@ -1013,9 +1013,9 @@ static int cx24120_set_inversion(struct cx24120_state *state, /* FEC lookup table for tuning */ struct cx24120_modfec_table { - fe_delivery_system_t delsys; - fe_modulation_t mod; - fe_code_rate_t fec; + enum fe_delivery_system delsys; + enum fe_modulation mod; + enum fe_code_rate fec; u8 val; }; @@ -1046,8 +1046,8 @@ static const struct cx24120_modfec_table modfec_table[] = { }; /* Set fec_val & fec_mask values from delsys, modulation & fec */ -static int cx24120_set_fec(struct cx24120_state *state, fe_modulation_t mod, - fe_code_rate_t fec) +static int cx24120_set_fec(struct cx24120_state *state, enum fe_modulation mod, + enum fe_code_rate fec) { int idx; @@ -1084,7 +1084,7 @@ static int cx24120_set_fec(struct cx24120_state *state, fe_modulation_t mod, } /* Set pilot */ -static int cx24120_set_pilot(struct cx24120_state *state, fe_pilot_t pilot) +static int cx24120_set_pilot(struct cx24120_state *state, enum fe_pilot pilot) { dev_dbg(&state->i2c->dev, "(%d)\n", pilot); @@ -1474,7 +1474,7 @@ static int cx24120_init(struct dvb_frontend *fe) static int cx24120_tune(struct dvb_frontend *fe, bool re_tune, unsigned int mode_flags, unsigned int *delay, - fe_status_t *status) + enum fe_status *status) { struct cx24120_state *state = fe->demodulator_priv; int ret; diff --git a/drivers/media/dvb-frontends/cx24123.c b/drivers/media/dvb-frontends/cx24123.c index 7975c6608e20..e18cf9e1185e 100644 --- a/drivers/media/dvb-frontends/cx24123.c +++ b/drivers/media/dvb-frontends/cx24123.c @@ -290,7 +290,7 @@ static int cx24123_i2c_readreg(struct cx24123_state *state, u8 i2c_addr, u8 reg) cx24123_i2c_writereg(state, state->config->demod_address, reg, val) static int cx24123_set_inversion(struct cx24123_state *state, - fe_spectral_inversion_t inversion) + enum fe_spectral_inversion inversion) { u8 nom_reg = cx24123_readreg(state, 0x0e); u8 auto_reg = cx24123_readreg(state, 0x10); @@ -318,7 +318,7 @@ static int cx24123_set_inversion(struct cx24123_state *state, } static int cx24123_get_inversion(struct cx24123_state *state, - fe_spectral_inversion_t *inversion) + enum fe_spectral_inversion *inversion) { u8 val; @@ -335,7 +335,7 @@ static int cx24123_get_inversion(struct cx24123_state *state, return 0; } -static int cx24123_set_fec(struct cx24123_state *state, fe_code_rate_t fec) +static int cx24123_set_fec(struct cx24123_state *state, enum fe_code_rate fec) { u8 nom_reg = cx24123_readreg(state, 0x0e) & ~0x07; @@ -397,7 +397,7 @@ static int cx24123_set_fec(struct cx24123_state *state, fe_code_rate_t fec) return 0; } -static int cx24123_get_fec(struct cx24123_state *state, fe_code_rate_t *fec) +static int cx24123_get_fec(struct cx24123_state *state, enum fe_code_rate *fec) { int ret; @@ -720,7 +720,7 @@ static int cx24123_initfe(struct dvb_frontend *fe) } static int cx24123_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) + enum fe_sec_voltage voltage) { struct cx24123_state *state = fe->demodulator_priv; u8 val; @@ -795,7 +795,7 @@ static int cx24123_send_diseqc_msg(struct dvb_frontend *fe, } static int cx24123_diseqc_send_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t burst) + enum fe_sec_mini_cmd burst) { struct cx24123_state *state = fe->demodulator_priv; int val, tone; @@ -831,7 +831,7 @@ static int cx24123_diseqc_send_burst(struct dvb_frontend *fe, return 0; } -static int cx24123_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int cx24123_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct cx24123_state *state = fe->demodulator_priv; int sync = cx24123_readreg(state, 0x14); @@ -966,7 +966,7 @@ static int cx24123_get_frontend(struct dvb_frontend *fe) return 0; } -static int cx24123_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) +static int cx24123_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone) { struct cx24123_state *state = fe->demodulator_priv; u8 val; @@ -995,7 +995,7 @@ static int cx24123_tune(struct dvb_frontend *fe, bool re_tune, unsigned int mode_flags, unsigned int *delay, - fe_status_t *status) + enum fe_status *status) { int retval = 0; diff --git a/drivers/media/dvb-frontends/cxd2820r_c.c b/drivers/media/dvb-frontends/cxd2820r_c.c index 72b0e2db3aab..42fad6aa3958 100644 --- a/drivers/media/dvb-frontends/cxd2820r_c.c +++ b/drivers/media/dvb-frontends/cxd2820r_c.c @@ -259,7 +259,7 @@ int cxd2820r_read_ucblocks_c(struct dvb_frontend *fe, u32 *ucblocks) return 0; } -int cxd2820r_read_status_c(struct dvb_frontend *fe, fe_status_t *status) +int cxd2820r_read_status_c(struct dvb_frontend *fe, enum fe_status *status) { struct cxd2820r_priv *priv = fe->demodulator_priv; int ret; diff --git a/drivers/media/dvb-frontends/cxd2820r_core.c b/drivers/media/dvb-frontends/cxd2820r_core.c index 490e090048ef..def6d21d1445 100644 --- a/drivers/media/dvb-frontends/cxd2820r_core.c +++ b/drivers/media/dvb-frontends/cxd2820r_core.c @@ -287,7 +287,8 @@ static int cxd2820r_set_frontend(struct dvb_frontend *fe) err: return ret; } -static int cxd2820r_read_status(struct dvb_frontend *fe, fe_status_t *status) + +static int cxd2820r_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct cxd2820r_priv *priv = fe->demodulator_priv; int ret; @@ -501,7 +502,7 @@ static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe) struct cxd2820r_priv *priv = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, i; - fe_status_t status = 0; + enum fe_status status = 0; dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__, fe->dtv_property_cache.delivery_system); diff --git a/drivers/media/dvb-frontends/cxd2820r_priv.h b/drivers/media/dvb-frontends/cxd2820r_priv.h index 4b428959b16e..a0d53f01a8bf 100644 --- a/drivers/media/dvb-frontends/cxd2820r_priv.h +++ b/drivers/media/dvb-frontends/cxd2820r_priv.h @@ -48,7 +48,7 @@ struct cxd2820r_priv { struct gpio_chip gpio_chip; #endif - fe_delivery_system_t delivery_system; + enum fe_delivery_system delivery_system; bool last_tune_failed; /* for switch between T and T2 tune */ }; @@ -80,7 +80,7 @@ int cxd2820r_get_frontend_c(struct dvb_frontend *fe); int cxd2820r_set_frontend_c(struct dvb_frontend *fe); -int cxd2820r_read_status_c(struct dvb_frontend *fe, fe_status_t *status); +int cxd2820r_read_status_c(struct dvb_frontend *fe, enum fe_status *status); int cxd2820r_read_ber_c(struct dvb_frontend *fe, u32 *ber); @@ -103,7 +103,7 @@ int cxd2820r_get_frontend_t(struct dvb_frontend *fe); int cxd2820r_set_frontend_t(struct dvb_frontend *fe); -int cxd2820r_read_status_t(struct dvb_frontend *fe, fe_status_t *status); +int cxd2820r_read_status_t(struct dvb_frontend *fe, enum fe_status *status); int cxd2820r_read_ber_t(struct dvb_frontend *fe, u32 *ber); @@ -126,7 +126,7 @@ int cxd2820r_get_frontend_t2(struct dvb_frontend *fe); int cxd2820r_set_frontend_t2(struct dvb_frontend *fe); -int cxd2820r_read_status_t2(struct dvb_frontend *fe, fe_status_t *status); +int cxd2820r_read_status_t2(struct dvb_frontend *fe, enum fe_status *status); int cxd2820r_read_ber_t2(struct dvb_frontend *fe, u32 *ber); diff --git a/drivers/media/dvb-frontends/cxd2820r_t.c b/drivers/media/dvb-frontends/cxd2820r_t.c index 008cb2ac8480..21abf1b4ed4d 100644 --- a/drivers/media/dvb-frontends/cxd2820r_t.c +++ b/drivers/media/dvb-frontends/cxd2820r_t.c @@ -349,7 +349,7 @@ int cxd2820r_read_ucblocks_t(struct dvb_frontend *fe, u32 *ucblocks) return 0; } -int cxd2820r_read_status_t(struct dvb_frontend *fe, fe_status_t *status) +int cxd2820r_read_status_t(struct dvb_frontend *fe, enum fe_status *status) { struct cxd2820r_priv *priv = fe->demodulator_priv; int ret; diff --git a/drivers/media/dvb-frontends/cxd2820r_t2.c b/drivers/media/dvb-frontends/cxd2820r_t2.c index 35fe364c7182..4e028b41c0d5 100644 --- a/drivers/media/dvb-frontends/cxd2820r_t2.c +++ b/drivers/media/dvb-frontends/cxd2820r_t2.c @@ -284,7 +284,7 @@ error: return ret; } -int cxd2820r_read_status_t2(struct dvb_frontend *fe, fe_status_t *status) +int cxd2820r_read_status_t2(struct dvb_frontend *fe, enum fe_status *status) { struct cxd2820r_priv *priv = fe->demodulator_priv; int ret; diff --git a/drivers/media/dvb-frontends/dib3000mb.c b/drivers/media/dvb-frontends/dib3000mb.c index af91e0c92339..7a61172d0d45 100644 --- a/drivers/media/dvb-frontends/dib3000mb.c +++ b/drivers/media/dvb-frontends/dib3000mb.c @@ -118,7 +118,7 @@ static int dib3000mb_set_frontend(struct dvb_frontend *fe, int tuner) { struct dib3000_state* state = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - fe_code_rate_t fe_cr = FEC_NONE; + enum fe_code_rate fe_cr = FEC_NONE; int search_state, seq; if (tuner && fe->ops.tuner_ops.set_params) { @@ -454,7 +454,7 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe) { struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct dib3000_state* state = fe->demodulator_priv; - fe_code_rate_t *cr; + enum fe_code_rate *cr; u16 tps_val; int inv_test1,inv_test2; u32 dds_val, threshold = 0x800000; @@ -611,7 +611,8 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe) return 0; } -static int dib3000mb_read_status(struct dvb_frontend* fe, fe_status_t *stat) +static int dib3000mb_read_status(struct dvb_frontend *fe, + enum fe_status *stat) { struct dib3000_state* state = fe->demodulator_priv; diff --git a/drivers/media/dvb-frontends/dib3000mc.c b/drivers/media/dvb-frontends/dib3000mc.c index a9b8081a0fbc..583d6b7fabed 100644 --- a/drivers/media/dvb-frontends/dib3000mc.c +++ b/drivers/media/dvb-frontends/dib3000mc.c @@ -736,7 +736,7 @@ static int dib3000mc_set_frontend(struct dvb_frontend *fe) return ret; } -static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat) +static int dib3000mc_read_status(struct dvb_frontend *fe, enum fe_status *stat) { struct dib3000mc_state *state = fe->demodulator_priv; u16 lock = dib3000mc_read_word(state, 509); diff --git a/drivers/media/dvb-frontends/dib7000m.c b/drivers/media/dvb-frontends/dib7000m.c index dcb9a15ef0c2..35eb71fe3c2b 100644 --- a/drivers/media/dvb-frontends/dib7000m.c +++ b/drivers/media/dvb-frontends/dib7000m.c @@ -1256,7 +1256,7 @@ static int dib7000m_set_frontend(struct dvb_frontend *fe) return ret; } -static int dib7000m_read_status(struct dvb_frontend *fe, fe_status_t *stat) +static int dib7000m_read_status(struct dvb_frontend *fe, enum fe_status *stat) { struct dib7000m_state *state = fe->demodulator_priv; u16 lock = dib7000m_read_word(state, 535); diff --git a/drivers/media/dvb-frontends/dib7000p.c b/drivers/media/dvb-frontends/dib7000p.c index c505d696f92d..33be5d6b9e10 100644 --- a/drivers/media/dvb-frontends/dib7000p.c +++ b/drivers/media/dvb-frontends/dib7000p.c @@ -1558,9 +1558,9 @@ static int dib7000p_set_frontend(struct dvb_frontend *fe) return ret; } -static int dib7000p_get_stats(struct dvb_frontend *fe, fe_status_t stat); +static int dib7000p_get_stats(struct dvb_frontend *fe, enum fe_status stat); -static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t * stat) +static int dib7000p_read_status(struct dvb_frontend *fe, enum fe_status *stat) { struct dib7000p_state *state = fe->demodulator_priv; u16 lock = dib7000p_read_word(state, 509); @@ -1877,7 +1877,7 @@ static u32 dib7000p_get_time_us(struct dvb_frontend *demod) return time_us; } -static int dib7000p_get_stats(struct dvb_frontend *demod, fe_status_t stat) +static int dib7000p_get_stats(struct dvb_frontend *demod, enum fe_status stat) { struct dib7000p_state *state = demod->demodulator_priv; struct dtv_frontend_properties *c = &demod->dtv_property_cache; diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c index 8c6663b6399d..94c26270fff0 100644 --- a/drivers/media/dvb-frontends/dib8000.c +++ b/drivers/media/dvb-frontends/dib8000.c @@ -3380,13 +3380,13 @@ static int dib8000_sleep(struct dvb_frontend *fe) return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF); } -static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat); +static int dib8000_read_status(struct dvb_frontend *fe, enum fe_status *stat); static int dib8000_get_frontend(struct dvb_frontend *fe) { struct dib8000_state *state = fe->demodulator_priv; u16 i, val = 0; - fe_status_t stat = 0; + enum fe_status stat = 0; u8 index_frontend, sub_index_frontend; fe->dtv_property_cache.bandwidth_hz = 6000000; @@ -3733,9 +3733,9 @@ static int dib8000_set_frontend(struct dvb_frontend *fe) return 0; } -static int dib8000_get_stats(struct dvb_frontend *fe, fe_status_t stat); +static int dib8000_get_stats(struct dvb_frontend *fe, enum fe_status stat); -static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat) +static int dib8000_read_status(struct dvb_frontend *fe, enum fe_status *stat) { struct dib8000_state *state = fe->demodulator_priv; u16 lock_slave = 0, lock; @@ -4089,7 +4089,7 @@ static u32 dib8000_get_time_us(struct dvb_frontend *fe, int layer) return time_us; } -static int dib8000_get_stats(struct dvb_frontend *fe, fe_status_t stat) +static int dib8000_get_stats(struct dvb_frontend *fe, enum fe_status stat) { struct dib8000_state *state = fe->demodulator_priv; struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache; diff --git a/drivers/media/dvb-frontends/dib9000.c b/drivers/media/dvb-frontends/dib9000.c index f75dec443783..8f92aca0b073 100644 --- a/drivers/media/dvb-frontends/dib9000.c +++ b/drivers/media/dvb-frontends/dib9000.c @@ -1893,7 +1893,7 @@ static int dib9000_get_frontend(struct dvb_frontend *fe) { struct dib9000_state *state = fe->demodulator_priv; u8 index_frontend, sub_index_frontend; - fe_status_t stat; + enum fe_status stat; int ret = 0; if (state->get_frontend_internal == 0) { @@ -2161,7 +2161,7 @@ static u16 dib9000_read_lock(struct dvb_frontend *fe) return dib9000_read_word(state, 535); } -static int dib9000_read_status(struct dvb_frontend *fe, fe_status_t * stat) +static int dib9000_read_status(struct dvb_frontend *fe, enum fe_status *stat) { struct dib9000_state *state = fe->demodulator_priv; u8 index_frontend; diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c index 52245354bf04..b28b5787b39a 100644 --- a/drivers/media/dvb-frontends/drx39xyj/drxj.c +++ b/drivers/media/dvb-frontends/drx39xyj/drxj.c @@ -11946,7 +11946,7 @@ static int drx39xxj_set_powerstate(struct dvb_frontend *fe, int enable) return 0; } -static int drx39xxj_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int drx39xxj_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct drx39xxj_state *state = fe->demodulator_priv; struct drx_demod_instance *demod = state->demod; diff --git a/drivers/media/dvb-frontends/drxd_hard.c b/drivers/media/dvb-frontends/drxd_hard.c index 687e893d29fe..34b9441840da 100644 --- a/drivers/media/dvb-frontends/drxd_hard.c +++ b/drivers/media/dvb-frontends/drxd_hard.c @@ -2805,7 +2805,7 @@ static int drxd_read_signal_strength(struct dvb_frontend *fe, u16 * strength) return 0; } -static int drxd_read_status(struct dvb_frontend *fe, fe_status_t * status) +static int drxd_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct drxd_state *state = fe->demodulator_priv; u32 lock; diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c index b1fc4bd44a2b..b975da099929 100644 --- a/drivers/media/dvb-frontends/drxk_hard.c +++ b/drivers/media/dvb-frontends/drxk_hard.c @@ -6640,7 +6640,7 @@ error: } -static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int drxk_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct drxk_state *state = fe->demodulator_priv; int rc; diff --git a/drivers/media/dvb-frontends/drxk_hard.h b/drivers/media/dvb-frontends/drxk_hard.h index bae9c71dc3e9..9ed88e014942 100644 --- a/drivers/media/dvb-frontends/drxk_hard.h +++ b/drivers/media/dvb-frontends/drxk_hard.h @@ -350,7 +350,7 @@ struct drxk_state { bool antenna_dvbt; u16 antenna_gpio; - fe_status_t fe_status; + enum fe_status fe_status; /* Firmware */ const char *microcode_name; diff --git a/drivers/media/dvb-frontends/ds3000.c b/drivers/media/dvb-frontends/ds3000.c index 9d0d0347758f..e8fc0329ea64 100644 --- a/drivers/media/dvb-frontends/ds3000.c +++ b/drivers/media/dvb-frontends/ds3000.c @@ -404,7 +404,8 @@ static int ds3000_load_firmware(struct dvb_frontend *fe, return ret; } -static int ds3000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +static int ds3000_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { struct ds3000_state *state = fe->demodulator_priv; u8 data; @@ -431,7 +432,7 @@ static int ds3000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) return 0; } -static int ds3000_read_status(struct dvb_frontend *fe, fe_status_t* status) +static int ds3000_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct ds3000_state *state = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; @@ -666,7 +667,7 @@ static int ds3000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) return 0; } -static int ds3000_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) +static int ds3000_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone) { struct ds3000_state *state = fe->demodulator_priv; u8 data; @@ -766,7 +767,7 @@ static int ds3000_send_diseqc_msg(struct dvb_frontend *fe, /* Send DiSEqC burst */ static int ds3000_diseqc_send_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t burst) + enum fe_sec_mini_cmd burst) { struct ds3000_state *state = fe->demodulator_priv; int i; @@ -905,7 +906,7 @@ static int ds3000_set_frontend(struct dvb_frontend *fe) struct dtv_frontend_properties *c = &fe->dtv_property_cache; int i; - fe_status_t status; + enum fe_status status; s32 offset_khz; u32 frequency; u16 value; @@ -1045,7 +1046,7 @@ static int ds3000_tune(struct dvb_frontend *fe, bool re_tune, unsigned int mode_flags, unsigned int *delay, - fe_status_t *status) + enum fe_status *status) { if (re_tune) { int ret = ds3000_set_frontend(fe); diff --git a/drivers/media/dvb-frontends/dvb_dummy_fe.c b/drivers/media/dvb-frontends/dvb_dummy_fe.c index d5acc304786b..14e996d45fac 100644 --- a/drivers/media/dvb-frontends/dvb_dummy_fe.c +++ b/drivers/media/dvb-frontends/dvb_dummy_fe.c @@ -33,7 +33,8 @@ struct dvb_dummy_fe_state { }; -static int dvb_dummy_fe_read_status(struct dvb_frontend* fe, fe_status_t* status) +static int dvb_dummy_fe_read_status(struct dvb_frontend *fe, + enum fe_status *status) { *status = FE_HAS_SIGNAL | FE_HAS_CARRIER @@ -97,12 +98,14 @@ static int dvb_dummy_fe_init(struct dvb_frontend* fe) return 0; } -static int dvb_dummy_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) +static int dvb_dummy_fe_set_tone(struct dvb_frontend *fe, + enum fe_sec_tone_mode tone) { return 0; } -static int dvb_dummy_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) +static int dvb_dummy_fe_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { return 0; } diff --git a/drivers/media/dvb-frontends/ec100.c b/drivers/media/dvb-frontends/ec100.c index 9d424809d06b..c9012e677cd1 100644 --- a/drivers/media/dvb-frontends/ec100.c +++ b/drivers/media/dvb-frontends/ec100.c @@ -174,7 +174,7 @@ static int ec100_get_tune_settings(struct dvb_frontend *fe, return 0; } -static int ec100_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int ec100_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct ec100_state *state = fe->demodulator_priv; int ret; diff --git a/drivers/media/dvb-frontends/hd29l2.c b/drivers/media/dvb-frontends/hd29l2.c index 67c8e6df42e8..40e359f2d17d 100644 --- a/drivers/media/dvb-frontends/hd29l2.c +++ b/drivers/media/dvb-frontends/hd29l2.c @@ -211,7 +211,7 @@ err: return ret; } -static int hd29l2_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int hd29l2_read_status(struct dvb_frontend *fe, enum fe_status *status) { int ret; struct hd29l2_priv *priv = fe->demodulator_priv; diff --git a/drivers/media/dvb-frontends/hd29l2_priv.h b/drivers/media/dvb-frontends/hd29l2_priv.h index 4d571a2282d4..6dc225c4bc91 100644 --- a/drivers/media/dvb-frontends/hd29l2_priv.h +++ b/drivers/media/dvb-frontends/hd29l2_priv.h @@ -67,7 +67,7 @@ struct hd29l2_priv { struct hd29l2_config cfg; u8 tuner_i2c_addr_programmed:1; - fe_status_t fe_status; + enum fe_status fe_status; }; static const struct reg_mod_vals reg_mod_vals_tab[] = { diff --git a/drivers/media/dvb-frontends/isl6405.c b/drivers/media/dvb-frontends/isl6405.c index 0c642a5bf823..b46450a10b80 100644 --- a/drivers/media/dvb-frontends/isl6405.c +++ b/drivers/media/dvb-frontends/isl6405.c @@ -43,7 +43,8 @@ struct isl6405 { u8 i2c_addr; }; -static int isl6405_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +static int isl6405_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { struct isl6405 *isl6405 = (struct isl6405 *) fe->sec_priv; struct i2c_msg msg = { .addr = isl6405->i2c_addr, .flags = 0, diff --git a/drivers/media/dvb-frontends/isl6421.c b/drivers/media/dvb-frontends/isl6421.c index c77002fcc8e2..3a4d4606a426 100644 --- a/drivers/media/dvb-frontends/isl6421.c +++ b/drivers/media/dvb-frontends/isl6421.c @@ -43,7 +43,8 @@ struct isl6421 { u8 i2c_addr; }; -static int isl6421_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +static int isl6421_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv; struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0, @@ -89,7 +90,8 @@ static int isl6421_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO; } -static int isl6421_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) +static int isl6421_set_tone(struct dvb_frontend *fe, + enum fe_sec_tone_mode tone) { struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv; struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0, diff --git a/drivers/media/dvb-frontends/l64781.c b/drivers/media/dvb-frontends/l64781.c index ddf866c46f8b..0977871232a2 100644 --- a/drivers/media/dvb-frontends/l64781.c +++ b/drivers/media/dvb-frontends/l64781.c @@ -359,7 +359,7 @@ static int get_frontend(struct dvb_frontend *fe) return 0; } -static int l64781_read_status(struct dvb_frontend* fe, fe_status_t* status) +static int l64781_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct l64781_state* state = fe->demodulator_priv; int sync = l64781_readreg (state, 0x32); diff --git a/drivers/media/dvb-frontends/lg2160.c b/drivers/media/dvb-frontends/lg2160.c index 99efeba3c31a..7880f71ccd8a 100644 --- a/drivers/media/dvb-frontends/lg2160.c +++ b/drivers/media/dvb-frontends/lg2160.c @@ -1203,7 +1203,7 @@ static int lg216x_read_lock_status(struct lg216x_state *state, #endif } -static int lg216x_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int lg216x_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct lg216x_state *state = fe->demodulator_priv; int ret, acq_lock, sync_lock; diff --git a/drivers/media/dvb-frontends/lgdt3305.c b/drivers/media/dvb-frontends/lgdt3305.c index d08570af1c10..47121866163d 100644 --- a/drivers/media/dvb-frontends/lgdt3305.c +++ b/drivers/media/dvb-frontends/lgdt3305.c @@ -60,7 +60,7 @@ struct lgdt3305_state { struct dvb_frontend frontend; - fe_modulation_t current_modulation; + enum fe_modulation current_modulation; u32 current_frequency; u32 snr; }; @@ -912,7 +912,7 @@ fail: return ret; } -static int lgdt3305_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int lgdt3305_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct lgdt3305_state *state = fe->demodulator_priv; u8 val; diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c index 0e2e43e9ede5..721fbc07e9ee 100644 --- a/drivers/media/dvb-frontends/lgdt3306a.c +++ b/drivers/media/dvb-frontends/lgdt3306a.c @@ -62,7 +62,7 @@ struct lgdt3306a_state { struct dvb_frontend frontend; - fe_modulation_t current_modulation; + enum fe_modulation current_modulation; u32 current_frequency; u32 snr; }; @@ -1558,7 +1558,8 @@ lgdt3306a_qam_lock_poll(struct lgdt3306a_state *state) return LG3306_UNLOCK; } -static int lgdt3306a_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int lgdt3306a_read_status(struct dvb_frontend *fe, + enum fe_status *status) { struct lgdt3306a_state *state = fe->demodulator_priv; u16 strength = 0; @@ -1705,7 +1706,7 @@ static int lgdt3306a_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) static int lgdt3306a_tune(struct dvb_frontend *fe, bool re_tune, unsigned int mode_flags, unsigned int *delay, - fe_status_t *status) + enum fe_status *status) { int ret = 0; struct lgdt3306a_state *state = fe->demodulator_priv; @@ -1735,7 +1736,7 @@ static int lgdt3306a_get_tune_settings(struct dvb_frontend *fe, static int lgdt3306a_search(struct dvb_frontend *fe) { - fe_status_t status = 0; + enum fe_status status = 0; int i, ret; /* set frontend */ diff --git a/drivers/media/dvb-frontends/lgdt330x.c b/drivers/media/dvb-frontends/lgdt330x.c index 2e1a61893fc1..cf3cc20510da 100644 --- a/drivers/media/dvb-frontends/lgdt330x.c +++ b/drivers/media/dvb-frontends/lgdt330x.c @@ -67,7 +67,7 @@ struct lgdt330x_state struct dvb_frontend frontend; /* Demodulator private data */ - fe_modulation_t current_modulation; + enum fe_modulation current_modulation; u32 snr; /* Result of last SNR calculation */ /* Tuner private data */ @@ -447,7 +447,8 @@ static int lgdt330x_get_frontend(struct dvb_frontend *fe) return 0; } -static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status) +static int lgdt3302_read_status(struct dvb_frontend *fe, + enum fe_status *status) { struct lgdt330x_state* state = fe->demodulator_priv; u8 buf[3]; @@ -505,7 +506,8 @@ static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status) return 0; } -static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status) +static int lgdt3303_read_status(struct dvb_frontend *fe, + enum fe_status *status) { struct lgdt330x_state* state = fe->demodulator_priv; int err; diff --git a/drivers/media/dvb-frontends/lgs8gl5.c b/drivers/media/dvb-frontends/lgs8gl5.c index 416cce3fefc7..7bbb2c18c2dd 100644 --- a/drivers/media/dvb-frontends/lgs8gl5.c +++ b/drivers/media/dvb-frontends/lgs8gl5.c @@ -249,7 +249,7 @@ lgs8gl5_init(struct dvb_frontend *fe) static int -lgs8gl5_read_status(struct dvb_frontend *fe, fe_status_t *status) +lgs8gl5_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct lgs8gl5_state *state = fe->demodulator_priv; u8 level = lgs8gl5_read_reg(state, REG_STRENGTH); diff --git a/drivers/media/dvb-frontends/lgs8gxx.c b/drivers/media/dvb-frontends/lgs8gxx.c index 3c92f36ea5c7..e2c191c8b196 100644 --- a/drivers/media/dvb-frontends/lgs8gxx.c +++ b/drivers/media/dvb-frontends/lgs8gxx.c @@ -732,7 +732,8 @@ int lgs8gxx_get_tune_settings(struct dvb_frontend *fe, return 0; } -static int lgs8gxx_read_status(struct dvb_frontend *fe, fe_status_t *fe_status) +static int lgs8gxx_read_status(struct dvb_frontend *fe, + enum fe_status *fe_status) { struct lgs8gxx_state *priv = fe->demodulator_priv; s8 ret; diff --git a/drivers/media/dvb-frontends/lnbp21.c b/drivers/media/dvb-frontends/lnbp21.c index f3ba7b5faa2e..4aca0fb9a8a7 100644 --- a/drivers/media/dvb-frontends/lnbp21.c +++ b/drivers/media/dvb-frontends/lnbp21.c @@ -45,7 +45,7 @@ struct lnbp21 { }; static int lnbp21_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) + enum fe_sec_voltage voltage) { struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv; struct i2c_msg msg = { .addr = lnbp21->i2c_addr, .flags = 0, @@ -92,7 +92,7 @@ static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) } static int lnbp21_set_tone(struct dvb_frontend *fe, - fe_sec_tone_mode_t tone) + enum fe_sec_tone_mode tone) { struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv; struct i2c_msg msg = { .addr = lnbp21->i2c_addr, .flags = 0, diff --git a/drivers/media/dvb-frontends/lnbp22.c b/drivers/media/dvb-frontends/lnbp22.c index c463da7f6dcc..d7ca0fdd0084 100644 --- a/drivers/media/dvb-frontends/lnbp22.c +++ b/drivers/media/dvb-frontends/lnbp22.c @@ -48,7 +48,8 @@ struct lnbp22 { struct i2c_adapter *i2c; }; -static int lnbp22_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +static int lnbp22_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { struct lnbp22 *lnbp22 = (struct lnbp22 *)fe->sec_priv; struct i2c_msg msg = { diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index 7b21f1ad4542..c24b15238a8e 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -186,7 +186,8 @@ err: return ret; } -static int m88ds3103_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int m88ds3103_read_status(struct dvb_frontend *fe, + enum fe_status *status) { struct m88ds3103_priv *priv = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; @@ -1094,7 +1095,7 @@ static int m88ds3103_read_ber(struct dvb_frontend *fe, u32 *ber) } static int m88ds3103_set_tone(struct dvb_frontend *fe, - fe_sec_tone_mode_t fe_sec_tone_mode) + enum fe_sec_tone_mode fe_sec_tone_mode) { struct m88ds3103_priv *priv = fe->demodulator_priv; int ret; @@ -1141,7 +1142,7 @@ err: } static int m88ds3103_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t fe_sec_voltage) + enum fe_sec_voltage fe_sec_voltage) { struct m88ds3103_priv *priv = fe->demodulator_priv; int ret; @@ -1268,7 +1269,7 @@ err: } static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t fe_sec_mini_cmd) + enum fe_sec_mini_cmd fe_sec_mini_cmd) { struct m88ds3103_priv *priv = fe->demodulator_priv; int ret; diff --git a/drivers/media/dvb-frontends/m88ds3103_priv.h b/drivers/media/dvb-frontends/m88ds3103_priv.h index 6217d928c23e..9d7d33430e40 100644 --- a/drivers/media/dvb-frontends/m88ds3103_priv.h +++ b/drivers/media/dvb-frontends/m88ds3103_priv.h @@ -38,8 +38,8 @@ struct m88ds3103_priv { struct m88ds3103_config config; const struct m88ds3103_config *cfg; struct dvb_frontend fe; - fe_delivery_system_t delivery_system; - fe_status_t fe_status; + enum fe_delivery_system delivery_system; + enum fe_status fe_status; u32 dvbv3_ber; /* for old DVBv3 API read_ber */ bool warm; /* FW running */ struct i2c_adapter *i2c_adapter; diff --git a/drivers/media/dvb-frontends/m88rs2000.c b/drivers/media/dvb-frontends/m88rs2000.c index d63bc9c13dce..9b6f464c48bd 100644 --- a/drivers/media/dvb-frontends/m88rs2000.c +++ b/drivers/media/dvb-frontends/m88rs2000.c @@ -41,7 +41,7 @@ struct m88rs2000_state { u8 no_lock_count; u32 tuner_frequency; u32 symbol_rate; - fe_code_rate_t fec_inner; + enum fe_code_rate fec_inner; u8 tuner_level; int errmode; }; @@ -247,7 +247,7 @@ static int m88rs2000_send_diseqc_msg(struct dvb_frontend *fe, } static int m88rs2000_send_diseqc_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t burst) + enum fe_sec_mini_cmd burst) { struct m88rs2000_state *state = fe->demodulator_priv; u8 reg0, reg1; @@ -264,7 +264,8 @@ static int m88rs2000_send_diseqc_burst(struct dvb_frontend *fe, return 0; } -static int m88rs2000_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) +static int m88rs2000_set_tone(struct dvb_frontend *fe, + enum fe_sec_tone_mode tone) { struct m88rs2000_state *state = fe->demodulator_priv; u8 reg0, reg1; @@ -412,7 +413,8 @@ static int m88rs2000_tab_set(struct m88rs2000_state *state, return 0; } -static int m88rs2000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt) +static int m88rs2000_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage volt) { struct m88rs2000_state *state = fe->demodulator_priv; u8 data; @@ -462,7 +464,8 @@ static int m88rs2000_sleep(struct dvb_frontend *fe) return ret; } -static int m88rs2000_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int m88rs2000_read_status(struct dvb_frontend *fe, + enum fe_status *status) { struct m88rs2000_state *state = fe->demodulator_priv; u8 reg = m88rs2000_readreg(state, 0x8c); @@ -539,7 +542,7 @@ static int m88rs2000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) } static int m88rs2000_set_fec(struct m88rs2000_state *state, - fe_code_rate_t fec) + enum fe_code_rate fec) { u8 fec_set, reg; int ret; @@ -574,7 +577,7 @@ static int m88rs2000_set_fec(struct m88rs2000_state *state, return ret; } -static fe_code_rate_t m88rs2000_get_fec(struct m88rs2000_state *state) +static enum fe_code_rate m88rs2000_get_fec(struct m88rs2000_state *state) { u8 reg; m88rs2000_writereg(state, 0x9a, 0x30); @@ -606,7 +609,7 @@ static int m88rs2000_set_frontend(struct dvb_frontend *fe) { struct m88rs2000_state *state = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - fe_status_t status; + enum fe_status status; int i, ret = 0; u32 tuner_freq; s16 offset = 0; diff --git a/drivers/media/dvb-frontends/mb86a16.c b/drivers/media/dvb-frontends/mb86a16.c index 3ddea4471d2b..79bc671e8769 100644 --- a/drivers/media/dvb-frontends/mb86a16.c +++ b/drivers/media/dvb-frontends/mb86a16.c @@ -593,7 +593,7 @@ err: return -EREMOTEIO; } -static int mb86a16_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int mb86a16_read_status(struct dvb_frontend *fe, enum fe_status *status) { u8 stat, stat2; struct mb86a16_state *state = fe->demodulator_priv; @@ -1562,7 +1562,8 @@ err: return -EREMOTEIO; } -static int mb86a16_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst) +static int mb86a16_send_diseqc_burst(struct dvb_frontend *fe, + enum fe_sec_mini_cmd burst) { struct mb86a16_state *state = fe->demodulator_priv; @@ -1590,7 +1591,7 @@ err: return -EREMOTEIO; } -static int mb86a16_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) +static int mb86a16_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone) { struct mb86a16_state *state = fe->demodulator_priv; diff --git a/drivers/media/dvb-frontends/mb86a16.h b/drivers/media/dvb-frontends/mb86a16.h index e486dc0d8e60..dbd5f43fa128 100644 --- a/drivers/media/dvb-frontends/mb86a16.h +++ b/drivers/media/dvb-frontends/mb86a16.h @@ -28,7 +28,8 @@ struct mb86a16_config { u8 demod_address; - int (*set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage); + int (*set_voltage)(struct dvb_frontend *fe, + enum fe_sec_voltage voltage); }; diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c index 8f54c39ca63f..cfc005ee11d8 100644 --- a/drivers/media/dvb-frontends/mb86a20s.c +++ b/drivers/media/dvb-frontends/mb86a20s.c @@ -294,7 +294,7 @@ static int mb86a20s_i2c_readreg(struct mb86a20s_state *state, * The functions below assume that gateway lock has already obtained */ -static int mb86a20s_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int mb86a20s_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct mb86a20s_state *state = fe->demodulator_priv; int val; @@ -1951,7 +1951,7 @@ static int mb86a20s_set_frontend(struct dvb_frontend *fe) } static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe, - fe_status_t *status) + enum fe_status *status) { struct mb86a20s_state *state = fe->demodulator_priv; int rc, status_nr; @@ -2042,7 +2042,7 @@ static int mb86a20s_tune(struct dvb_frontend *fe, bool re_tune, unsigned int mode_flags, unsigned int *delay, - fe_status_t *status) + enum fe_status *status) { struct mb86a20s_state *state = fe->demodulator_priv; int rc = 0; diff --git a/drivers/media/dvb-frontends/mt312.c b/drivers/media/dvb-frontends/mt312.c index 2163490c1e6b..c36e6764eead 100644 --- a/drivers/media/dvb-frontends/mt312.c +++ b/drivers/media/dvb-frontends/mt312.c @@ -156,7 +156,7 @@ static int mt312_reset(struct mt312_state *state, const u8 full) } static int mt312_get_inversion(struct mt312_state *state, - fe_spectral_inversion_t *i) + enum fe_spectral_inversion *i) { int ret; u8 vit_mode; @@ -225,9 +225,9 @@ static int mt312_get_symbol_rate(struct mt312_state *state, u32 *sr) return 0; } -static int mt312_get_code_rate(struct mt312_state *state, fe_code_rate_t *cr) +static int mt312_get_code_rate(struct mt312_state *state, enum fe_code_rate *cr) { - const fe_code_rate_t fec_tab[8] = + const enum fe_code_rate fec_tab[8] = { FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_6_7, FEC_7_8, FEC_AUTO, FEC_AUTO }; @@ -380,7 +380,8 @@ static int mt312_send_master_cmd(struct dvb_frontend *fe, return 0; } -static int mt312_send_burst(struct dvb_frontend *fe, const fe_sec_mini_cmd_t c) +static int mt312_send_burst(struct dvb_frontend *fe, + const enum fe_sec_mini_cmd c) { struct mt312_state *state = fe->demodulator_priv; const u8 mini_tab[2] = { 0x02, 0x03 }; @@ -403,7 +404,8 @@ static int mt312_send_burst(struct dvb_frontend *fe, const fe_sec_mini_cmd_t c) return 0; } -static int mt312_set_tone(struct dvb_frontend *fe, const fe_sec_tone_mode_t t) +static int mt312_set_tone(struct dvb_frontend *fe, + const enum fe_sec_tone_mode t) { struct mt312_state *state = fe->demodulator_priv; const u8 tone_tab[2] = { 0x01, 0x00 }; @@ -426,7 +428,8 @@ static int mt312_set_tone(struct dvb_frontend *fe, const fe_sec_tone_mode_t t) return 0; } -static int mt312_set_voltage(struct dvb_frontend *fe, const fe_sec_voltage_t v) +static int mt312_set_voltage(struct dvb_frontend *fe, + const enum fe_sec_voltage v) { struct mt312_state *state = fe->demodulator_priv; const u8 volt_tab[3] = { 0x00, 0x40, 0x00 }; @@ -442,7 +445,7 @@ static int mt312_set_voltage(struct dvb_frontend *fe, const fe_sec_voltage_t v) return mt312_writereg(state, DISEQC_MODE, val); } -static int mt312_read_status(struct dvb_frontend *fe, fe_status_t *s) +static int mt312_read_status(struct dvb_frontend *fe, enum fe_status *s) { struct mt312_state *state = fe->demodulator_priv; int ret; diff --git a/drivers/media/dvb-frontends/mt352.c b/drivers/media/dvb-frontends/mt352.c index 2c3b50e828d7..123bb2f8e4b6 100644 --- a/drivers/media/dvb-frontends/mt352.c +++ b/drivers/media/dvb-frontends/mt352.c @@ -417,7 +417,7 @@ static int mt352_get_parameters(struct dvb_frontend* fe) return 0; } -static int mt352_read_status(struct dvb_frontend* fe, fe_status_t* status) +static int mt352_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct mt352_state* state = fe->demodulator_priv; int s0, s1, s3; diff --git a/drivers/media/dvb-frontends/nxt200x.c b/drivers/media/dvb-frontends/nxt200x.c index 8a8e1ecb762d..79c3040912ab 100644 --- a/drivers/media/dvb-frontends/nxt200x.c +++ b/drivers/media/dvb-frontends/nxt200x.c @@ -781,7 +781,7 @@ static int nxt200x_setup_frontend_parameters(struct dvb_frontend *fe) return 0; } -static int nxt200x_read_status(struct dvb_frontend* fe, fe_status_t* status) +static int nxt200x_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct nxt200x_state* state = fe->demodulator_priv; u8 lock; diff --git a/drivers/media/dvb-frontends/nxt6000.c b/drivers/media/dvb-frontends/nxt6000.c index 90ae6c72c0e3..73f9505367ac 100644 --- a/drivers/media/dvb-frontends/nxt6000.c +++ b/drivers/media/dvb-frontends/nxt6000.c @@ -109,7 +109,8 @@ static int nxt6000_set_bandwidth(struct nxt6000_state *state, u32 bandwidth) return nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_2, (nominal_rate >> 8) & 0xFF); } -static int nxt6000_set_guard_interval(struct nxt6000_state* state, fe_guard_interval_t guard_interval) +static int nxt6000_set_guard_interval(struct nxt6000_state *state, + enum fe_guard_interval guard_interval) { switch (guard_interval) { @@ -131,7 +132,8 @@ static int nxt6000_set_guard_interval(struct nxt6000_state* state, fe_guard_inte } } -static int nxt6000_set_inversion(struct nxt6000_state* state, fe_spectral_inversion_t inversion) +static int nxt6000_set_inversion(struct nxt6000_state *state, + enum fe_spectral_inversion inversion) { switch (inversion) { @@ -147,7 +149,9 @@ static int nxt6000_set_inversion(struct nxt6000_state* state, fe_spectral_invers } } -static int nxt6000_set_transmission_mode(struct nxt6000_state* state, fe_transmit_mode_t transmission_mode) +static int +nxt6000_set_transmission_mode(struct nxt6000_state *state, + enum fe_transmit_mode transmission_mode) { int result; @@ -416,7 +420,7 @@ static void nxt6000_dump_status(struct nxt6000_state *state) printk("\n"); } -static int nxt6000_read_status(struct dvb_frontend* fe, fe_status_t* status) +static int nxt6000_read_status(struct dvb_frontend *fe, enum fe_status *status) { u8 core_status; struct nxt6000_state* state = fe->demodulator_priv; diff --git a/drivers/media/dvb-frontends/or51132.c b/drivers/media/dvb-frontends/or51132.c index cbbd259eacfe..35b1053b3640 100644 --- a/drivers/media/dvb-frontends/or51132.c +++ b/drivers/media/dvb-frontends/or51132.c @@ -63,7 +63,7 @@ struct or51132_state struct dvb_frontend frontend; /* Demodulator private data */ - fe_modulation_t current_modulation; + enum fe_modulation current_modulation; u32 snr; /* Result of last SNR calculation */ /* Tuner private data */ @@ -292,7 +292,7 @@ static int or51132_setmode(struct dvb_frontend* fe) #define MOD_FWCLASS_UNKNOWN 0 #define MOD_FWCLASS_VSB 1 #define MOD_FWCLASS_QAM 2 -static int modulation_fw_class(fe_modulation_t modulation) +static int modulation_fw_class(enum fe_modulation modulation) { switch(modulation) { case VSB_8: @@ -415,7 +415,7 @@ start: return 0; } -static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status) +static int or51132_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct or51132_state* state = fe->demodulator_priv; int reg; diff --git a/drivers/media/dvb-frontends/or51211.c b/drivers/media/dvb-frontends/or51211.c index 873ea1da844b..e82413b975e6 100644 --- a/drivers/media/dvb-frontends/or51211.c +++ b/drivers/media/dvb-frontends/or51211.c @@ -237,7 +237,7 @@ static int or51211_set_parameters(struct dvb_frontend *fe) return 0; } -static int or51211_read_status(struct dvb_frontend* fe, fe_status_t* status) +static int or51211_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct or51211_state* state = fe->demodulator_priv; unsigned char rec_buf[2]; diff --git a/drivers/media/dvb-frontends/rtl2830.c b/drivers/media/dvb-frontends/rtl2830.c index e1b8df62bd59..3d01f4f22aca 100644 --- a/drivers/media/dvb-frontends/rtl2830.c +++ b/drivers/media/dvb-frontends/rtl2830.c @@ -392,7 +392,7 @@ err: return ret; } -static int rtl2830_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int rtl2830_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct i2c_client *client = fe->demodulator_priv; struct rtl2830_dev *dev = i2c_get_clientdata(client); diff --git a/drivers/media/dvb-frontends/rtl2830_priv.h b/drivers/media/dvb-frontends/rtl2830_priv.h index d50d5376c9c5..cf793f39a09b 100644 --- a/drivers/media/dvb-frontends/rtl2830_priv.h +++ b/drivers/media/dvb-frontends/rtl2830_priv.h @@ -34,7 +34,7 @@ struct rtl2830_dev { bool sleeping; unsigned long filters; struct delayed_work stat_work; - fe_status_t fe_status; + enum fe_status fe_status; u64 post_bit_error_prev; /* for old DVBv3 read_ber() calculation */ u64 post_bit_error; u64 post_bit_count; diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c index a57c478e2306..822ea4b7a7ff 100644 --- a/drivers/media/dvb-frontends/rtl2832.c +++ b/drivers/media/dvb-frontends/rtl2832.c @@ -688,7 +688,7 @@ err: return ret; } -static int rtl2832_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int rtl2832_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct rtl2832_dev *dev = fe->demodulator_priv; struct i2c_client *client = dev->client; diff --git a/drivers/media/dvb-frontends/rtl2832_priv.h b/drivers/media/dvb-frontends/rtl2832_priv.h index 6f3a49c63ab0..5dcd3a41d23f 100644 --- a/drivers/media/dvb-frontends/rtl2832_priv.h +++ b/drivers/media/dvb-frontends/rtl2832_priv.h @@ -39,7 +39,7 @@ struct rtl2832_dev { struct i2c_adapter *i2c_adapter_tuner; struct dvb_frontend fe; struct delayed_work stat_work; - fe_status_t fe_status; + enum fe_status fe_status; u64 post_bit_error_prev; /* for old DVBv3 read_ber() calculation */ u64 post_bit_error; u64 post_bit_count; diff --git a/drivers/media/dvb-frontends/s5h1409.c b/drivers/media/dvb-frontends/s5h1409.c index 5ff474a7ff29..10964848a2f1 100644 --- a/drivers/media/dvb-frontends/s5h1409.c +++ b/drivers/media/dvb-frontends/s5h1409.c @@ -38,7 +38,7 @@ struct s5h1409_state { struct dvb_frontend frontend; /* previous uncorrected block counter */ - fe_modulation_t current_modulation; + enum fe_modulation current_modulation; u32 current_frequency; int if_freq; @@ -400,7 +400,7 @@ static int s5h1409_set_spectralinversion(struct dvb_frontend *fe, int inverted) } static int s5h1409_enable_modulation(struct dvb_frontend *fe, - fe_modulation_t m) + enum fe_modulation m) { struct s5h1409_state *state = fe->demodulator_priv; @@ -755,7 +755,7 @@ static int s5h1409_init(struct dvb_frontend *fe) return 0; } -static int s5h1409_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int s5h1409_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct s5h1409_state *state = fe->demodulator_priv; u16 reg; diff --git a/drivers/media/dvb-frontends/s5h1411.c b/drivers/media/dvb-frontends/s5h1411.c index 64f35fed7ae1..9afc3f42290e 100644 --- a/drivers/media/dvb-frontends/s5h1411.c +++ b/drivers/media/dvb-frontends/s5h1411.c @@ -37,7 +37,7 @@ struct s5h1411_state { struct dvb_frontend frontend; - fe_modulation_t current_modulation; + enum fe_modulation current_modulation; unsigned int first_tune:1; u32 current_frequency; @@ -484,7 +484,7 @@ static int s5h1411_set_serialmode(struct dvb_frontend *fe, int serial) } static int s5h1411_enable_modulation(struct dvb_frontend *fe, - fe_modulation_t m) + enum fe_modulation m) { struct s5h1411_state *state = fe->demodulator_priv; @@ -659,7 +659,7 @@ static int s5h1411_init(struct dvb_frontend *fe) return 0; } -static int s5h1411_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int s5h1411_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct s5h1411_state *state = fe->demodulator_priv; u16 reg; diff --git a/drivers/media/dvb-frontends/s5h1420.c b/drivers/media/dvb-frontends/s5h1420.c index dfc20665e372..9c22a4c70d87 100644 --- a/drivers/media/dvb-frontends/s5h1420.c +++ b/drivers/media/dvb-frontends/s5h1420.c @@ -52,7 +52,7 @@ struct s5h1420_state { u8 postlocked:1; u32 fclk; u32 tunedfreq; - fe_code_rate_t fec_inner; + enum fe_code_rate fec_inner; u32 symbol_rate; /* FIXME: ugly workaround for flexcop's incapable i2c-controller @@ -124,7 +124,8 @@ static int s5h1420_writereg (struct s5h1420_state* state, u8 reg, u8 data) return 0; } -static int s5h1420_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) +static int s5h1420_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { struct s5h1420_state* state = fe->demodulator_priv; @@ -149,7 +150,8 @@ static int s5h1420_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag return 0; } -static int s5h1420_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) +static int s5h1420_set_tone(struct dvb_frontend *fe, + enum fe_sec_tone_mode tone) { struct s5h1420_state* state = fe->demodulator_priv; @@ -270,7 +272,8 @@ exit: return result; } -static int s5h1420_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) +static int s5h1420_send_burst(struct dvb_frontend *fe, + enum fe_sec_mini_cmd minicmd) { struct s5h1420_state* state = fe->demodulator_priv; u8 val; @@ -307,10 +310,10 @@ static int s5h1420_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicm return result; } -static fe_status_t s5h1420_get_status_bits(struct s5h1420_state* state) +static enum fe_status s5h1420_get_status_bits(struct s5h1420_state *state) { u8 val; - fe_status_t status = 0; + enum fe_status status = 0; val = s5h1420_readreg(state, 0x14); if (val & 0x02) @@ -328,7 +331,8 @@ static fe_status_t s5h1420_get_status_bits(struct s5h1420_state* state) return status; } -static int s5h1420_read_status(struct dvb_frontend* fe, fe_status_t* status) +static int s5h1420_read_status(struct dvb_frontend *fe, + enum fe_status *status) { struct s5h1420_state* state = fe->demodulator_priv; u8 val; @@ -601,7 +605,7 @@ static void s5h1420_setfec_inversion(struct s5h1420_state* state, dprintk("leave %s\n", __func__); } -static fe_code_rate_t s5h1420_getfec(struct s5h1420_state* state) +static enum fe_code_rate s5h1420_getfec(struct s5h1420_state *state) { switch(s5h1420_readreg(state, 0x32) & 0x07) { case 0: @@ -626,7 +630,8 @@ static fe_code_rate_t s5h1420_getfec(struct s5h1420_state* state) return FEC_NONE; } -static fe_spectral_inversion_t s5h1420_getinversion(struct s5h1420_state* state) +static enum fe_spectral_inversion +s5h1420_getinversion(struct s5h1420_state *state) { if (s5h1420_readreg(state, 0x32) & 0x08) return INVERSION_ON; diff --git a/drivers/media/dvb-frontends/s5h1432.c b/drivers/media/dvb-frontends/s5h1432.c index 6ec16a243741..4215652f8eb7 100644 --- a/drivers/media/dvb-frontends/s5h1432.c +++ b/drivers/media/dvb-frontends/s5h1432.c @@ -36,7 +36,7 @@ struct s5h1432_state { struct dvb_frontend frontend; - fe_modulation_t current_modulation; + enum fe_modulation current_modulation; unsigned int first_tune:1; u32 current_frequency; @@ -302,7 +302,7 @@ static int s5h1432_init(struct dvb_frontend *fe) return 0; } -static int s5h1432_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int s5h1432_read_status(struct dvb_frontend *fe, enum fe_status *status) { return 0; } diff --git a/drivers/media/dvb-frontends/s921.c b/drivers/media/dvb-frontends/s921.c index 69862e1fd9e9..b2d9fe13e1a0 100644 --- a/drivers/media/dvb-frontends/s921.c +++ b/drivers/media/dvb-frontends/s921.c @@ -348,7 +348,7 @@ static int s921_initfe(struct dvb_frontend *fe) return 0; } -static int s921_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int s921_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct s921_state *state = fe->demodulator_priv; int regstatus, rc; @@ -389,7 +389,7 @@ static int s921_read_status(struct dvb_frontend *fe, fe_status_t *status) static int s921_read_signal_strength(struct dvb_frontend *fe, u16 *strength) { - fe_status_t status; + enum fe_status status; struct s921_state *state = fe->demodulator_priv; int rc; @@ -449,7 +449,7 @@ static int s921_tune(struct dvb_frontend *fe, bool re_tune, unsigned int mode_flags, unsigned int *delay, - fe_status_t *status) + enum fe_status *status) { int rc = 0; diff --git a/drivers/media/dvb-frontends/si2165.c b/drivers/media/dvb-frontends/si2165.c index 4cc5d10ed0d4..7c2eeee69757 100644 --- a/drivers/media/dvb-frontends/si2165.c +++ b/drivers/media/dvb-frontends/si2165.c @@ -698,7 +698,7 @@ static int si2165_sleep(struct dvb_frontend *fe) return 0; } -static int si2165_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int si2165_read_status(struct dvb_frontend *fe, enum fe_status *status) { int ret; u8 fec_lock = 0; diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c index d6a4cb0688c3..25e238c370e5 100644 --- a/drivers/media/dvb-frontends/si2168.c +++ b/drivers/media/dvb-frontends/si2168.c @@ -120,7 +120,7 @@ static int si2168_cmd_execute(struct i2c_client *client, struct si2168_cmd *cmd) return ret; } -static int si2168_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int si2168_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct i2c_client *client = fe->demodulator_priv; struct si2168_dev *dev = i2c_get_clientdata(client); diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h index 90b6b6eace24..c07e6fe2cb10 100644 --- a/drivers/media/dvb-frontends/si2168_priv.h +++ b/drivers/media/dvb-frontends/si2168_priv.h @@ -31,8 +31,8 @@ struct si2168_dev { struct i2c_adapter *adapter; struct dvb_frontend fe; - fe_delivery_system_t delivery_system; - fe_status_t fe_status; + enum fe_delivery_system delivery_system; + enum fe_status fe_status; bool active; bool fw_loaded; u8 ts_mode; diff --git a/drivers/media/dvb-frontends/si21xx.c b/drivers/media/dvb-frontends/si21xx.c index 16850e2bf02f..62ad7a7be9f8 100644 --- a/drivers/media/dvb-frontends/si21xx.c +++ b/drivers/media/dvb-frontends/si21xx.c @@ -410,7 +410,7 @@ static int si21xx_send_diseqc_msg(struct dvb_frontend *fe, } static int si21xx_send_diseqc_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t burst) + enum fe_sec_mini_cmd burst) { struct si21xx_state *state = fe->demodulator_priv; u8 val; @@ -434,7 +434,7 @@ static int si21xx_send_diseqc_burst(struct dvb_frontend *fe, return 0; } /* 30.06.2008 */ -static int si21xx_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) +static int si21xx_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone) { struct si21xx_state *state = fe->demodulator_priv; u8 val; @@ -454,7 +454,7 @@ static int si21xx_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) } } -static int si21xx_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt) +static int si21xx_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage volt) { struct si21xx_state *state = fe->demodulator_priv; @@ -536,7 +536,7 @@ static int si21xx_init(struct dvb_frontend *fe) } -static int si21_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int si21_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct si21xx_state *state = fe->demodulator_priv; u8 regs_read[2]; @@ -641,7 +641,7 @@ static int si21_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) /* initiates a channel acquisition sequence using the specified symbol rate and code rate */ static int si21xx_setacquire(struct dvb_frontend *fe, int symbrate, - fe_code_rate_t crate) + enum fe_code_rate crate) { struct si21xx_state *state = fe->demodulator_priv; diff --git a/drivers/media/dvb-frontends/sp8870.c b/drivers/media/dvb-frontends/sp8870.c index 57dc2abaa87b..e87ac30d7fb8 100644 --- a/drivers/media/dvb-frontends/sp8870.c +++ b/drivers/media/dvb-frontends/sp8870.c @@ -350,7 +350,8 @@ static int sp8870_init (struct dvb_frontend* fe) return 0; } -static int sp8870_read_status (struct dvb_frontend* fe, fe_status_t * fe_status) +static int sp8870_read_status(struct dvb_frontend *fe, + enum fe_status *fe_status) { struct sp8870_state* state = fe->demodulator_priv; int status; diff --git a/drivers/media/dvb-frontends/sp887x.c b/drivers/media/dvb-frontends/sp887x.c index 1bb81b5ae6e0..4378fe1b978e 100644 --- a/drivers/media/dvb-frontends/sp887x.c +++ b/drivers/media/dvb-frontends/sp887x.c @@ -416,7 +416,7 @@ static int sp887x_setup_frontend_parameters(struct dvb_frontend *fe) return 0; } -static int sp887x_read_status(struct dvb_frontend* fe, fe_status_t* status) +static int sp887x_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct sp887x_state* state = fe->demodulator_priv; u16 snr12 = sp887x_readreg(state, 0xf16); diff --git a/drivers/media/dvb-frontends/stb0899_drv.c b/drivers/media/dvb-frontends/stb0899_drv.c index c73899d3a53d..756650f154ab 100644 --- a/drivers/media/dvb-frontends/stb0899_drv.c +++ b/drivers/media/dvb-frontends/stb0899_drv.c @@ -792,7 +792,8 @@ static int stb0899_wait_diseqc_txidle(struct stb0899_state *state, int timeout) return 0; } -static int stb0899_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst) +static int stb0899_send_diseqc_burst(struct dvb_frontend *fe, + enum fe_sec_mini_cmd burst) { struct stb0899_state *state = fe->demodulator_priv; u8 reg, old_state; @@ -1178,7 +1179,8 @@ static int stb0899_read_ber(struct dvb_frontend *fe, u32 *ber) return 0; } -static int stb0899_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +static int stb0899_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { struct stb0899_state *state = fe->demodulator_priv; @@ -1205,7 +1207,7 @@ static int stb0899_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage return 0; } -static int stb0899_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) +static int stb0899_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone) { struct stb0899_state *state = fe->demodulator_priv; struct stb0899_internal *internal = &state->internal; diff --git a/drivers/media/dvb-frontends/stv0288.c b/drivers/media/dvb-frontends/stv0288.c index ecf4bb3a3b6b..c93d9a45f7f7 100644 --- a/drivers/media/dvb-frontends/stv0288.c +++ b/drivers/media/dvb-frontends/stv0288.c @@ -44,7 +44,7 @@ struct stv0288_state { u8 initialised:1; u32 tuner_frequency; u32 symbol_rate; - fe_code_rate_t fec_inner; + enum fe_code_rate fec_inner; int errmode; }; @@ -174,7 +174,7 @@ static int stv0288_send_diseqc_msg(struct dvb_frontend *fe, } static int stv0288_send_diseqc_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t burst) + enum fe_sec_mini_cmd burst) { struct stv0288_state *state = fe->demodulator_priv; @@ -193,7 +193,7 @@ static int stv0288_send_diseqc_burst(struct dvb_frontend *fe, return 0; } -static int stv0288_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) +static int stv0288_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone) { struct stv0288_state *state = fe->demodulator_priv; @@ -323,7 +323,8 @@ static u8 stv0288_inittab[] = { 0xff, 0xff, }; -static int stv0288_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt) +static int stv0288_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage volt) { dprintk("%s: %s\n", __func__, volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" : @@ -361,7 +362,7 @@ static int stv0288_init(struct dvb_frontend *fe) return 0; } -static int stv0288_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int stv0288_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct stv0288_state *state = fe->demodulator_priv; diff --git a/drivers/media/dvb-frontends/stv0297.c b/drivers/media/dvb-frontends/stv0297.c index dfc14d5c3999..75b4d8b25657 100644 --- a/drivers/media/dvb-frontends/stv0297.c +++ b/drivers/media/dvb-frontends/stv0297.c @@ -233,7 +233,8 @@ static void stv0297_set_initialdemodfreq(struct stv0297_state *state, long freq) stv0297_writereg(state, 0x20, tmp); } -static int stv0297_set_qam(struct stv0297_state *state, fe_modulation_t modulation) +static int stv0297_set_qam(struct stv0297_state *state, + enum fe_modulation modulation) { int val = 0; @@ -267,7 +268,8 @@ static int stv0297_set_qam(struct stv0297_state *state, fe_modulation_t modulati return 0; } -static int stv0297_set_inversion(struct stv0297_state *state, fe_spectral_inversion_t inversion) +static int stv0297_set_inversion(struct stv0297_state *state, + enum fe_spectral_inversion inversion) { int val = 0; @@ -325,7 +327,8 @@ static int stv0297_sleep(struct dvb_frontend *fe) return 0; } -static int stv0297_read_status(struct dvb_frontend *fe, fe_status_t * status) +static int stv0297_read_status(struct dvb_frontend *fe, + enum fe_status *status) { struct stv0297_state *state = fe->demodulator_priv; @@ -415,7 +418,7 @@ static int stv0297_set_frontend(struct dvb_frontend *fe) int sweeprate; int carrieroffset; unsigned long timeout; - fe_spectral_inversion_t inversion; + enum fe_spectral_inversion inversion; switch (p->modulation) { case QAM_16: diff --git a/drivers/media/dvb-frontends/stv0299.c b/drivers/media/dvb-frontends/stv0299.c index b57ecf42e75a..0ca5d9f0d851 100644 --- a/drivers/media/dvb-frontends/stv0299.c +++ b/drivers/media/dvb-frontends/stv0299.c @@ -61,7 +61,7 @@ struct stv0299_state { u8 initialised:1; u32 tuner_frequency; u32 symbol_rate; - fe_code_rate_t fec_inner; + enum fe_code_rate fec_inner; int errmode; u32 ucblocks; u8 mcr_reg; @@ -134,7 +134,7 @@ static int stv0299_readregs (struct stv0299_state* state, u8 reg1, u8 *b, u8 len return ret == 2 ? 0 : ret; } -static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec) +static int stv0299_set_FEC(struct stv0299_state *state, enum fe_code_rate fec) { dprintk ("%s\n", __func__); @@ -170,10 +170,10 @@ static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec) } } -static fe_code_rate_t stv0299_get_fec (struct stv0299_state* state) +static enum fe_code_rate stv0299_get_fec(struct stv0299_state *state) { - static fe_code_rate_t fec_tab [] = { FEC_2_3, FEC_3_4, FEC_5_6, - FEC_7_8, FEC_1_2 }; + static enum fe_code_rate fec_tab[] = { FEC_2_3, FEC_3_4, FEC_5_6, + FEC_7_8, FEC_1_2 }; u8 index; dprintk ("%s\n", __func__); @@ -302,7 +302,8 @@ static int stv0299_send_diseqc_msg (struct dvb_frontend* fe, return 0; } -static int stv0299_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) +static int stv0299_send_diseqc_burst(struct dvb_frontend *fe, + enum fe_sec_mini_cmd burst) { struct stv0299_state* state = fe->demodulator_priv; u8 val; @@ -329,7 +330,8 @@ static int stv0299_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t return 0; } -static int stv0299_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) +static int stv0299_set_tone(struct dvb_frontend *fe, + enum fe_sec_tone_mode tone) { struct stv0299_state* state = fe->demodulator_priv; u8 val; @@ -351,7 +353,8 @@ static int stv0299_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) } } -static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) +static int stv0299_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { struct stv0299_state* state = fe->demodulator_priv; u8 reg0x08; @@ -476,7 +479,8 @@ static int stv0299_init (struct dvb_frontend* fe) return 0; } -static int stv0299_read_status(struct dvb_frontend* fe, fe_status_t* status) +static int stv0299_read_status(struct dvb_frontend *fe, + enum fe_status *status) { struct stv0299_state* state = fe->demodulator_priv; diff --git a/drivers/media/dvb-frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c index b31ff265ff24..ec3e18e5ff50 100644 --- a/drivers/media/dvb-frontends/stv0367.c +++ b/drivers/media/dvb-frontends/stv0367.c @@ -59,7 +59,7 @@ struct stv0367cab_state { int locked; /* channel found */ u32 freq_khz; /* found frequency (in kHz) */ u32 symbol_rate; /* found symbol rate (in Bds) */ - fe_spectral_inversion_t spect_inv; /* Spectrum Inversion */ + enum fe_spectral_inversion spect_inv; /* Spectrum Inversion */ }; struct stv0367ter_state { @@ -67,10 +67,10 @@ struct stv0367ter_state { enum stv0367_ter_signal_type state; enum stv0367_ter_if_iq_mode if_iq_mode; enum stv0367_ter_mode mode;/* mode 2K or 8K */ - fe_guard_interval_t guard; + enum fe_guard_interval guard; enum stv0367_ter_hierarchy hierarchy; u32 frequency; - fe_spectral_inversion_t sense; /* current search spectrum */ + enum fe_spectral_inversion sense; /* current search spectrum */ u8 force; /* force mode/guard */ u8 bw; /* channel width 6, 7 or 8 in MHz */ u8 pBW; /* channel width used during previous lock */ @@ -2074,7 +2074,8 @@ static int stv0367ter_status(struct dvb_frontend *fe) return locked; } #endif -static int stv0367ter_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int stv0367ter_read_status(struct dvb_frontend *fe, + enum fe_status *status) { struct stv0367_state *state = fe->demodulator_priv; @@ -2716,7 +2717,8 @@ static u32 stv0367cab_GetSymbolRate(struct stv0367_state *state, u32 mclk_hz) return regsym; } -static int stv0367cab_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int stv0367cab_read_status(struct dvb_frontend *fe, + enum fe_status *status) { struct stv0367_state *state = fe->demodulator_priv; diff --git a/drivers/media/dvb-frontends/stv0367_priv.h b/drivers/media/dvb-frontends/stv0367_priv.h index 995db0689ddd..89bf6f64b078 100644 --- a/drivers/media/dvb-frontends/stv0367_priv.h +++ b/drivers/media/dvb-frontends/stv0367_priv.h @@ -188,7 +188,7 @@ struct stv0367_cab_signal_info { u32 frequency; /* kHz */ u32 symbol_rate; /* Mbds */ enum stv0367cab_mod modulation; - fe_spectral_inversion_t spect_inv; + enum fe_spectral_inversion spect_inv; s32 Power_dBmx10; /* Power of the RF signal (dBm x 10) */ u32 CN_dBx10; /* Carrier to noise ratio (dB x 10) */ u32 BER; /* Bit error rate (x 10000000) */ diff --git a/drivers/media/dvb-frontends/stv0900_core.c b/drivers/media/dvb-frontends/stv0900_core.c index 2c88abfab531..fe31dd541955 100644 --- a/drivers/media/dvb-frontends/stv0900_core.c +++ b/drivers/media/dvb-frontends/stv0900_core.c @@ -1744,7 +1744,8 @@ static int stv0900_send_master_cmd(struct dvb_frontend *fe, state->demod); } -static int stv0900_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst) +static int stv0900_send_burst(struct dvb_frontend *fe, + enum fe_sec_mini_cmd burst) { struct stv0900_state *state = fe->demodulator_priv; struct stv0900_internal *intp = state->internal; @@ -1793,7 +1794,8 @@ static int stv0900_recv_slave_reply(struct dvb_frontend *fe, return 0; } -static int stv0900_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t toneoff) +static int stv0900_set_tone(struct dvb_frontend *fe, + enum fe_sec_tone_mode toneoff) { struct stv0900_state *state = fe->demodulator_priv; struct stv0900_internal *intp = state->internal; diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c index 0b2a934f53e5..25bdf6e0f963 100644 --- a/drivers/media/dvb-frontends/stv090x.c +++ b/drivers/media/dvb-frontends/stv090x.c @@ -3732,7 +3732,7 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr) return 0; } -static int stv090x_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) +static int stv090x_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone) { struct stv090x_state *state = fe->demodulator_priv; u32 reg; @@ -3822,7 +3822,8 @@ err: return -1; } -static int stv090x_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst) +static int stv090x_send_diseqc_burst(struct dvb_frontend *fe, + enum fe_sec_mini_cmd burst) { struct stv090x_state *state = fe->demodulator_priv; u32 reg, idle = 0, fifo_full = 1; diff --git a/drivers/media/dvb-frontends/stv6110.c b/drivers/media/dvb-frontends/stv6110.c index b1425830a24e..91c6dcf65d2a 100644 --- a/drivers/media/dvb-frontends/stv6110.c +++ b/drivers/media/dvb-frontends/stv6110.c @@ -158,7 +158,7 @@ static int stv6110_sleep(struct dvb_frontend *fe) return 0; } -static u32 carrier_width(u32 symbol_rate, fe_rolloff_t rolloff) +static u32 carrier_width(u32 symbol_rate, enum fe_rolloff rolloff) { u32 rlf; diff --git a/drivers/media/dvb-frontends/tc90522.c b/drivers/media/dvb-frontends/tc90522.c index dce22ce35d20..456cdc7fb1e7 100644 --- a/drivers/media/dvb-frontends/tc90522.c +++ b/drivers/media/dvb-frontends/tc90522.c @@ -130,7 +130,7 @@ static int tc90522t_set_layers(struct dvb_frontend *fe) /* frontend ops */ -static int tc90522s_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int tc90522s_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct tc90522_state *state; int ret; @@ -158,7 +158,7 @@ static int tc90522s_read_status(struct dvb_frontend *fe, fe_status_t *status) return 0; } -static int tc90522t_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int tc90522t_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct tc90522_state *state; int ret; @@ -194,7 +194,7 @@ static int tc90522t_read_status(struct dvb_frontend *fe, fe_status_t *status) return 0; } -static const fe_code_rate_t fec_conv_sat[] = { +static const enum fe_code_rate fec_conv_sat[] = { FEC_NONE, /* unused */ FEC_1_2, /* for BPSK */ FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, /* for QPSK */ @@ -238,7 +238,10 @@ static int tc90522s_get_frontend(struct dvb_frontend *fe) c->layer[1].segment_count = 0; else c->layer[1].segment_count = val[4] & 0x3f; /* slots */ - /* actually, BPSK if v==1, but not defined in fe_modulation_t */ + /* + * actually, BPSK if v==1, but not defined in + * enum fe_modulation + */ c->layer[1].modulation = QPSK; layers = (v > 0) ? 2 : 1; } @@ -319,18 +322,18 @@ static int tc90522s_get_frontend(struct dvb_frontend *fe) } -static const fe_transmit_mode_t tm_conv[] = { +static const enum fe_transmit_mode tm_conv[] = { TRANSMISSION_MODE_2K, TRANSMISSION_MODE_4K, TRANSMISSION_MODE_8K, 0 }; -static const fe_code_rate_t fec_conv_ter[] = { +static const enum fe_code_rate fec_conv_ter[] = { FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, 0, 0, 0 }; -static const fe_modulation_t mod_conv[] = { +static const enum fe_modulation mod_conv[] = { DQPSK, QPSK, QAM_16, QAM_64, 0, 0, 0, 0 }; diff --git a/drivers/media/dvb-frontends/tda10021.c b/drivers/media/dvb-frontends/tda10021.c index 28d987068048..a684424e665a 100644 --- a/drivers/media/dvb-frontends/tda10021.c +++ b/drivers/media/dvb-frontends/tda10021.c @@ -129,8 +129,8 @@ static int unlock_tuner(struct tda10021_state* state) return 0; } -static int tda10021_setup_reg0 (struct tda10021_state* state, u8 reg0, - fe_spectral_inversion_t inversion) +static int tda10021_setup_reg0(struct tda10021_state *state, u8 reg0, + enum fe_spectral_inversion inversion) { reg0 |= state->reg0 & 0x63; @@ -308,7 +308,8 @@ static int tda10021_set_parameters(struct dvb_frontend *fe) return 0; } -static int tda10021_read_status(struct dvb_frontend* fe, fe_status_t* status) +static int tda10021_read_status(struct dvb_frontend *fe, + enum fe_status *status) { struct tda10021_state* state = fe->demodulator_priv; int sync; diff --git a/drivers/media/dvb-frontends/tda10023.c b/drivers/media/dvb-frontends/tda10023.c index f92fbbbb4a71..44a55656093f 100644 --- a/drivers/media/dvb-frontends/tda10023.c +++ b/drivers/media/dvb-frontends/tda10023.c @@ -376,7 +376,8 @@ static int tda10023_set_parameters(struct dvb_frontend *fe) return 0; } -static int tda10023_read_status(struct dvb_frontend* fe, fe_status_t* status) +static int tda10023_read_status(struct dvb_frontend *fe, + enum fe_status *status) { struct tda10023_state* state = fe->demodulator_priv; int sync; diff --git a/drivers/media/dvb-frontends/tda10048.c b/drivers/media/dvb-frontends/tda10048.c index 71fb63299de7..8451086c563f 100644 --- a/drivers/media/dvb-frontends/tda10048.c +++ b/drivers/media/dvb-frontends/tda10048.c @@ -792,7 +792,7 @@ static int tda10048_init(struct dvb_frontend *fe) return ret; } -static int tda10048_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int tda10048_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct tda10048_state *state = fe->demodulator_priv; u8 reg; diff --git a/drivers/media/dvb-frontends/tda1004x.c b/drivers/media/dvb-frontends/tda1004x.c index d2b8ecbea81e..0e209b56c76c 100644 --- a/drivers/media/dvb-frontends/tda1004x.c +++ b/drivers/media/dvb-frontends/tda1004x.c @@ -1005,7 +1005,8 @@ static int tda1004x_get_fe(struct dvb_frontend *fe) return 0; } -static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status) +static int tda1004x_read_status(struct dvb_frontend *fe, + enum fe_status *fe_status) { struct tda1004x_state* state = fe->demodulator_priv; int status; diff --git a/drivers/media/dvb-frontends/tda10071.c b/drivers/media/dvb-frontends/tda10071.c index 1470a5d63f58..f6dc6307d35a 100644 --- a/drivers/media/dvb-frontends/tda10071.c +++ b/drivers/media/dvb-frontends/tda10071.c @@ -203,7 +203,7 @@ error: } static int tda10071_set_tone(struct dvb_frontend *fe, - fe_sec_tone_mode_t fe_sec_tone_mode) + enum fe_sec_tone_mode fe_sec_tone_mode) { struct tda10071_priv *priv = fe->demodulator_priv; struct tda10071_cmd cmd; @@ -249,7 +249,7 @@ error: } static int tda10071_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t fe_sec_voltage) + enum fe_sec_voltage fe_sec_voltage) { struct tda10071_priv *priv = fe->demodulator_priv; struct tda10071_cmd cmd; @@ -413,7 +413,7 @@ error: } static int tda10071_diseqc_send_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t fe_sec_mini_cmd) + enum fe_sec_mini_cmd fe_sec_mini_cmd) { struct tda10071_priv *priv = fe->demodulator_priv; struct tda10071_cmd cmd; @@ -476,7 +476,7 @@ error: return ret; } -static int tda10071_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int tda10071_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct tda10071_priv *priv = fe->demodulator_priv; int ret; @@ -668,7 +668,7 @@ static int tda10071_set_frontend(struct dvb_frontend *fe) struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, i; u8 mode, rolloff, pilot, inversion, div; - fe_modulation_t modulation; + enum fe_modulation modulation; dev_dbg(&priv->i2c->dev, "%s: delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d pilot=%d rolloff=%d\n", diff --git a/drivers/media/dvb-frontends/tda10071_priv.h b/drivers/media/dvb-frontends/tda10071_priv.h index 7ec69ac510d7..54d7c713eec8 100644 --- a/drivers/media/dvb-frontends/tda10071_priv.h +++ b/drivers/media/dvb-frontends/tda10071_priv.h @@ -34,15 +34,15 @@ struct tda10071_priv { u8 meas_count[2]; u32 ber; u32 ucb; - fe_status_t fe_status; - fe_delivery_system_t delivery_system; + enum fe_status fe_status; + enum fe_delivery_system delivery_system; bool warm; /* FW running */ }; static struct tda10071_modcod { - fe_delivery_system_t delivery_system; - fe_modulation_t modulation; - fe_code_rate_t fec; + enum fe_delivery_system delivery_system; + enum fe_modulation modulation; + enum fe_code_rate fec; u8 val; } TDA10071_MODCOD[] = { /* NBC-QPSK */ diff --git a/drivers/media/dvb-frontends/tda10086.c b/drivers/media/dvb-frontends/tda10086.c index f1a752187d08..95a33e187f8e 100644 --- a/drivers/media/dvb-frontends/tda10086.c +++ b/drivers/media/dvb-frontends/tda10086.c @@ -185,7 +185,8 @@ static void tda10086_diseqc_wait(struct tda10086_state *state) } } -static int tda10086_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) +static int tda10086_set_tone(struct dvb_frontend *fe, + enum fe_sec_tone_mode tone) { struct tda10086_state* state = fe->demodulator_priv; u8 t22k_off = 0x80; @@ -238,7 +239,8 @@ static int tda10086_send_master_cmd (struct dvb_frontend* fe, return 0; } -static int tda10086_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) +static int tda10086_send_burst(struct dvb_frontend *fe, + enum fe_sec_mini_cmd minicmd) { struct tda10086_state* state = fe->demodulator_priv; u8 oldval = tda10086_read_byte(state, 0x36); @@ -551,7 +553,8 @@ static int tda10086_get_frontend(struct dvb_frontend *fe) return 0; } -static int tda10086_read_status(struct dvb_frontend* fe, fe_status_t *fe_status) +static int tda10086_read_status(struct dvb_frontend *fe, + enum fe_status *fe_status) { struct tda10086_state* state = fe->demodulator_priv; u8 val; diff --git a/drivers/media/dvb-frontends/tda8083.c b/drivers/media/dvb-frontends/tda8083.c index 69e62f42e2e1..796543fa2c8d 100644 --- a/drivers/media/dvb-frontends/tda8083.c +++ b/drivers/media/dvb-frontends/tda8083.c @@ -97,7 +97,8 @@ static inline u8 tda8083_readreg (struct tda8083_state* state, u8 reg) return val; } -static int tda8083_set_inversion (struct tda8083_state* state, fe_spectral_inversion_t inversion) +static int tda8083_set_inversion(struct tda8083_state *state, + enum fe_spectral_inversion inversion) { /* XXX FIXME: implement other modes than FEC_AUTO */ if (inversion == INVERSION_AUTO) @@ -106,7 +107,7 @@ static int tda8083_set_inversion (struct tda8083_state* state, fe_spectral_inver return -EINVAL; } -static int tda8083_set_fec (struct tda8083_state* state, fe_code_rate_t fec) +static int tda8083_set_fec(struct tda8083_state *state, enum fe_code_rate fec) { if (fec == FEC_AUTO) return tda8083_writereg (state, 0x07, 0xff); @@ -117,11 +118,13 @@ static int tda8083_set_fec (struct tda8083_state* state, fe_code_rate_t fec) return -EINVAL; } -static fe_code_rate_t tda8083_get_fec (struct tda8083_state* state) +static enum fe_code_rate tda8083_get_fec(struct tda8083_state *state) { u8 index; - static fe_code_rate_t fec_tab [] = { FEC_8_9, FEC_1_2, FEC_2_3, FEC_3_4, - FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8 }; + static enum fe_code_rate fec_tab[] = { + FEC_8_9, FEC_1_2, FEC_2_3, FEC_3_4, + FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8 + }; index = tda8083_readreg(state, 0x0e) & 0x07; @@ -178,7 +181,8 @@ static void tda8083_wait_diseqc_fifo (struct tda8083_state* state, int timeout) } } -static int tda8083_set_tone (struct tda8083_state* state, fe_sec_tone_mode_t tone) +static int tda8083_set_tone(struct tda8083_state *state, + enum fe_sec_tone_mode tone) { tda8083_writereg (state, 0x26, 0xf1); @@ -192,7 +196,8 @@ static int tda8083_set_tone (struct tda8083_state* state, fe_sec_tone_mode_t ton } } -static int tda8083_set_voltage (struct tda8083_state* state, fe_sec_voltage_t voltage) +static int tda8083_set_voltage(struct tda8083_state *state, + enum fe_sec_voltage voltage) { switch (voltage) { case SEC_VOLTAGE_13: @@ -204,7 +209,8 @@ static int tda8083_set_voltage (struct tda8083_state* state, fe_sec_voltage_t vo } } -static int tda8083_send_diseqc_burst (struct tda8083_state* state, fe_sec_mini_cmd_t burst) +static int tda8083_send_diseqc_burst(struct tda8083_state *state, + enum fe_sec_mini_cmd burst) { switch (burst) { case SEC_MINI_A: @@ -222,8 +228,8 @@ static int tda8083_send_diseqc_burst (struct tda8083_state* state, fe_sec_mini_c return 0; } -static int tda8083_send_diseqc_msg (struct dvb_frontend* fe, - struct dvb_diseqc_master_cmd *m) +static int tda8083_send_diseqc_msg(struct dvb_frontend *fe, + struct dvb_diseqc_master_cmd *m) { struct tda8083_state* state = fe->demodulator_priv; int i; @@ -240,7 +246,8 @@ static int tda8083_send_diseqc_msg (struct dvb_frontend* fe, return 0; } -static int tda8083_read_status(struct dvb_frontend* fe, fe_status_t* status) +static int tda8083_read_status(struct dvb_frontend *fe, + enum fe_status *status) { struct tda8083_state* state = fe->demodulator_priv; @@ -372,7 +379,8 @@ static int tda8083_init(struct dvb_frontend* fe) return 0; } -static int tda8083_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) +static int tda8083_diseqc_send_burst(struct dvb_frontend *fe, + enum fe_sec_mini_cmd burst) { struct tda8083_state* state = fe->demodulator_priv; @@ -383,7 +391,8 @@ static int tda8083_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t return 0; } -static int tda8083_diseqc_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) +static int tda8083_diseqc_set_tone(struct dvb_frontend *fe, + enum fe_sec_tone_mode tone) { struct tda8083_state* state = fe->demodulator_priv; @@ -394,7 +403,8 @@ static int tda8083_diseqc_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t t return 0; } -static int tda8083_diseqc_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) +static int tda8083_diseqc_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { struct tda8083_state* state = fe->demodulator_priv; diff --git a/drivers/media/dvb-frontends/ves1820.c b/drivers/media/dvb-frontends/ves1820.c index bb42b563c42d..aacfdda3e005 100644 --- a/drivers/media/dvb-frontends/ves1820.c +++ b/drivers/media/dvb-frontends/ves1820.c @@ -90,7 +90,8 @@ static u8 ves1820_readreg(struct ves1820_state *state, u8 reg) return b1[0]; } -static int ves1820_setup_reg0(struct ves1820_state *state, u8 reg0, fe_spectral_inversion_t inversion) +static int ves1820_setup_reg0(struct ves1820_state *state, + u8 reg0, enum fe_spectral_inversion inversion) { reg0 |= state->reg0 & 0x62; @@ -237,7 +238,8 @@ static int ves1820_set_parameters(struct dvb_frontend *fe) return 0; } -static int ves1820_read_status(struct dvb_frontend* fe, fe_status_t* status) +static int ves1820_read_status(struct dvb_frontend *fe, + enum fe_status *status) { struct ves1820_state* state = fe->demodulator_priv; int sync; diff --git a/drivers/media/dvb-frontends/ves1x93.c b/drivers/media/dvb-frontends/ves1x93.c index 9c17eacaec24..526952396422 100644 --- a/drivers/media/dvb-frontends/ves1x93.c +++ b/drivers/media/dvb-frontends/ves1x93.c @@ -41,7 +41,7 @@ struct ves1x93_state { struct dvb_frontend frontend; /* previous uncorrected block counter */ - fe_spectral_inversion_t inversion; + enum fe_spectral_inversion inversion; u8 *init_1x93_tab; u8 *init_1x93_wtab; u8 tab_size; @@ -130,7 +130,8 @@ static int ves1x93_clr_bit (struct ves1x93_state* state) return 0; } -static int ves1x93_set_inversion (struct ves1x93_state* state, fe_spectral_inversion_t inversion) +static int ves1x93_set_inversion(struct ves1x93_state *state, + enum fe_spectral_inversion inversion) { u8 val; @@ -156,7 +157,7 @@ static int ves1x93_set_inversion (struct ves1x93_state* state, fe_spectral_inver return ves1x93_writereg (state, 0x0c, (state->init_1x93_tab[0x0c] & 0x3f) | val); } -static int ves1x93_set_fec (struct ves1x93_state* state, fe_code_rate_t fec) +static int ves1x93_set_fec(struct ves1x93_state *state, enum fe_code_rate fec) { if (fec == FEC_AUTO) return ves1x93_writereg (state, 0x0d, 0x08); @@ -166,7 +167,7 @@ static int ves1x93_set_fec (struct ves1x93_state* state, fe_code_rate_t fec) return ves1x93_writereg (state, 0x0d, fec - FEC_1_2); } -static fe_code_rate_t ves1x93_get_fec (struct ves1x93_state* state) +static enum fe_code_rate ves1x93_get_fec(struct ves1x93_state *state) { return FEC_1_2 + ((ves1x93_readreg (state, 0x0d) >> 4) & 0x7); } @@ -281,7 +282,8 @@ static int ves1x93_init (struct dvb_frontend* fe) return 0; } -static int ves1x93_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) +static int ves1x93_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { struct ves1x93_state* state = fe->demodulator_priv; @@ -297,7 +299,8 @@ static int ves1x93_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag } } -static int ves1x93_read_status(struct dvb_frontend* fe, fe_status_t* status) +static int ves1x93_read_status(struct dvb_frontend *fe, + enum fe_status *status) { struct ves1x93_state* state = fe->demodulator_priv; diff --git a/drivers/media/dvb-frontends/zl10353.c b/drivers/media/dvb-frontends/zl10353.c index 4e62a6611847..ef9764a02d4c 100644 --- a/drivers/media/dvb-frontends/zl10353.c +++ b/drivers/media/dvb-frontends/zl10353.c @@ -462,7 +462,7 @@ static int zl10353_get_parameters(struct dvb_frontend *fe) return 0; } -static int zl10353_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int zl10353_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct zl10353_state *state = fe->demodulator_priv; int s6, s7, s8; diff --git a/drivers/media/firewire/firedtv-fe.c b/drivers/media/firewire/firedtv-fe.c index 6fe9793b98b3..17acda6bcb6e 100644 --- a/drivers/media/firewire/firedtv-fe.c +++ b/drivers/media/firewire/firedtv-fe.c @@ -61,12 +61,12 @@ static int fdtv_diseqc_send_master_cmd(struct dvb_frontend *fe, } static int fdtv_diseqc_send_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t minicmd) + enum fe_sec_mini_cmd minicmd) { return 0; } -static int fdtv_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) +static int fdtv_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone) { struct firedtv *fdtv = fe->sec_priv; @@ -75,7 +75,7 @@ static int fdtv_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) } static int fdtv_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) + enum fe_sec_voltage voltage) { struct firedtv *fdtv = fe->sec_priv; @@ -83,7 +83,7 @@ static int fdtv_set_voltage(struct dvb_frontend *fe, return 0; } -static int fdtv_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int fdtv_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct firedtv *fdtv = fe->sec_priv; struct firedtv_tuner_status stat; diff --git a/drivers/media/firewire/firedtv.h b/drivers/media/firewire/firedtv.h index 346a85be6de2..345d1eda8c05 100644 --- a/drivers/media/firewire/firedtv.h +++ b/drivers/media/firewire/firedtv.h @@ -99,8 +99,8 @@ struct firedtv { s8 isochannel; struct fdtv_ir_context *ir_context; - fe_sec_voltage_t voltage; - fe_sec_tone_mode_t tone; + enum fe_sec_voltage voltage; + enum fe_sec_tone_mode tone; struct mutex demux_mutex; unsigned long channel_active; diff --git a/drivers/media/pci/bt8xx/dst.c b/drivers/media/pci/bt8xx/dst.c index f2261dfe5d1a..4a90eee5e3bb 100644 --- a/drivers/media/pci/bt8xx/dst.c +++ b/drivers/media/pci/bt8xx/dst.c @@ -425,7 +425,8 @@ static int dst_set_bandwidth(struct dst_state *state, u32 bandwidth) return 0; } -static int dst_set_inversion(struct dst_state *state, fe_spectral_inversion_t inversion) +static int dst_set_inversion(struct dst_state *state, + enum fe_spectral_inversion inversion) { state->inversion = inversion; switch (inversion) { @@ -442,13 +443,13 @@ static int dst_set_inversion(struct dst_state *state, fe_spectral_inversion_t in return 0; } -static int dst_set_fec(struct dst_state *state, fe_code_rate_t fec) +static int dst_set_fec(struct dst_state *state, enum fe_code_rate fec) { state->fec = fec; return 0; } -static fe_code_rate_t dst_get_fec(struct dst_state *state) +static enum fe_code_rate dst_get_fec(struct dst_state *state) { return state->fec; } @@ -499,7 +500,8 @@ static int dst_set_symbolrate(struct dst_state *state, u32 srate) return 0; } -static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulation) +static int dst_set_modulation(struct dst_state *state, + enum fe_modulation modulation) { if (state->dst_type != DST_TYPE_IS_CABLE) return -EOPNOTSUPP; @@ -536,7 +538,7 @@ static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulatio return 0; } -static fe_modulation_t dst_get_modulation(struct dst_state *state) +static enum fe_modulation dst_get_modulation(struct dst_state *state) { return state->modulation; } @@ -1376,7 +1378,8 @@ static int dst_get_tuna(struct dst_state *state) return 1; } -static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage); +static int dst_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage); static int dst_write_tuna(struct dvb_frontend *fe) { @@ -1466,7 +1469,7 @@ static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd return dst_command(state, paket, 8); } -static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +static int dst_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage) { int need_cmd, retval = 0; struct dst_state *state = fe->demodulator_priv; @@ -1500,7 +1503,7 @@ static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) return retval; } -static int dst_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) +static int dst_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone) { struct dst_state *state = fe->demodulator_priv; @@ -1525,7 +1528,7 @@ static int dst_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) return dst_tone_power_cmd(state); } -static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd) +static int dst_send_burst(struct dvb_frontend *fe, enum fe_sec_mini_cmd minicmd) { struct dst_state *state = fe->demodulator_priv; @@ -1575,7 +1578,7 @@ static int bt8xx_dst_init(struct dvb_frontend *fe) return 0; } -static int dst_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int dst_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct dst_state *state = fe->demodulator_priv; @@ -1646,7 +1649,7 @@ static int dst_tune_frontend(struct dvb_frontend* fe, bool re_tune, unsigned int mode_flags, unsigned int *delay, - fe_status_t *status) + enum fe_status *status) { struct dst_state *state = fe->demodulator_priv; struct dtv_frontend_properties *p = &fe->dtv_property_cache; diff --git a/drivers/media/pci/bt8xx/dst_common.h b/drivers/media/pci/bt8xx/dst_common.h index d70d98f1a571..6a2cfdd44e3e 100644 --- a/drivers/media/pci/bt8xx/dst_common.h +++ b/drivers/media/pci/bt8xx/dst_common.h @@ -113,11 +113,11 @@ struct dst_state { u8 dst_type; u32 type_flags; u32 frequency; /* intermediate frequency in kHz for QPSK */ - fe_spectral_inversion_t inversion; + enum fe_spectral_inversion inversion; u32 symbol_rate; /* symbol rate in Symbols per second */ - fe_code_rate_t fec; - fe_sec_voltage_t voltage; - fe_sec_tone_mode_t tone; + enum fe_code_rate fec; + enum fe_sec_voltage voltage; + enum fe_sec_tone_mode tone; u32 decode_freq; u8 decode_lock; u16 decode_strength; @@ -127,8 +127,8 @@ struct dst_state { u32 bandwidth; u32 dst_hw_cap; u8 dst_fw_version; - fe_sec_mini_cmd_t minicmd; - fe_modulation_t modulation; + enum fe_sec_mini_cmd minicmd; + enum fe_modulation modulation; u8 messages[256]; u8 mac_address[8]; u8 fw_version[8]; diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 9f377ad5e845..a77c2d3b50fb 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -572,7 +572,8 @@ static struct stb6100_config prof_8000_stb6100_config = { .refclock = 27000000, }; -static int p8000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +static int p8000_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { struct cx23885_tsport *port = fe->dvb->priv; struct cx23885_dev *dev = port->dev; @@ -587,7 +588,7 @@ static int p8000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) } static int dvbsky_t9580_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) + enum fe_sec_voltage voltage) { struct cx23885_tsport *port = fe->dvb->priv; struct cx23885_dev *dev = port->dev; @@ -616,7 +617,7 @@ static int dvbsky_t9580_set_voltage(struct dvb_frontend *fe, } static int dvbsky_s952_portc_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) + enum fe_sec_voltage voltage) { struct cx23885_tsport *port = fe->dvb->priv; struct cx23885_dev *dev = port->dev; @@ -1186,7 +1187,8 @@ static int dvb_register(struct cx23885_tsport *port) struct i2c_client *client_demod = NULL, *client_tuner = NULL; struct i2c_client *client_sec = NULL; const struct m88ds3103_config *p_m88ds3103_config = NULL; - int (*p_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage) = NULL; + int (*p_set_voltage)(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) = NULL; int mfe_shared = 0; /* bus not shared by default */ int ret; diff --git a/drivers/media/pci/cx23885/cx23885-f300.c b/drivers/media/pci/cx23885/cx23885-f300.c index 6f817d8732da..a6c45eb0a105 100644 --- a/drivers/media/pci/cx23885/cx23885-f300.c +++ b/drivers/media/pci/cx23885/cx23885-f300.c @@ -144,7 +144,7 @@ static u8 f300_xfer(struct dvb_frontend *fe, u8 *buf) return ret; } -int f300_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +int f300_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage) { u8 buf[16]; diff --git a/drivers/media/pci/cx23885/cx23885-f300.h b/drivers/media/pci/cx23885/cx23885-f300.h index e73344c94963..be14d7de7cd8 100644 --- a/drivers/media/pci/cx23885/cx23885-f300.h +++ b/drivers/media/pci/cx23885/cx23885-f300.h @@ -1,2 +1,2 @@ extern int f300_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage); + enum fe_sec_voltage voltage); diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h index 81e25194986b..027ead438194 100644 --- a/drivers/media/pci/cx23885/cx23885.h +++ b/drivers/media/pci/cx23885/cx23885.h @@ -309,7 +309,7 @@ struct cx23885_tsport { int (*set_frontend)(struct dvb_frontend *fe); int (*fe_set_voltage)(struct dvb_frontend *fe, - fe_sec_voltage_t voltage); + enum fe_sec_voltage voltage); }; struct cx23885_kernel_ir { diff --git a/drivers/media/pci/cx88/cx88-dvb.c b/drivers/media/pci/cx88/cx88-dvb.c index 1b2ed238cdb6..9dfa5ee32a8f 100644 --- a/drivers/media/pci/cx88/cx88-dvb.c +++ b/drivers/media/pci/cx88/cx88-dvb.c @@ -449,7 +449,7 @@ static int cx24123_set_ts_param(struct dvb_frontend* fe, } static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe, - fe_sec_voltage_t voltage) + enum fe_sec_voltage voltage) { struct cx8802_dev *dev= fe->dvb->priv; struct cx88_core *core = dev->core; @@ -465,7 +465,7 @@ static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe, } static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) + enum fe_sec_voltage voltage) { struct cx8802_dev *dev= fe->dvb->priv; struct cx88_core *core = dev->core; @@ -481,7 +481,7 @@ static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe, } static int tevii_dvbs_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) + enum fe_sec_voltage voltage) { struct cx8802_dev *dev= fe->dvb->priv; struct cx88_core *core = dev->core; @@ -505,7 +505,7 @@ static int tevii_dvbs_set_voltage(struct dvb_frontend *fe, } static int vp1027_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) + enum fe_sec_voltage voltage) { struct cx8802_dev *dev = fe->dvb->priv; struct cx88_core *core = dev->core; @@ -897,7 +897,7 @@ static int samsung_smt_7020_tuner_set_params(struct dvb_frontend *fe) } static int samsung_smt_7020_set_tone(struct dvb_frontend *fe, - fe_sec_tone_mode_t tone) + enum fe_sec_tone_mode tone) { struct cx8802_dev *dev = fe->dvb->priv; struct cx88_core *core = dev->core; @@ -919,7 +919,7 @@ static int samsung_smt_7020_set_tone(struct dvb_frontend *fe, } static int samsung_smt_7020_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) + enum fe_sec_voltage voltage) { struct cx8802_dev *dev = fe->dvb->priv; struct cx88_core *core = dev->core; diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h index e75547827c52..785fe2e0d702 100644 --- a/drivers/media/pci/cx88/cx88.h +++ b/drivers/media/pci/cx88/cx88.h @@ -375,9 +375,10 @@ struct cx88_core { /* config info -- dvb */ #if IS_ENABLED(CONFIG_VIDEO_CX88_DVB) - int (*prev_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage); + int (*prev_set_voltage)(struct dvb_frontend *fe, + enum fe_sec_voltage voltage); #endif - void (*gate_ctrl)(struct cx88_core *core, int open); + void (*gate_ctrl)(struct cx88_core *core, int open); /* state info */ struct task_struct *kthread; diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c index ed11716731e9..88915fb87e80 100644 --- a/drivers/media/pci/dm1105/dm1105.c +++ b/drivers/media/pci/dm1105/dm1105.c @@ -591,7 +591,8 @@ static inline struct dm1105_dev *frontend_to_dm1105_dev(struct dvb_frontend *fe) return container_of(fe->dvb, struct dm1105_dev, dvb_adapter); } -static int dm1105_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +static int dm1105_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { struct dm1105_dev *dev = frontend_to_dm1105_dev(fe); diff --git a/drivers/media/pci/mantis/mantis_vp1034.c b/drivers/media/pci/mantis/mantis_vp1034.c index 7c1bd167225c..3b1928594b12 100644 --- a/drivers/media/pci/mantis/mantis_vp1034.c +++ b/drivers/media/pci/mantis/mantis_vp1034.c @@ -44,7 +44,7 @@ static struct mb86a16_config vp1034_mb86a16_config = { #define MANTIS_MODEL_NAME "VP-1034" #define MANTIS_DEV_TYPE "DVB-S/DSS" -int vp1034_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +int vp1034_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage) { struct mantis_pci *mantis = fe->dvb->priv; diff --git a/drivers/media/pci/mantis/mantis_vp1034.h b/drivers/media/pci/mantis/mantis_vp1034.h index 323f38ef8e3d..764b1c66ea1b 100644 --- a/drivers/media/pci/mantis/mantis_vp1034.h +++ b/drivers/media/pci/mantis/mantis_vp1034.h @@ -28,6 +28,7 @@ #define MANTIS_VP_1034_DVB_S 0x0014 extern struct mantis_hwconfig vp1034_config; -extern int vp1034_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage); +extern int vp1034_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage); #endif /* __MANTIS_VP1034_H */ diff --git a/drivers/media/pci/ngene/ngene.h b/drivers/media/pci/ngene/ngene.h index 51e2fbd18b1b..fa30930d7047 100644 --- a/drivers/media/pci/ngene/ngene.h +++ b/drivers/media/pci/ngene/ngene.h @@ -682,7 +682,7 @@ struct ngene_channel { int AudioDTOUpdated; u32 AudioDTOValue; - int (*set_tone)(struct dvb_frontend *, fe_sec_tone_mode_t); + int (*set_tone)(struct dvb_frontend *, enum fe_sec_tone_mode); u8 lnbh; /* stuff from analog driver */ diff --git a/drivers/media/pci/pt1/pt1.c b/drivers/media/pci/pt1/pt1.c index acc35b42e53c..e7e4428109c3 100644 --- a/drivers/media/pci/pt1/pt1.c +++ b/drivers/media/pci/pt1/pt1.c @@ -101,11 +101,11 @@ struct pt1_adapter { struct dmxdev dmxdev; struct dvb_frontend *fe; int (*orig_set_voltage)(struct dvb_frontend *fe, - fe_sec_voltage_t voltage); + enum fe_sec_voltage voltage); int (*orig_sleep)(struct dvb_frontend *fe); int (*orig_init)(struct dvb_frontend *fe); - fe_sec_voltage_t voltage; + enum fe_sec_voltage voltage; int sleep; }; @@ -575,7 +575,7 @@ pt1_update_power(struct pt1 *pt1) mutex_unlock(&pt1->lock); } -static int pt1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +static int pt1_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage) { struct pt1_adapter *adap; diff --git a/drivers/media/pci/pt1/va1j5jf8007s.c b/drivers/media/pci/pt1/va1j5jf8007s.c index 1b637b74ef58..d0e70dc0e16f 100644 --- a/drivers/media/pci/pt1/va1j5jf8007s.c +++ b/drivers/media/pci/pt1/va1j5jf8007s.c @@ -108,7 +108,7 @@ static int va1j5jf8007s_get_frontend_algo(struct dvb_frontend *fe) } static int -va1j5jf8007s_read_status(struct dvb_frontend *fe, fe_status_t *status) +va1j5jf8007s_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct va1j5jf8007s_state *state; @@ -387,7 +387,7 @@ static int va1j5jf8007s_tune(struct dvb_frontend *fe, bool re_tune, unsigned int mode_flags, unsigned int *delay, - fe_status_t *status) + enum fe_status *status) { struct va1j5jf8007s_state *state; int ret; diff --git a/drivers/media/pci/pt1/va1j5jf8007t.c b/drivers/media/pci/pt1/va1j5jf8007t.c index 2db15159d514..0268f20b8097 100644 --- a/drivers/media/pci/pt1/va1j5jf8007t.c +++ b/drivers/media/pci/pt1/va1j5jf8007t.c @@ -98,7 +98,7 @@ static int va1j5jf8007t_get_frontend_algo(struct dvb_frontend *fe) } static int -va1j5jf8007t_read_status(struct dvb_frontend *fe, fe_status_t *status) +va1j5jf8007t_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct va1j5jf8007t_state *state; @@ -266,7 +266,7 @@ static int va1j5jf8007t_tune(struct dvb_frontend *fe, bool re_tune, unsigned int mode_flags, unsigned int *delay, - fe_status_t *status) + enum fe_status *status) { struct va1j5jf8007t_state *state; int ret; diff --git a/drivers/media/pci/pt3/pt3.c b/drivers/media/pci/pt3/pt3.c index 7a37e8fe2ee2..0d2e2b217121 100644 --- a/drivers/media/pci/pt3/pt3.c +++ b/drivers/media/pci/pt3/pt3.c @@ -188,7 +188,7 @@ static int pt3_set_lna(struct dvb_frontend *fe) return ret; } -static int pt3_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt) +static int pt3_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage volt) { struct pt3_adapter *adap; struct pt3_board *pt3; diff --git a/drivers/media/pci/saa7134/saa7134-dvb.c b/drivers/media/pci/saa7134/saa7134-dvb.c index d47fb22e12f2..101ba8729416 100644 --- a/drivers/media/pci/saa7134/saa7134-dvb.c +++ b/drivers/media/pci/saa7134/saa7134-dvb.c @@ -987,7 +987,8 @@ static struct tda10086_config sd1878_4m = { * special case: lnb supply is connected to the gated i2c */ -static int md8800_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +static int md8800_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { int res = -EIO; struct saa7134_dev *dev = fe->dvb->priv; @@ -1013,7 +1014,8 @@ static int md8800_set_high_voltage(struct dvb_frontend *fe, long arg) return res; }; -static int md8800_set_voltage2(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +static int md8800_set_voltage2(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { struct saa7134_dev *dev = fe->dvb->priv; u8 wbuf[2] = { 0x1f, 00 }; diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h index 6fec01711680..f682ba9b34a7 100644 --- a/drivers/media/pci/saa7134/saa7134.h +++ b/drivers/media/pci/saa7134/saa7134.h @@ -656,7 +656,8 @@ struct saa7134_dev { /* SAA7134_MPEG_DVB only */ struct vb2_dvb_frontends frontends; int (*original_demod_sleep)(struct dvb_frontend *fe); - int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage); + int (*original_set_voltage)(struct dvb_frontend *fe, + enum fe_sec_voltage voltage); int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg); #endif void (*gate_ctrl)(struct saa7134_dev *dev, int open); diff --git a/drivers/media/pci/ttpci/av7110.c b/drivers/media/pci/ttpci/av7110.c index 45199a12b9d9..3f24fce74fc1 100644 --- a/drivers/media/pci/ttpci/av7110.c +++ b/drivers/media/pci/ttpci/av7110.c @@ -1172,7 +1172,7 @@ static int dvb_get_stc(struct dmx_demux *demux, unsigned int num, ******************************************************************************/ -static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) +static int av7110_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone) { struct av7110* av7110 = fe->dvb->priv; @@ -1197,7 +1197,7 @@ static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe, } static int av7110_diseqc_send_burst(struct dvb_frontend* fe, - fe_sec_mini_cmd_t minicmd) + enum fe_sec_mini_cmd minicmd) { struct av7110* av7110 = fe->dvb->priv; @@ -1946,7 +1946,7 @@ static struct l64781_config grundig_29504_401_config = { -static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status) +static int av7110_fe_lock_fix(struct av7110 *av7110, enum fe_status status) { int ret = 0; int synced = (status & FE_HAS_LOCK) ? 1 : 0; @@ -2008,7 +2008,8 @@ static int av7110_fe_init(struct dvb_frontend* fe) return ret; } -static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status) +static int av7110_fe_read_status(struct dvb_frontend *fe, + enum fe_status *status) { struct av7110* av7110 = fe->dvb->priv; @@ -2043,7 +2044,8 @@ static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe, return ret; } -static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) +static int av7110_fe_diseqc_send_burst(struct dvb_frontend *fe, + enum fe_sec_mini_cmd minicmd) { struct av7110* av7110 = fe->dvb->priv; @@ -2055,7 +2057,8 @@ static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_ return ret; } -static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) +static int av7110_fe_set_tone(struct dvb_frontend *fe, + enum fe_sec_tone_mode tone) { struct av7110* av7110 = fe->dvb->priv; @@ -2067,7 +2070,8 @@ static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) return ret; } -static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) +static int av7110_fe_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { struct av7110* av7110 = fe->dvb->priv; diff --git a/drivers/media/pci/ttpci/av7110.h b/drivers/media/pci/ttpci/av7110.h index 835635b0c712..3a55927edb95 100644 --- a/drivers/media/pci/ttpci/av7110.h +++ b/drivers/media/pci/ttpci/av7110.h @@ -269,25 +269,30 @@ struct av7110 { unsigned long size_root; struct dvb_frontend* fe; - fe_status_t fe_status; + enum fe_status fe_status; struct mutex ioctl_mutex; /* crash recovery */ void (*recover)(struct av7110* av7110); - fe_sec_voltage_t saved_voltage; - fe_sec_tone_mode_t saved_tone; + enum fe_sec_voltage saved_voltage; + enum fe_sec_tone_mode saved_tone; struct dvb_diseqc_master_cmd saved_master_cmd; - fe_sec_mini_cmd_t saved_minicmd; + enum fe_sec_mini_cmd saved_minicmd; int (*fe_init)(struct dvb_frontend* fe); - int (*fe_read_status)(struct dvb_frontend* fe, fe_status_t* status); - int (*fe_diseqc_reset_overload)(struct dvb_frontend* fe); - int (*fe_diseqc_send_master_cmd)(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd); - int (*fe_diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd); - int (*fe_set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone); - int (*fe_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); - int (*fe_dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd); + int (*fe_read_status)(struct dvb_frontend *fe, enum fe_status *status); + int (*fe_diseqc_reset_overload)(struct dvb_frontend *fe); + int (*fe_diseqc_send_master_cmd)(struct dvb_frontend *fe, + struct dvb_diseqc_master_cmd *cmd); + int (*fe_diseqc_send_burst)(struct dvb_frontend *fe, + enum fe_sec_mini_cmd minicmd); + int (*fe_set_tone)(struct dvb_frontend *fe, + enum fe_sec_tone_mode tone); + int (*fe_set_voltage)(struct dvb_frontend *fe, + enum fe_sec_voltage voltage); + int (*fe_dishnetwork_send_legacy_command)(struct dvb_frontend *fe, + unsigned long cmd); int (*fe_set_frontend)(struct dvb_frontend *fe); }; diff --git a/drivers/media/pci/ttpci/budget-core.c b/drivers/media/pci/ttpci/budget-core.c index 23e05499b509..e9674b40007c 100644 --- a/drivers/media/pci/ttpci/budget-core.c +++ b/drivers/media/pci/ttpci/budget-core.c @@ -161,7 +161,8 @@ static int start_ts_capture(struct budget *budget) return 0; } -static int budget_read_fe_status(struct dvb_frontend *fe, fe_status_t *status) +static int budget_read_fe_status(struct dvb_frontend *fe, + enum fe_status *status) { struct budget *budget = (struct budget *) fe->dvb->priv; int synced; diff --git a/drivers/media/pci/ttpci/budget-patch.c b/drivers/media/pci/ttpci/budget-patch.c index a4d8867e1d7b..b5b65962ce8f 100644 --- a/drivers/media/pci/ttpci/budget-patch.c +++ b/drivers/media/pci/ttpci/budget-patch.c @@ -128,9 +128,9 @@ static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long return 0; } -/* shamelessly copy/pasted from budget.c -*/ -static int budget_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) +/* shamelessly copy/pasted from budget.c */ +static int budget_set_tone(struct dvb_frontend *fe, + enum fe_sec_tone_mode tone) { struct budget* budget = (struct budget*) fe->dvb->priv; @@ -159,7 +159,8 @@ static int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_dis return 0; } -static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) +static int budget_diseqc_send_burst(struct dvb_frontend *fe, + enum fe_sec_mini_cmd minicmd) { struct budget* budget = (struct budget*) fe->dvb->priv; @@ -223,7 +224,8 @@ static int av7110_send_diseqc_msg(struct budget_patch *budget, int len, u8 *msg, return 0; } -static int budget_patch_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) +static int budget_patch_set_tone(struct dvb_frontend *fe, + enum fe_sec_tone_mode tone) { struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; @@ -252,7 +254,8 @@ static int budget_patch_diseqc_send_master_cmd(struct dvb_frontend* fe, struct d return 0; } -static int budget_patch_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) +static int budget_patch_diseqc_send_burst(struct dvb_frontend *fe, + enum fe_sec_mini_cmd minicmd) { struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; diff --git a/drivers/media/pci/ttpci/budget.c b/drivers/media/pci/ttpci/budget.c index 6ccc48833fd8..99972beca262 100644 --- a/drivers/media/pci/ttpci/budget.c +++ b/drivers/media/pci/ttpci/budget.c @@ -132,7 +132,8 @@ static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long * Voltage must be set here. * GPIO 1: LNBP EN, GPIO 2: LNBP VSEL */ -static int SetVoltage_Activy (struct budget *budget, fe_sec_voltage_t voltage) +static int SetVoltage_Activy(struct budget *budget, + enum fe_sec_voltage voltage) { struct saa7146_dev *dev=budget->dev; @@ -157,14 +158,16 @@ static int SetVoltage_Activy (struct budget *budget, fe_sec_voltage_t voltage) return 0; } -static int siemens_budget_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) +static int siemens_budget_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { struct budget* budget = (struct budget*) fe->dvb->priv; return SetVoltage_Activy (budget, voltage); } -static int budget_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) +static int budget_set_tone(struct dvb_frontend *fe, + enum fe_sec_tone_mode tone) { struct budget* budget = (struct budget*) fe->dvb->priv; @@ -193,7 +196,8 @@ static int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_dis return 0; } -static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) +static int budget_diseqc_send_burst(struct dvb_frontend *fe, + enum fe_sec_mini_cmd minicmd) { struct budget* budget = (struct budget*) fe->dvb->priv; diff --git a/drivers/media/pci/ttpci/budget.h b/drivers/media/pci/ttpci/budget.h index 3d8a806c20bb..1ccbe1a49a4b 100644 --- a/drivers/media/pci/ttpci/budget.h +++ b/drivers/media/pci/ttpci/budget.h @@ -72,7 +72,7 @@ struct budget { struct dvb_adapter dvb_adapter; struct dvb_frontend *dvb_frontend; - int (*read_fe_status)(struct dvb_frontend *fe, fe_status_t *status); + int (*read_fe_status)(struct dvb_frontend *fe, enum fe_status *status); int fe_synced; void *priv; diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c b/drivers/media/usb/dvb-usb-v2/af9015.c index 16c0b7d4f8e7..95a7388e89d4 100644 --- a/drivers/media/usb/dvb-usb-v2/af9015.c +++ b/drivers/media/usb/dvb-usb-v2/af9015.c @@ -641,7 +641,7 @@ static int af9015_af9013_set_frontend(struct dvb_frontend *fe) /* override demod callbacks for resource locking */ static int af9015_af9013_read_status(struct dvb_frontend *fe, - fe_status_t *status) + enum fe_status *status) { int ret; struct af9015_state *state = fe_to_priv(fe); diff --git a/drivers/media/usb/dvb-usb-v2/af9015.h b/drivers/media/usb/dvb-usb-v2/af9015.h index 3a6f3ad1eadb..1db1bb0d57bc 100644 --- a/drivers/media/usb/dvb-usb-v2/af9015.h +++ b/drivers/media/usb/dvb-usb-v2/af9015.h @@ -133,7 +133,7 @@ struct af9015_state { /* for demod callback override */ int (*set_frontend[2]) (struct dvb_frontend *fe); - int (*read_status[2]) (struct dvb_frontend *fe, fe_status_t *status); + int (*read_status[2]) (struct dvb_frontend *fe, enum fe_status *status); int (*init[2]) (struct dvb_frontend *fe); int (*sleep[2]) (struct dvb_frontend *fe); int (*tuner_init[2]) (struct dvb_frontend *fe); diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c index 57c8c2db9f2d..5cc01bbdede9 100644 --- a/drivers/media/usb/dvb-usb-v2/dvbsky.c +++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c @@ -45,9 +45,9 @@ struct dvbsky_state { /* fe hook functions*/ int (*fe_set_voltage)(struct dvb_frontend *fe, - fe_sec_voltage_t voltage); + enum fe_sec_voltage voltage); int (*fe_read_status)(struct dvb_frontend *fe, - fe_status_t *status); + enum fe_status *status); }; static int dvbsky_usb_generic_rw(struct dvb_usb_device *d, @@ -237,7 +237,7 @@ static int dvbsky_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) #endif static int dvbsky_usb_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) + enum fe_sec_voltage voltage) { struct dvb_usb_device *d = fe_to_d(fe); struct dvbsky_state *state = d_to_priv(d); @@ -277,7 +277,8 @@ static int dvbsky_read_mac_addr(struct dvb_usb_adapter *adap, u8 mac[6]) return 0; } -static int dvbsky_usb_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int dvbsky_usb_read_status(struct dvb_frontend *fe, + enum fe_status *status) { struct dvb_usb_device *d = fe_to_d(fe); struct dvbsky_state *state = d_to_priv(d); @@ -368,7 +369,7 @@ fail_attach: } static int dvbsky_usb_ci_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) + enum fe_sec_voltage voltage) { struct dvb_usb_device *d = fe_to_d(fe); struct dvbsky_state *state = d_to_priv(d); diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c index 5de6f7c04d09..1b6ca42ad116 100644 --- a/drivers/media/usb/dvb-usb-v2/lmedm04.c +++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c @@ -126,7 +126,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); struct lme2510_state { unsigned long int_urb_due; - fe_status_t lock_status; + enum fe_status lock_status; u8 id; u8 tuner_config; u8 signal_level; @@ -144,12 +144,12 @@ struct lme2510_state { struct urb *lme_urb; void *usb_buffer; /* Frontend original calls */ - int (*fe_read_status)(struct dvb_frontend *, fe_status_t *); + int (*fe_read_status)(struct dvb_frontend *, enum fe_status *); int (*fe_read_signal_strength)(struct dvb_frontend *, u16 *); int (*fe_read_snr)(struct dvb_frontend *, u16 *); int (*fe_read_ber)(struct dvb_frontend *, u32 *); int (*fe_read_ucblocks)(struct dvb_frontend *, u32 *); - int (*fe_set_voltage)(struct dvb_frontend *, fe_sec_voltage_t); + int (*fe_set_voltage)(struct dvb_frontend *, enum fe_sec_voltage); u8 dvb_usb_lme2510_firmware; }; @@ -802,7 +802,7 @@ static struct ts2020_config ts2020_config = { }; static int dm04_lme2510_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) + enum fe_sec_voltage voltage) { struct dvb_usb_device *d = fe_to_d(fe); struct lme2510_state *st = fe_to_priv(fe); @@ -837,7 +837,7 @@ static int dm04_lme2510_set_voltage(struct dvb_frontend *fe, return (ret < 0) ? -ENODEV : 0; } -static int dm04_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int dm04_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct dvb_usb_device *d = fe_to_d(fe); struct lme2510_state *st = d->priv; diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c index ecefa5c477fa..ea3753653368 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c @@ -72,7 +72,7 @@ int mxl111sf_demod_program_regs(struct mxl111sf_demod_state *state, static int mxl1x1sf_demod_get_tps_code_rate(struct mxl111sf_demod_state *state, - fe_code_rate_t *code_rate) + enum fe_code_rate *code_rate) { u8 val; int ret = mxl111sf_demod_read_reg(state, V6_CODE_RATE_TPS_REG, &val); @@ -103,7 +103,7 @@ fail: static int mxl1x1sf_demod_get_tps_modulation(struct mxl111sf_demod_state *state, - fe_modulation_t *modulation) + enum fe_modulation *modulation) { u8 val; int ret = mxl111sf_demod_read_reg(state, V6_MODORDER_TPS_REG, &val); @@ -128,7 +128,7 @@ fail: static int mxl1x1sf_demod_get_tps_guard_fft_mode(struct mxl111sf_demod_state *state, - fe_transmit_mode_t *fft_mode) + enum fe_transmit_mode *fft_mode) { u8 val; int ret = mxl111sf_demod_read_reg(state, V6_MODE_TPS_REG, &val); @@ -153,7 +153,7 @@ fail: static int mxl1x1sf_demod_get_tps_guard_interval(struct mxl111sf_demod_state *state, - fe_guard_interval_t *guard) + enum fe_guard_interval *guard) { u8 val; int ret = mxl111sf_demod_read_reg(state, V6_CP_TPS_REG, &val); @@ -181,7 +181,7 @@ fail: static int mxl1x1sf_demod_get_tps_hierarchy(struct mxl111sf_demod_state *state, - fe_hierarchy_t *hierarchy) + enum fe_hierarchy *hierarchy) { u8 val; int ret = mxl111sf_demod_read_reg(state, V6_TPS_HIERACHY_REG, &val); @@ -441,7 +441,7 @@ fail: } static int mxl111sf_demod_read_status(struct dvb_frontend *fe, - fe_status_t *status) + enum fe_status *status) { struct mxl111sf_demod_state *state = fe->demodulator_priv; int ret, locked, cr_lock, sync_lock, fec_lock; @@ -480,7 +480,7 @@ static int mxl111sf_demod_read_signal_strength(struct dvb_frontend *fe, u16 *signal_strength) { struct mxl111sf_demod_state *state = fe->demodulator_priv; - fe_modulation_t modulation; + enum fe_modulation modulation; u16 snr; mxl111sf_demod_calc_snr(state, &snr); diff --git a/drivers/media/usb/dvb-usb/af9005-fe.c b/drivers/media/usb/dvb-usb/af9005-fe.c index 6e84a546dfdc..ac97075d75f7 100644 --- a/drivers/media/usb/dvb-usb/af9005-fe.c +++ b/drivers/media/usb/dvb-usb/af9005-fe.c @@ -29,7 +29,7 @@ struct af9005_fe_state { struct dvb_usb_device *d; - fe_status_t stat; + enum fe_status stat; /* retraining parameters */ u32 original_fcw; @@ -437,7 +437,8 @@ static int af9005_fe_refresh_state(struct dvb_frontend *fe) return 0; } -static int af9005_fe_read_status(struct dvb_frontend *fe, fe_status_t * stat) +static int af9005_fe_read_status(struct dvb_frontend *fe, + enum fe_status *stat) { struct af9005_fe_state *state = fe->demodulator_priv; u8 temp; diff --git a/drivers/media/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c index 0df52ab32a7b..92e47d6c3ee3 100644 --- a/drivers/media/usb/dvb-usb/az6027.c +++ b/drivers/media/usb/dvb-usb/az6027.c @@ -778,7 +778,8 @@ static int az6027_read_mac_addr(struct dvb_usb_device *d, u8 mac[6]) } */ -static int az6027_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +static int az6027_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { u8 buf; diff --git a/drivers/media/usb/dvb-usb/cinergyT2-fe.c b/drivers/media/usb/dvb-usb/cinergyT2-fe.c index c890fe46acd3..b3ec743a7a2e 100644 --- a/drivers/media/usb/dvb-usb/cinergyT2-fe.c +++ b/drivers/media/usb/dvb-usb/cinergyT2-fe.c @@ -142,7 +142,7 @@ struct cinergyt2_fe_state { }; static int cinergyt2_fe_read_status(struct dvb_frontend *fe, - fe_status_t *status) + enum fe_status *status) { struct cinergyt2_fe_state *state = fe->demodulator_priv; struct dvbt_get_status_msg result; diff --git a/drivers/media/usb/dvb-usb/dib0700.h b/drivers/media/usb/dvb-usb/dib0700.h index 927617d95616..8fd8f5b489d2 100644 --- a/drivers/media/usb/dvb-usb/dib0700.h +++ b/drivers/media/usb/dvb-usb/dib0700.h @@ -48,7 +48,7 @@ struct dib0700_state { u8 disable_streaming_master_mode; u32 fw_version; u32 nb_packet_buffer_size; - int (*read_status)(struct dvb_frontend *, fe_status_t *); + int (*read_status)(struct dvb_frontend *, enum fe_status *); int (*sleep)(struct dvb_frontend* fe); u8 buf[255]; }; diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c index 5a3dbb8c7658..7ed49646a699 100644 --- a/drivers/media/usb/dvb-usb/dib0700_devices.c +++ b/drivers/media/usb/dvb-usb/dib0700_devices.c @@ -3309,7 +3309,7 @@ static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap) } static int novatd_read_status_override(struct dvb_frontend *fe, - fe_status_t *stat) + enum fe_status *stat) { struct dvb_usb_adapter *adap = fe->dvb->priv; struct dvb_usb_device *dev = adap->dev; diff --git a/drivers/media/usb/dvb-usb/dtt200u-fe.c b/drivers/media/usb/dvb-usb/dtt200u-fe.c index 3d81daa49172..8637ad1be6be 100644 --- a/drivers/media/usb/dvb-usb/dtt200u-fe.c +++ b/drivers/media/usb/dvb-usb/dtt200u-fe.c @@ -14,13 +14,14 @@ struct dtt200u_fe_state { struct dvb_usb_device *d; - fe_status_t stat; + enum fe_status stat; struct dtv_frontend_properties fep; struct dvb_frontend frontend; }; -static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat) +static int dtt200u_fe_read_status(struct dvb_frontend *fe, + enum fe_status *stat) { struct dtt200u_fe_state *state = fe->demodulator_priv; u8 st = GET_TUNE_STATUS, b[3]; @@ -105,7 +106,7 @@ static int dtt200u_fe_set_frontend(struct dvb_frontend *fe) struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct dtt200u_fe_state *state = fe->demodulator_priv; int i; - fe_status_t st; + enum fe_status st; u16 freq = fep->frequency / 250000; u8 bwbuf[2] = { SET_BANDWIDTH, 0 },freqbuf[3] = { SET_RF_FREQ, 0, 0 }; diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c index c2632bc9e530..14ef25dc6cd3 100644 --- a/drivers/media/usb/dvb-usb/dw2102.c +++ b/drivers/media/usb/dvb-usb/dw2102.c @@ -121,9 +121,9 @@ struct dw2102_state { struct i2c_client *i2c_client_tuner; /* fe hook functions*/ - int (*old_set_voltage)(struct dvb_frontend *f, fe_sec_voltage_t v); + int (*old_set_voltage)(struct dvb_frontend *f, enum fe_sec_voltage v); int (*fe_read_status)(struct dvb_frontend *fe, - fe_status_t *status); + enum fe_status *status); }; /* debug */ @@ -949,7 +949,8 @@ static int su3000_identify_state(struct usb_device *udev, return 0; } -static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +static int dw210x_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { static u8 command_13v[] = {0x00, 0x01}; static u8 command_18v[] = {0x01, 0x01}; @@ -973,7 +974,8 @@ static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) return 0; } -static int s660_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +static int s660_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { struct dvb_usb_adapter *d = (struct dvb_usb_adapter *)(fe->dvb->priv); @@ -1004,7 +1006,8 @@ static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon) i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1); } -static int tt_s2_4600_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int tt_s2_4600_read_status(struct dvb_frontend *fe, + enum fe_status *status) { struct dvb_usb_adapter *d = (struct dvb_usb_adapter *)(fe->dvb->priv); diff --git a/drivers/media/usb/dvb-usb/friio-fe.c b/drivers/media/usb/dvb-usb/friio-fe.c index d56f927fc31a..8ec92fbeabad 100644 --- a/drivers/media/usb/dvb-usb/friio-fe.c +++ b/drivers/media/usb/dvb-usb/friio-fe.c @@ -210,7 +210,8 @@ error: return -EREMOTEIO; } -static int jdvbt90502_read_status(struct dvb_frontend *fe, fe_status_t *state) +static int jdvbt90502_read_status(struct dvb_frontend *fe, + enum fe_status *state) { u8 result; int ret; diff --git a/drivers/media/usb/dvb-usb/gp8psk-fe.c b/drivers/media/usb/dvb-usb/gp8psk-fe.c index 67957dd99ede..db6eb79cde07 100644 --- a/drivers/media/usb/dvb-usb/gp8psk-fe.c +++ b/drivers/media/usb/dvb-usb/gp8psk-fe.c @@ -51,7 +51,8 @@ static int gp8psk_fe_update_status(struct gp8psk_fe_state *st) return 0; } -static int gp8psk_fe_read_status(struct dvb_frontend* fe, fe_status_t *status) +static int gp8psk_fe_read_status(struct dvb_frontend *fe, + enum fe_status *status) { struct gp8psk_fe_state *st = fe->demodulator_priv; gp8psk_fe_update_status(st); @@ -236,8 +237,8 @@ static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe, return 0; } -static int gp8psk_fe_send_diseqc_burst (struct dvb_frontend* fe, - fe_sec_mini_cmd_t burst) +static int gp8psk_fe_send_diseqc_burst(struct dvb_frontend *fe, + enum fe_sec_mini_cmd burst) { struct gp8psk_fe_state *st = fe->demodulator_priv; u8 cmd; @@ -254,7 +255,8 @@ static int gp8psk_fe_send_diseqc_burst (struct dvb_frontend* fe, return 0; } -static int gp8psk_fe_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) +static int gp8psk_fe_set_tone(struct dvb_frontend *fe, + enum fe_sec_tone_mode tone) { struct gp8psk_fe_state* state = fe->demodulator_priv; @@ -265,7 +267,8 @@ static int gp8psk_fe_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) return 0; } -static int gp8psk_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) +static int gp8psk_fe_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { struct gp8psk_fe_state* state = fe->demodulator_priv; diff --git a/drivers/media/usb/dvb-usb/opera1.c b/drivers/media/usb/dvb-usb/opera1.c index 14a2119912ba..2566d2f1c2ad 100644 --- a/drivers/media/usb/dvb-usb/opera1.c +++ b/drivers/media/usb/dvb-usb/opera1.c @@ -167,7 +167,8 @@ static struct i2c_algorithm opera1_i2c_algo = { .functionality = opera1_i2c_func, }; -static int opera1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +static int opera1_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { static u8 command_13v[1]={0x00}; static u8 command_18v[1]={0x01}; diff --git a/drivers/media/usb/dvb-usb/technisat-usb2.c b/drivers/media/usb/dvb-usb/technisat-usb2.c index 5801ae7f672a..03f334d3a8f4 100644 --- a/drivers/media/usb/dvb-usb/technisat-usb2.c +++ b/drivers/media/usb/dvb-usb/technisat-usb2.c @@ -453,7 +453,7 @@ static struct stv090x_config technisat_usb2_stv090x_config; /* frontend attach */ static int technisat_usb2_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) + enum fe_sec_voltage voltage) { int i; u8 gpio[3] = { 0 }; /* 0 = 2, 1 = 3, 2 = 4 */ diff --git a/drivers/media/usb/dvb-usb/vp702x-fe.c b/drivers/media/usb/dvb-usb/vp702x-fe.c index 5eab468dd904..d361a72ca0fa 100644 --- a/drivers/media/usb/dvb-usb/vp702x-fe.c +++ b/drivers/media/usb/dvb-usb/vp702x-fe.c @@ -26,8 +26,8 @@ struct vp702x_fe_state { struct dvb_frontend_ops ops; - fe_sec_voltage_t voltage; - fe_sec_tone_mode_t tone_mode; + enum fe_sec_voltage voltage; + enum fe_sec_tone_mode tone_mode; u8 lnb_buf[8]; @@ -72,7 +72,8 @@ static u8 vp702x_chksum(u8 *buf,int f, int count) return ~s+1; } -static int vp702x_fe_read_status(struct dvb_frontend* fe, fe_status_t *status) +static int vp702x_fe_read_status(struct dvb_frontend *fe, + enum fe_status *status) { struct vp702x_fe_state *st = fe->demodulator_priv; vp702x_fe_refresh_state(st); @@ -243,13 +244,15 @@ static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe, return 0; } -static int vp702x_fe_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) +static int vp702x_fe_send_diseqc_burst(struct dvb_frontend *fe, + enum fe_sec_mini_cmd burst) { deb_fe("%s\n",__func__); return 0; } -static int vp702x_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) +static int vp702x_fe_set_tone(struct dvb_frontend *fe, + enum fe_sec_tone_mode tone) { struct vp702x_fe_state *st = fe->demodulator_priv; struct vp702x_device_state *dst = st->d->priv; @@ -282,8 +285,8 @@ static int vp702x_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) return 0; } -static int vp702x_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t - voltage) +static int vp702x_fe_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { struct vp702x_fe_state *st = fe->demodulator_priv; struct vp702x_device_state *dst = st->d->priv; diff --git a/drivers/media/usb/dvb-usb/vp7045-fe.c b/drivers/media/usb/dvb-usb/vp7045-fe.c index b8825b18c003..e708afc6a57f 100644 --- a/drivers/media/usb/dvb-usb/vp7045-fe.c +++ b/drivers/media/usb/dvb-usb/vp7045-fe.c @@ -26,7 +26,8 @@ struct vp7045_fe_state { struct dvb_usb_device *d; }; -static int vp7045_fe_read_status(struct dvb_frontend* fe, fe_status_t *status) +static int vp7045_fe_read_status(struct dvb_frontend *fe, + enum fe_status *status) { struct vp7045_fe_state *state = fe->demodulator_priv; u8 s0 = vp7045_read_reg(state->d,0x00), diff --git a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c index cef7a00099ea..d52d4a8d39ad 100644 --- a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c @@ -111,8 +111,8 @@ struct ttusb { int last_filter; u8 c; /* transaction counter, wraps around... */ - fe_sec_tone_mode_t tone; - fe_sec_voltage_t voltage; + enum fe_sec_tone_mode tone; + enum fe_sec_voltage voltage; int mux_state; // 0..2 - MuxSyncWord, 3 - nMuxPacks, 4 - muxpack u8 mux_npacks; @@ -511,7 +511,8 @@ static int ttusb_update_lnb(struct ttusb *ttusb) return err; } -static int ttusb_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) +static int ttusb_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; @@ -520,7 +521,7 @@ static int ttusb_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) } #ifdef TTUSB_TONE -static int ttusb_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) +static int ttusb_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone) { struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; diff --git a/drivers/media/usb/ttusb-dec/ttusbdecfe.c b/drivers/media/usb/ttusb-dec/ttusbdecfe.c index 9c29552aedec..8781335ab92f 100644 --- a/drivers/media/usb/ttusb-dec/ttusbdecfe.c +++ b/drivers/media/usb/ttusb-dec/ttusbdecfe.c @@ -39,7 +39,7 @@ struct ttusbdecfe_state { static int ttusbdecfe_dvbs_read_status(struct dvb_frontend *fe, - fe_status_t *status) + enum fe_status *status) { *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK; @@ -48,7 +48,7 @@ static int ttusbdecfe_dvbs_read_status(struct dvb_frontend *fe, static int ttusbdecfe_dvbt_read_status(struct dvb_frontend *fe, - fe_status_t *status) + enum fe_status *status) { struct ttusbdecfe_state* state = fe->demodulator_priv; u8 b[] = { 0x00, 0x00, 0x00, 0x00, @@ -169,7 +169,8 @@ static int ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend* fe, struc } -static int ttusbdecfe_dvbs_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) +static int ttusbdecfe_dvbs_set_tone(struct dvb_frontend *fe, + enum fe_sec_tone_mode tone) { struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; @@ -179,7 +180,8 @@ static int ttusbdecfe_dvbs_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t } -static int ttusbdecfe_dvbs_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) +static int ttusbdecfe_dvbs_set_voltage(struct dvb_frontend *fe, + enum fe_sec_voltage voltage) { struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; diff --git a/drivers/staging/media/mn88472/mn88472.c b/drivers/staging/media/mn88472/mn88472.c index 6863c431c648..a8d45f44765c 100644 --- a/drivers/staging/media/mn88472/mn88472.c +++ b/drivers/staging/media/mn88472/mn88472.c @@ -218,7 +218,7 @@ err: return ret; } -static int mn88472_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int mn88472_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct i2c_client *client = fe->demodulator_priv; struct mn88472_dev *dev = i2c_get_clientdata(client); diff --git a/drivers/staging/media/mn88472/mn88472_priv.h b/drivers/staging/media/mn88472/mn88472_priv.h index 9ba8c8b3823e..1a0de9e46b66 100644 --- a/drivers/staging/media/mn88472/mn88472_priv.h +++ b/drivers/staging/media/mn88472/mn88472_priv.h @@ -29,7 +29,7 @@ struct mn88472_dev { struct regmap *regmap[3]; struct dvb_frontend fe; u16 i2c_wr_max; - fe_delivery_system_t delivery_system; + enum fe_delivery_system delivery_system; bool warm; /* FW running */ u32 xtal; int ts_mode; diff --git a/drivers/staging/media/mn88473/mn88473.c b/drivers/staging/media/mn88473/mn88473.c index 8b6736c70057..f9146a146d07 100644 --- a/drivers/staging/media/mn88473/mn88473.c +++ b/drivers/staging/media/mn88473/mn88473.c @@ -167,7 +167,7 @@ err: return ret; } -static int mn88473_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int mn88473_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct i2c_client *client = fe->demodulator_priv; struct mn88473_dev *dev = i2c_get_clientdata(client); diff --git a/drivers/staging/media/mn88473/mn88473_priv.h b/drivers/staging/media/mn88473/mn88473_priv.h index ef6f01323ac9..54beb4241ccf 100644 --- a/drivers/staging/media/mn88473/mn88473_priv.h +++ b/drivers/staging/media/mn88473/mn88473_priv.h @@ -29,7 +29,7 @@ struct mn88473_dev { struct regmap *regmap[3]; struct dvb_frontend fe; u16 i2c_wr_max; - fe_delivery_system_t delivery_system; + enum fe_delivery_system delivery_system; bool warm; /* FW running */ u32 xtal; }; diff --git a/include/uapi/linux/dvb/frontend.h b/include/uapi/linux/dvb/frontend.h index a36d802fae0c..7f829c92dd64 100644 --- a/include/uapi/linux/dvb/frontend.h +++ b/include/uapi/linux/dvb/frontend.h @@ -77,7 +77,7 @@ typedef enum fe_caps fe_caps_t; struct dvb_frontend_info { char name[128]; - fe_type_t type; /* DEPRECATED. Use DTV_ENUM_DELSYS instead */ + enum fe_type type; /* DEPRECATED. Use DTV_ENUM_DELSYS instead */ __u32 frequency_min; __u32 frequency_max; __u32 frequency_stepsize; @@ -86,7 +86,7 @@ struct dvb_frontend_info { __u32 symbol_rate_max; __u32 symbol_rate_tolerance; /* ppm */ __u32 notifier_delay; /* DEPRECATED */ - fe_caps_t caps; + enum fe_caps caps; }; -- cgit v1.2.3-59-g8ed1b From 28ffeebbb7bdc0dd7899286b63f3c359d43d0a1a Mon Sep 17 00:00:00 2001 From: Fabien Dessenne Date: Tue, 12 May 2015 13:02:10 -0300 Subject: [media] bdisp: 2D blitter driver using v4l2 mem2mem framework This v4l2 mem2mem driver is a 2D blitter for STMicroelectronics SoC. It uses the v4l2 mem2mem framework. The following features are supported and tested: - Color format conversion (RGB32, RGB24, RGB16, NV12, YUV420P) - Copy - Scale - Flip - Deinterlace - Wide (4K) picture support - Crop Signed-off-by: Fabien Dessenne Signed-off-by: Hans Verkuil [hans.verkuil@cisco.com: added missing slab.h include to bdisp-v4l2.c] Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/Kconfig | 10 + drivers/media/platform/Makefile | 2 + drivers/media/platform/sti/bdisp/Kconfig | 9 + drivers/media/platform/sti/bdisp/Makefile | 3 + drivers/media/platform/sti/bdisp/bdisp-filter.h | 346 ++++++ drivers/media/platform/sti/bdisp/bdisp-hw.c | 783 +++++++++++++ drivers/media/platform/sti/bdisp/bdisp-reg.h | 235 ++++ drivers/media/platform/sti/bdisp/bdisp-v4l2.c | 1405 +++++++++++++++++++++++ drivers/media/platform/sti/bdisp/bdisp.h | 186 +++ 9 files changed, 2979 insertions(+) create mode 100644 drivers/media/platform/sti/bdisp/Kconfig create mode 100644 drivers/media/platform/sti/bdisp/Makefile create mode 100644 drivers/media/platform/sti/bdisp/bdisp-filter.h create mode 100644 drivers/media/platform/sti/bdisp/bdisp-hw.c create mode 100644 drivers/media/platform/sti/bdisp/bdisp-reg.h create mode 100644 drivers/media/platform/sti/bdisp/bdisp-v4l2.c create mode 100644 drivers/media/platform/sti/bdisp/bdisp.h (limited to 'drivers/media') diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 421f53188c6c..4776a8cb1071 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -212,6 +212,16 @@ config VIDEO_SAMSUNG_EXYNOS_GSC help This is a v4l2 driver for Samsung EXYNOS5 SoC G-Scaler. +config VIDEO_STI_BDISP + tristate "STMicroelectronics BDISP 2D blitter driver" + depends on VIDEO_DEV && VIDEO_V4L2 + depends on ARCH_STI || COMPILE_TEST + depends on HAS_DMA + select VIDEOBUF2_DMA_CONTIG + select V4L2_MEM2MEM_DEV + help + This v4l2 mem2mem driver is a 2D blitter for STMicroelectronics SoC. + config VIDEO_SH_VEU tristate "SuperH VEU mem2mem video processing driver" depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index 8f855616c237..114f9aba1c00 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -34,6 +34,8 @@ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_TV) += s5p-tv/ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_G2D) += s5p-g2d/ obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC) += exynos-gsc/ +obj-$(CONFIG_VIDEO_STI_BDISP) += sti/bdisp/ + obj-$(CONFIG_BLACKFIN) += blackfin/ obj-$(CONFIG_ARCH_DAVINCI) += davinci/ diff --git a/drivers/media/platform/sti/bdisp/Kconfig b/drivers/media/platform/sti/bdisp/Kconfig new file mode 100644 index 000000000000..afaf4a6ecc72 --- /dev/null +++ b/drivers/media/platform/sti/bdisp/Kconfig @@ -0,0 +1,9 @@ +config VIDEO_STI_BDISP + tristate "STMicroelectronics BDISP 2D blitter driver" + depends on VIDEO_DEV && VIDEO_V4L2 + select VIDEOBUF2_DMA_CONTIG + select V4L2_MEM2MEM_DEV + help + This v4l2 mem2mem driver is a 2D blitter for STMicroelectronics SoC. + To compile this driver as a module, choose M here: the module will + be called bdisp.ko. diff --git a/drivers/media/platform/sti/bdisp/Makefile b/drivers/media/platform/sti/bdisp/Makefile new file mode 100644 index 000000000000..260509483aaf --- /dev/null +++ b/drivers/media/platform/sti/bdisp/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_VIDEO_STI_BDISP) := bdisp.o + +bdisp-objs := bdisp-v4l2.o bdisp-hw.o diff --git a/drivers/media/platform/sti/bdisp/bdisp-filter.h b/drivers/media/platform/sti/bdisp/bdisp-filter.h new file mode 100644 index 000000000000..fc8c54f725ad --- /dev/null +++ b/drivers/media/platform/sti/bdisp/bdisp-filter.h @@ -0,0 +1,346 @@ +/* + * Copyright (C) STMicroelectronics SA 2014 + * Authors: Fabien Dessenne for STMicroelectronics. + * License terms: GNU General Public License (GPL), version 2 + */ + +#define BDISP_HF_NB 64 +#define BDISP_VF_NB 40 + +/** + * struct bdisp_filter_h_spec - Horizontal filter specification + * + * @min: min scale factor for this filter (6.10 fixed point) + * @max: max scale factor for this filter (6.10 fixed point) + * coef: filter coefficients + */ +struct bdisp_filter_h_spec { + const u16 min; + const u16 max; + const u8 coef[BDISP_HF_NB]; +}; + +static const struct bdisp_filter_h_spec bdisp_h_spec[] = { + { + .min = 0, + .max = 921, + .coef = { + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x07, 0x3d, 0xfc, 0x01, 0x00, + 0x00, 0x01, 0xfd, 0x11, 0x36, 0xf9, 0x02, 0x00, + 0x00, 0x01, 0xfb, 0x1b, 0x2e, 0xf9, 0x02, 0x00, + 0x00, 0x01, 0xf9, 0x26, 0x26, 0xf9, 0x01, 0x00, + 0x00, 0x02, 0xf9, 0x30, 0x19, 0xfb, 0x01, 0x00, + 0x00, 0x02, 0xf9, 0x39, 0x0e, 0xfd, 0x01, 0x00, + 0x00, 0x01, 0xfc, 0x3e, 0x06, 0xff, 0x00, 0x00 + } + }, + { + .min = 921, + .max = 1024, + .coef = { + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0xff, 0x03, 0xfd, 0x08, 0x3e, 0xf9, 0x04, 0xfe, + 0xfd, 0x06, 0xf8, 0x13, 0x3b, 0xf4, 0x07, 0xfc, + 0xfb, 0x08, 0xf5, 0x1f, 0x34, 0xf1, 0x09, 0xfb, + 0xfb, 0x09, 0xf2, 0x2b, 0x2a, 0xf1, 0x09, 0xfb, + 0xfb, 0x09, 0xf2, 0x35, 0x1e, 0xf4, 0x08, 0xfb, + 0xfc, 0x07, 0xf5, 0x3c, 0x12, 0xf7, 0x06, 0xfd, + 0xfe, 0x04, 0xfa, 0x3f, 0x07, 0xfc, 0x03, 0xff + } + }, + { + .min = 1024, + .max = 1126, + .coef = { + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0xff, 0x03, 0xfd, 0x08, 0x3e, 0xf9, 0x04, 0xfe, + 0xfd, 0x06, 0xf8, 0x13, 0x3b, 0xf4, 0x07, 0xfc, + 0xfb, 0x08, 0xf5, 0x1f, 0x34, 0xf1, 0x09, 0xfb, + 0xfb, 0x09, 0xf2, 0x2b, 0x2a, 0xf1, 0x09, 0xfb, + 0xfb, 0x09, 0xf2, 0x35, 0x1e, 0xf4, 0x08, 0xfb, + 0xfc, 0x07, 0xf5, 0x3c, 0x12, 0xf7, 0x06, 0xfd, + 0xfe, 0x04, 0xfa, 0x3f, 0x07, 0xfc, 0x03, 0xff + } + }, + { + .min = 1126, + .max = 1228, + .coef = { + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0xff, 0x03, 0xfd, 0x08, 0x3e, 0xf9, 0x04, 0xfe, + 0xfd, 0x06, 0xf8, 0x13, 0x3b, 0xf4, 0x07, 0xfc, + 0xfb, 0x08, 0xf5, 0x1f, 0x34, 0xf1, 0x09, 0xfb, + 0xfb, 0x09, 0xf2, 0x2b, 0x2a, 0xf1, 0x09, 0xfb, + 0xfb, 0x09, 0xf2, 0x35, 0x1e, 0xf4, 0x08, 0xfb, + 0xfc, 0x07, 0xf5, 0x3c, 0x12, 0xf7, 0x06, 0xfd, + 0xfe, 0x04, 0xfa, 0x3f, 0x07, 0xfc, 0x03, 0xff + } + }, + { + .min = 1228, + .max = 1331, + .coef = { + 0xfd, 0x04, 0xfc, 0x05, 0x39, 0x05, 0xfc, 0x04, + 0xfc, 0x06, 0xf9, 0x0c, 0x39, 0xfe, 0x00, 0x02, + 0xfb, 0x08, 0xf6, 0x17, 0x35, 0xf9, 0x02, 0x00, + 0xfc, 0x08, 0xf4, 0x20, 0x30, 0xf4, 0x05, 0xff, + 0xfd, 0x07, 0xf4, 0x29, 0x28, 0xf3, 0x07, 0xfd, + 0xff, 0x05, 0xf5, 0x31, 0x1f, 0xf3, 0x08, 0xfc, + 0x00, 0x02, 0xf9, 0x38, 0x14, 0xf6, 0x08, 0xfb, + 0x02, 0x00, 0xff, 0x3a, 0x0b, 0xf8, 0x06, 0xfc + } + }, + { + .min = 1331, + .max = 1433, + .coef = { + 0xfc, 0x06, 0xf9, 0x09, 0x34, 0x09, 0xf9, 0x06, + 0xfd, 0x07, 0xf7, 0x10, 0x32, 0x02, 0xfc, 0x05, + 0xfe, 0x07, 0xf6, 0x17, 0x2f, 0xfc, 0xff, 0x04, + 0xff, 0x06, 0xf5, 0x20, 0x2a, 0xf9, 0x01, 0x02, + 0x00, 0x04, 0xf6, 0x27, 0x25, 0xf6, 0x04, 0x00, + 0x02, 0x01, 0xf9, 0x2d, 0x1d, 0xf5, 0x06, 0xff, + 0x04, 0xff, 0xfd, 0x31, 0x15, 0xf5, 0x07, 0xfe, + 0x05, 0xfc, 0x02, 0x35, 0x0d, 0xf7, 0x07, 0xfd + } + }, + { + .min = 1433, + .max = 1536, + .coef = { + 0xfe, 0x06, 0xf8, 0x0b, 0x30, 0x0b, 0xf8, 0x06, + 0xff, 0x06, 0xf7, 0x12, 0x2d, 0x05, 0xfa, 0x06, + 0x00, 0x04, 0xf6, 0x18, 0x2c, 0x00, 0xfc, 0x06, + 0x01, 0x02, 0xf7, 0x1f, 0x27, 0xfd, 0xff, 0x04, + 0x03, 0x00, 0xf9, 0x24, 0x24, 0xf9, 0x00, 0x03, + 0x04, 0xff, 0xfd, 0x29, 0x1d, 0xf7, 0x02, 0x01, + 0x06, 0xfc, 0x00, 0x2d, 0x17, 0xf6, 0x04, 0x00, + 0x06, 0xfa, 0x05, 0x30, 0x0f, 0xf7, 0x06, 0xff + } + }, + { + .min = 1536, + .max = 2048, + .coef = { + 0x05, 0xfd, 0xfb, 0x13, 0x25, 0x13, 0xfb, 0xfd, + 0x05, 0xfc, 0xfd, 0x17, 0x24, 0x0f, 0xf9, 0xff, + 0x04, 0xfa, 0xff, 0x1b, 0x24, 0x0b, 0xf9, 0x00, + 0x03, 0xf9, 0x01, 0x1f, 0x23, 0x08, 0xf8, 0x01, + 0x02, 0xf9, 0x04, 0x22, 0x20, 0x04, 0xf9, 0x02, + 0x01, 0xf8, 0x08, 0x25, 0x1d, 0x01, 0xf9, 0x03, + 0x00, 0xf9, 0x0c, 0x25, 0x1a, 0xfe, 0xfa, 0x04, + 0xff, 0xf9, 0x10, 0x26, 0x15, 0xfc, 0xfc, 0x05 + } + }, + { + .min = 2048, + .max = 3072, + .coef = { + 0xfc, 0xfd, 0x06, 0x13, 0x18, 0x13, 0x06, 0xfd, + 0xfc, 0xfe, 0x08, 0x15, 0x17, 0x12, 0x04, 0xfc, + 0xfb, 0xfe, 0x0a, 0x16, 0x18, 0x10, 0x03, 0xfc, + 0xfb, 0x00, 0x0b, 0x18, 0x17, 0x0f, 0x01, 0xfb, + 0xfb, 0x00, 0x0d, 0x19, 0x17, 0x0d, 0x00, 0xfb, + 0xfb, 0x01, 0x0f, 0x19, 0x16, 0x0b, 0x00, 0xfb, + 0xfc, 0x03, 0x11, 0x19, 0x15, 0x09, 0xfe, 0xfb, + 0xfc, 0x04, 0x12, 0x1a, 0x12, 0x08, 0xfe, 0xfc + } + }, + { + .min = 3072, + .max = 4096, + .coef = { + 0xfe, 0x02, 0x09, 0x0f, 0x0e, 0x0f, 0x09, 0x02, + 0xff, 0x02, 0x09, 0x0f, 0x10, 0x0e, 0x08, 0x01, + 0xff, 0x03, 0x0a, 0x10, 0x10, 0x0d, 0x07, 0x00, + 0x00, 0x04, 0x0b, 0x10, 0x0f, 0x0c, 0x06, 0x00, + 0x00, 0x05, 0x0c, 0x10, 0x0e, 0x0c, 0x05, 0x00, + 0x00, 0x06, 0x0c, 0x11, 0x0e, 0x0b, 0x04, 0x00, + 0x00, 0x07, 0x0d, 0x11, 0x0f, 0x0a, 0x03, 0xff, + 0x01, 0x08, 0x0e, 0x11, 0x0e, 0x09, 0x02, 0xff + } + }, + { + .min = 4096, + .max = 5120, + .coef = { + 0x00, 0x04, 0x09, 0x0c, 0x0e, 0x0c, 0x09, 0x04, + 0x01, 0x05, 0x09, 0x0c, 0x0d, 0x0c, 0x08, 0x04, + 0x01, 0x05, 0x0a, 0x0c, 0x0e, 0x0b, 0x08, 0x03, + 0x02, 0x06, 0x0a, 0x0d, 0x0c, 0x0b, 0x07, 0x03, + 0x02, 0x07, 0x0a, 0x0d, 0x0d, 0x0a, 0x07, 0x02, + 0x03, 0x07, 0x0b, 0x0d, 0x0c, 0x0a, 0x06, 0x02, + 0x03, 0x08, 0x0b, 0x0d, 0x0d, 0x0a, 0x05, 0x01, + 0x04, 0x08, 0x0c, 0x0d, 0x0c, 0x09, 0x05, 0x01 + } + }, + { + .min = 5120, + .max = 65535, + .coef = { + 0x03, 0x06, 0x09, 0x0b, 0x09, 0x0b, 0x09, 0x06, + 0x03, 0x06, 0x09, 0x0b, 0x0c, 0x0a, 0x08, 0x05, + 0x03, 0x06, 0x09, 0x0b, 0x0c, 0x0a, 0x08, 0x05, + 0x04, 0x07, 0x09, 0x0b, 0x0b, 0x0a, 0x08, 0x04, + 0x04, 0x07, 0x0a, 0x0b, 0x0b, 0x0a, 0x07, 0x04, + 0x04, 0x08, 0x0a, 0x0b, 0x0b, 0x09, 0x07, 0x04, + 0x05, 0x08, 0x0a, 0x0b, 0x0c, 0x09, 0x06, 0x03, + 0x05, 0x08, 0x0a, 0x0b, 0x0c, 0x09, 0x06, 0x03 + } + } +}; + +/** + * struct bdisp_filter_v_spec - Vertical filter specification + * + * @min: min scale factor for this filter (6.10 fixed point) + * @max: max scale factor for this filter (6.10 fixed point) + * coef: filter coefficients + */ +struct bdisp_filter_v_spec { + const u16 min; + const u16 max; + const u8 coef[BDISP_VF_NB]; +}; + +static const struct bdisp_filter_v_spec bdisp_v_spec[] = { + { + .min = 0, + .max = 1024, + .coef = { + 0x00, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x06, 0x3d, 0xfd, 0x00, + 0xfe, 0x0f, 0x38, 0xfb, 0x00, + 0xfd, 0x19, 0x2f, 0xfb, 0x00, + 0xfc, 0x24, 0x24, 0xfc, 0x00, + 0xfb, 0x2f, 0x19, 0xfd, 0x00, + 0xfb, 0x38, 0x0f, 0xfe, 0x00, + 0xfd, 0x3d, 0x06, 0x00, 0x00 + } + }, + { + .min = 1024, + .max = 1331, + .coef = { + 0xfc, 0x05, 0x3e, 0x05, 0xfc, + 0xf8, 0x0e, 0x3b, 0xff, 0x00, + 0xf5, 0x18, 0x38, 0xf9, 0x02, + 0xf4, 0x21, 0x31, 0xf5, 0x05, + 0xf4, 0x2a, 0x27, 0xf4, 0x07, + 0xf6, 0x30, 0x1e, 0xf4, 0x08, + 0xf9, 0x35, 0x15, 0xf6, 0x07, + 0xff, 0x37, 0x0b, 0xf9, 0x06 + } + }, + { + .min = 1331, + .max = 1433, + .coef = { + 0xf8, 0x0a, 0x3c, 0x0a, 0xf8, + 0xf6, 0x12, 0x3b, 0x02, 0xfb, + 0xf4, 0x1b, 0x35, 0xfd, 0xff, + 0xf4, 0x23, 0x30, 0xf8, 0x01, + 0xf6, 0x29, 0x27, 0xf6, 0x04, + 0xf9, 0x2e, 0x1e, 0xf5, 0x06, + 0xfd, 0x31, 0x16, 0xf6, 0x06, + 0x02, 0x32, 0x0d, 0xf8, 0x07 + } + }, + { + .min = 1433, + .max = 1536, + .coef = { + 0xf6, 0x0e, 0x38, 0x0e, 0xf6, + 0xf5, 0x15, 0x38, 0x06, 0xf8, + 0xf5, 0x1d, 0x33, 0x00, 0xfb, + 0xf6, 0x23, 0x2d, 0xfc, 0xfe, + 0xf9, 0x28, 0x26, 0xf9, 0x00, + 0xfc, 0x2c, 0x1e, 0xf7, 0x03, + 0x00, 0x2e, 0x18, 0xf6, 0x04, + 0x05, 0x2e, 0x11, 0xf7, 0x05 + } + }, + { + .min = 1536, + .max = 2048, + .coef = { + 0xfb, 0x13, 0x24, 0x13, 0xfb, + 0xfd, 0x17, 0x23, 0x0f, 0xfa, + 0xff, 0x1a, 0x23, 0x0b, 0xf9, + 0x01, 0x1d, 0x22, 0x07, 0xf9, + 0x04, 0x20, 0x1f, 0x04, 0xf9, + 0x07, 0x22, 0x1c, 0x01, 0xfa, + 0x0b, 0x24, 0x17, 0xff, 0xfb, + 0x0f, 0x24, 0x14, 0xfd, 0xfc + } + }, + { + .min = 2048, + .max = 3072, + .coef = { + 0x05, 0x10, 0x16, 0x10, 0x05, + 0x06, 0x11, 0x16, 0x0f, 0x04, + 0x08, 0x13, 0x15, 0x0e, 0x02, + 0x09, 0x14, 0x16, 0x0c, 0x01, + 0x0b, 0x15, 0x15, 0x0b, 0x00, + 0x0d, 0x16, 0x13, 0x0a, 0x00, + 0x0f, 0x17, 0x13, 0x08, 0xff, + 0x11, 0x18, 0x12, 0x07, 0xfe + } + }, + { + .min = 3072, + .max = 4096, + .coef = { + 0x09, 0x0f, 0x10, 0x0f, 0x09, + 0x09, 0x0f, 0x12, 0x0e, 0x08, + 0x0a, 0x10, 0x11, 0x0e, 0x07, + 0x0b, 0x11, 0x11, 0x0d, 0x06, + 0x0c, 0x11, 0x12, 0x0c, 0x05, + 0x0d, 0x12, 0x11, 0x0c, 0x04, + 0x0e, 0x12, 0x11, 0x0b, 0x04, + 0x0f, 0x13, 0x11, 0x0a, 0x03 + } + }, + { + .min = 4096, + .max = 5120, + .coef = { + 0x0a, 0x0e, 0x10, 0x0e, 0x0a, + 0x0b, 0x0e, 0x0f, 0x0e, 0x0a, + 0x0b, 0x0f, 0x10, 0x0d, 0x09, + 0x0c, 0x0f, 0x10, 0x0d, 0x08, + 0x0d, 0x0f, 0x0f, 0x0d, 0x08, + 0x0d, 0x10, 0x10, 0x0c, 0x07, + 0x0e, 0x10, 0x0f, 0x0c, 0x07, + 0x0f, 0x10, 0x10, 0x0b, 0x06 + } + }, + { + .min = 5120, + .max = 65535, + .coef = { + 0x0b, 0x0e, 0x0e, 0x0e, 0x0b, + 0x0b, 0x0e, 0x0f, 0x0d, 0x0b, + 0x0c, 0x0e, 0x0f, 0x0d, 0x0a, + 0x0c, 0x0e, 0x0f, 0x0d, 0x0a, + 0x0d, 0x0f, 0x0e, 0x0d, 0x09, + 0x0d, 0x0f, 0x0f, 0x0c, 0x09, + 0x0e, 0x0f, 0x0e, 0x0c, 0x09, + 0x0e, 0x0f, 0x0f, 0x0c, 0x08 + } + } +}; + +#define NB_H_FILTER ARRAY_SIZE(bdisp_h_spec) +#define NB_V_FILTER ARRAY_SIZE(bdisp_v_spec) + +/* RGB YUV 601 standard conversion */ +static const u32 bdisp_rgb_to_yuv[] = { + 0x0e1e8bee, 0x08420419, 0xfb5ed471, 0x08004080, +}; + +static const u32 bdisp_yuv_to_rgb[] = { + 0x3324a800, 0xe604ab9c, 0x0004a957, 0x32121eeb, +}; diff --git a/drivers/media/platform/sti/bdisp/bdisp-hw.c b/drivers/media/platform/sti/bdisp/bdisp-hw.c new file mode 100644 index 000000000000..9c288acd835d --- /dev/null +++ b/drivers/media/platform/sti/bdisp/bdisp-hw.c @@ -0,0 +1,783 @@ +/* + * Copyright (C) STMicroelectronics SA 2014 + * Authors: Fabien Dessenne for STMicroelectronics. + * License terms: GNU General Public License (GPL), version 2 + */ + +#include + +#include "bdisp.h" +#include "bdisp-filter.h" +#include "bdisp-reg.h" + +/* Max width of the source frame in a single node */ +#define MAX_SRC_WIDTH 2048 + +/* Reset & boot poll config */ +#define POLL_RST_MAX 50 +#define POLL_RST_DELAY_MS 20 + +enum bdisp_target_plan { + BDISP_RGB, + BDISP_Y, + BDISP_CBCR +}; + +struct bdisp_op_cfg { + bool cconv; /* RGB - YUV conversion */ + bool hflip; /* Horizontal flip */ + bool vflip; /* Vertical flip */ + bool wide; /* Wide (>MAX_SRC_WIDTH) */ + bool scale; /* Scale */ + u16 h_inc; /* Horizontal increment in 6.10 format */ + u16 v_inc; /* Vertical increment in 6.10 format */ + bool src_interlaced; /* is the src an interlaced buffer */ + u8 src_nbp; /* nb of planes of the src */ + bool src_yuv; /* is the src a YUV color format */ + bool src_420; /* is the src 4:2:0 chroma subsampled */ + u8 dst_nbp; /* nb of planes of the dst */ + bool dst_yuv; /* is the dst a YUV color format */ + bool dst_420; /* is the dst 4:2:0 chroma subsampled */ +}; + +struct bdisp_filter_addr { + u16 min; /* Filter min scale factor (6.10 fixed point) */ + u16 max; /* Filter max scale factor (6.10 fixed point) */ + void *virt; /* Virtual address for filter table */ + dma_addr_t paddr; /* Physical address for filter table */ +}; + +static struct bdisp_filter_addr bdisp_h_filter[NB_H_FILTER]; +static struct bdisp_filter_addr bdisp_v_filter[NB_V_FILTER]; + +/** + * bdisp_hw_reset + * @bdisp: bdisp entity + * + * Resets HW + * + * RETURNS: + * 0 on success. + */ +int bdisp_hw_reset(struct bdisp_dev *bdisp) +{ + unsigned int i; + + dev_dbg(bdisp->dev, "%s\n", __func__); + + /* Mask Interrupt */ + writel(0, bdisp->regs + BLT_ITM0); + + /* Reset */ + writel(readl(bdisp->regs + BLT_CTL) | BLT_CTL_RESET, + bdisp->regs + BLT_CTL); + writel(0, bdisp->regs + BLT_CTL); + + /* Wait for reset done */ + for (i = 0; i < POLL_RST_MAX; i++) { + if (readl(bdisp->regs + BLT_STA1) & BLT_STA1_IDLE) + break; + msleep(POLL_RST_DELAY_MS); + } + if (i == POLL_RST_MAX) + dev_err(bdisp->dev, "Reset timeout\n"); + + return (i == POLL_RST_MAX) ? -EAGAIN : 0; +} + +/** + * bdisp_hw_get_and_clear_irq + * @bdisp: bdisp entity + * + * Read then reset interrupt status + * + * RETURNS: + * 0 if expected interrupt was raised. + */ +int bdisp_hw_get_and_clear_irq(struct bdisp_dev *bdisp) +{ + u32 its; + + its = readl(bdisp->regs + BLT_ITS); + + /* Check for the only expected IT: LastNode of AQ1 */ + if (!(its & BLT_ITS_AQ1_LNA)) { + dev_dbg(bdisp->dev, "Unexpected IT status: 0x%08X\n", its); + writel(its, bdisp->regs + BLT_ITS); + return -1; + } + + /* Clear and mask */ + writel(its, bdisp->regs + BLT_ITS); + writel(0, bdisp->regs + BLT_ITM0); + + return 0; +} + +/** + * bdisp_hw_free_nodes + * @ctx: bdisp context + * + * Free node memory + * + * RETURNS: + * None + */ +void bdisp_hw_free_nodes(struct bdisp_ctx *ctx) +{ + if (ctx && ctx->node[0]) { + DEFINE_DMA_ATTRS(attrs); + + dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs); + dma_free_attrs(ctx->bdisp_dev->dev, + sizeof(struct bdisp_node) * MAX_NB_NODE, + ctx->node[0], ctx->node_paddr[0], &attrs); + } +} + +/** + * bdisp_hw_alloc_nodes + * @ctx: bdisp context + * + * Allocate dma memory for nodes + * + * RETURNS: + * 0 on success + */ +int bdisp_hw_alloc_nodes(struct bdisp_ctx *ctx) +{ + struct device *dev = ctx->bdisp_dev->dev; + unsigned int i, node_size = sizeof(struct bdisp_node); + void *base; + dma_addr_t paddr; + DEFINE_DMA_ATTRS(attrs); + + /* Allocate all the nodes within a single memory page */ + dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs); + base = dma_alloc_attrs(dev, node_size * MAX_NB_NODE, &paddr, + GFP_KERNEL | GFP_DMA, &attrs); + if (!base) { + dev_err(dev, "%s no mem\n", __func__); + return -ENOMEM; + } + + memset(base, 0, node_size * MAX_NB_NODE); + + for (i = 0; i < MAX_NB_NODE; i++) { + ctx->node[i] = base; + ctx->node_paddr[i] = paddr; + dev_dbg(dev, "node[%d]=0x%p (paddr=%pad)\n", i, ctx->node[i], + &paddr); + base += node_size; + paddr += node_size; + } + + return 0; +} + +/** + * bdisp_hw_free_filters + * @dev: device + * + * Free filters memory + * + * RETURNS: + * None + */ +void bdisp_hw_free_filters(struct device *dev) +{ + int size = (BDISP_HF_NB * NB_H_FILTER) + (BDISP_VF_NB * NB_V_FILTER); + + if (bdisp_h_filter[0].virt) { + DEFINE_DMA_ATTRS(attrs); + + dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs); + dma_free_attrs(dev, size, bdisp_h_filter[0].virt, + bdisp_h_filter[0].paddr, &attrs); + } +} + +/** + * bdisp_hw_alloc_filters + * @dev: device + * + * Allocate dma memory for filters + * + * RETURNS: + * 0 on success + */ +int bdisp_hw_alloc_filters(struct device *dev) +{ + unsigned int i, size; + void *base; + dma_addr_t paddr; + DEFINE_DMA_ATTRS(attrs); + + /* Allocate all the filters within a single memory page */ + size = (BDISP_HF_NB * NB_H_FILTER) + (BDISP_VF_NB * NB_V_FILTER); + dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs); + base = dma_alloc_attrs(dev, size, &paddr, GFP_KERNEL | GFP_DMA, &attrs); + if (!base) + return -ENOMEM; + + /* Setup filter addresses */ + for (i = 0; i < NB_H_FILTER; i++) { + bdisp_h_filter[i].min = bdisp_h_spec[i].min; + bdisp_h_filter[i].max = bdisp_h_spec[i].max; + memcpy(base, bdisp_h_spec[i].coef, BDISP_HF_NB); + bdisp_h_filter[i].virt = base; + bdisp_h_filter[i].paddr = paddr; + base += BDISP_HF_NB; + paddr += BDISP_HF_NB; + } + + for (i = 0; i < NB_V_FILTER; i++) { + bdisp_v_filter[i].min = bdisp_v_spec[i].min; + bdisp_v_filter[i].max = bdisp_v_spec[i].max; + memcpy(base, bdisp_v_spec[i].coef, BDISP_VF_NB); + bdisp_v_filter[i].virt = base; + bdisp_v_filter[i].paddr = paddr; + base += BDISP_VF_NB; + paddr += BDISP_VF_NB; + } + + return 0; +} + +/** + * bdisp_hw_get_hf_addr + * @inc: resize increment + * + * Find the horizontal filter table that fits the resize increment + * + * RETURNS: + * table physical address + */ +static dma_addr_t bdisp_hw_get_hf_addr(u16 inc) +{ + unsigned int i; + + for (i = NB_H_FILTER - 1; i > 0; i--) + if ((bdisp_h_filter[i].min < inc) && + (inc <= bdisp_h_filter[i].max)) + break; + + return bdisp_h_filter[i].paddr; +} + +/** + * bdisp_hw_get_vf_addr + * @inc: resize increment + * + * Find the vertical filter table that fits the resize increment + * + * RETURNS: + * table physical address + */ +static dma_addr_t bdisp_hw_get_vf_addr(u16 inc) +{ + unsigned int i; + + for (i = NB_V_FILTER - 1; i > 0; i--) + if ((bdisp_v_filter[i].min < inc) && + (inc <= bdisp_v_filter[i].max)) + break; + + return bdisp_v_filter[i].paddr; +} + +/** + * bdisp_hw_get_inc + * @from: input size + * @to: output size + * @inc: resize increment in 6.10 format + * + * Computes the increment (inverse of scale) in 6.10 format + * + * RETURNS: + * 0 on success + */ +static int bdisp_hw_get_inc(u32 from, u32 to, u16 *inc) +{ + u32 tmp; + + if (!to) + return -EINVAL; + + if (to == from) { + *inc = 1 << 10; + return 0; + } + + tmp = (from << 10) / to; + if ((tmp > 0xFFFF) || (!tmp)) + /* overflow (downscale x 63) or too small (upscale x 1024) */ + return -EINVAL; + + *inc = (u16)tmp; + + return 0; +} + +/** + * bdisp_hw_get_hv_inc + * @ctx: device context + * @h_inc: horizontal increment + * @v_inc: vertical increment + * + * Computes the horizontal & vertical increments (inverse of scale) + * + * RETURNS: + * 0 on success + */ +static int bdisp_hw_get_hv_inc(struct bdisp_ctx *ctx, u16 *h_inc, u16 *v_inc) +{ + u32 src_w, src_h, dst_w, dst_h; + + src_w = ctx->src.crop.width; + src_h = ctx->src.crop.height; + dst_w = ctx->dst.width; + dst_h = ctx->dst.height; + + if (bdisp_hw_get_inc(src_w, dst_w, h_inc) || + bdisp_hw_get_inc(src_h, dst_h, v_inc)) { + dev_err(ctx->bdisp_dev->dev, + "scale factors failed (%dx%d)->(%dx%d)\n", + src_w, src_h, dst_w, dst_h); + return -EINVAL; + } + + return 0; +} + +/** + * bdisp_hw_get_op_cfg + * @ctx: device context + * @c: operation configuration + * + * Check which blitter operations are expected and sets the scaling increments + * + * RETURNS: + * 0 on success + */ +static int bdisp_hw_get_op_cfg(struct bdisp_ctx *ctx, struct bdisp_op_cfg *c) +{ + struct device *dev = ctx->bdisp_dev->dev; + struct bdisp_frame *src = &ctx->src; + struct bdisp_frame *dst = &ctx->dst; + + if (src->width > MAX_SRC_WIDTH * MAX_VERTICAL_STRIDES) { + dev_err(dev, "Image width out of HW caps\n"); + return -EINVAL; + } + + c->wide = src->width > MAX_SRC_WIDTH; + + c->hflip = ctx->hflip; + c->vflip = ctx->vflip; + + c->src_interlaced = (src->field == V4L2_FIELD_INTERLACED); + + c->src_nbp = src->fmt->nb_planes; + c->src_yuv = (src->fmt->pixelformat == V4L2_PIX_FMT_NV12) || + (src->fmt->pixelformat == V4L2_PIX_FMT_YUV420); + c->src_420 = c->src_yuv; + + c->dst_nbp = dst->fmt->nb_planes; + c->dst_yuv = (dst->fmt->pixelformat == V4L2_PIX_FMT_NV12) || + (dst->fmt->pixelformat == V4L2_PIX_FMT_YUV420); + c->dst_420 = c->dst_yuv; + + c->cconv = (c->src_yuv != c->dst_yuv); + + if (bdisp_hw_get_hv_inc(ctx, &c->h_inc, &c->v_inc)) { + dev_err(dev, "Scale factor out of HW caps\n"); + return -EINVAL; + } + + /* Deinterlacing adjustment : stretch a field to a frame */ + if (c->src_interlaced) + c->v_inc /= 2; + + if ((c->h_inc != (1 << 10)) || (c->v_inc != (1 << 10))) + c->scale = true; + else + c->scale = false; + + return 0; +} + +/** + * bdisp_hw_color_format + * @pixelformat: v4l2 pixel format + * + * v4l2 to bdisp pixel format convert + * + * RETURNS: + * bdisp pixel format + */ +static u32 bdisp_hw_color_format(u32 pixelformat) +{ + u32 ret; + + switch (pixelformat) { + case V4L2_PIX_FMT_YUV420: + ret = (BDISP_YUV_3B << BLT_TTY_COL_SHIFT); + break; + case V4L2_PIX_FMT_NV12: + ret = (BDISP_NV12 << BLT_TTY_COL_SHIFT) | BLT_TTY_BIG_END; + break; + case V4L2_PIX_FMT_RGB565: + ret = (BDISP_RGB565 << BLT_TTY_COL_SHIFT); + break; + case V4L2_PIX_FMT_XBGR32: /* This V4L format actually refers to xRGB */ + ret = (BDISP_XRGB8888 << BLT_TTY_COL_SHIFT); + break; + case V4L2_PIX_FMT_RGB24: /* RGB888 format */ + ret = (BDISP_RGB888 << BLT_TTY_COL_SHIFT) | BLT_TTY_BIG_END; + break; + case V4L2_PIX_FMT_ABGR32: /* This V4L format actually refers to ARGB */ + + default: + ret = (BDISP_ARGB8888 << BLT_TTY_COL_SHIFT) | BLT_TTY_ALPHA_R; + break; + } + + return ret; +} + +/** + * bdisp_hw_build_node + * @ctx: device context + * @cfg: operation configuration + * @node: node to be set + * @t_plan: whether the node refers to a RGB/Y or a CbCr plane + * @src_x_offset: x offset in the source image + * + * Build a node + * + * RETURNS: + * None + */ +static void bdisp_hw_build_node(struct bdisp_ctx *ctx, + struct bdisp_op_cfg *cfg, + struct bdisp_node *node, + enum bdisp_target_plan t_plan, int src_x_offset) +{ + struct bdisp_frame *src = &ctx->src; + struct bdisp_frame *dst = &ctx->dst; + u16 h_inc, v_inc, yh_inc, yv_inc; + struct v4l2_rect src_rect = src->crop; + struct v4l2_rect dst_rect = dst->crop; + int dst_x_offset; + s32 dst_width = dst->crop.width; + u32 src_fmt, dst_fmt; + const u32 *ivmx; + + dev_dbg(ctx->bdisp_dev->dev, "%s\n", __func__); + + memset(node, 0, sizeof(*node)); + + /* Adjust src and dst areas wrt src_x_offset */ + src_rect.left += src_x_offset; + src_rect.width -= src_x_offset; + src_rect.width = min_t(__s32, MAX_SRC_WIDTH, src_rect.width); + + dst_x_offset = (src_x_offset * dst->width) / ctx->src.crop.width; + dst_rect.left += dst_x_offset; + dst_rect.width = (src_rect.width * dst->width) / ctx->src.crop.width; + + /* General */ + src_fmt = src->fmt->pixelformat; + dst_fmt = dst->fmt->pixelformat; + + node->nip = 0; + node->cic = BLT_CIC_ALL_GRP; + node->ack = BLT_ACK_BYPASS_S2S3; + + switch (cfg->src_nbp) { + case 1: + /* Src2 = RGB / Src1 = Src3 = off */ + node->ins = BLT_INS_S1_OFF | BLT_INS_S2_MEM | BLT_INS_S3_OFF; + break; + case 2: + /* Src3 = Y + * Src2 = CbCr or ColorFill if writing the Y plane + * Src1 = off */ + node->ins = BLT_INS_S1_OFF | BLT_INS_S3_MEM; + if (t_plan == BDISP_Y) + node->ins |= BLT_INS_S2_CF; + else + node->ins |= BLT_INS_S2_MEM; + break; + case 3: + default: + /* Src3 = Y + * Src2 = Cb or ColorFill if writing the Y plane + * Src1 = Cr or ColorFill if writing the Y plane */ + node->ins = BLT_INS_S3_MEM; + if (t_plan == BDISP_Y) + node->ins |= BLT_INS_S2_CF | BLT_INS_S1_CF; + else + node->ins |= BLT_INS_S2_MEM | BLT_INS_S1_MEM; + break; + } + + /* Color convert */ + node->ins |= cfg->cconv ? BLT_INS_IVMX : 0; + /* Scale needed if scaling OR 4:2:0 up/downsampling */ + node->ins |= (cfg->scale || cfg->src_420 || cfg->dst_420) ? + BLT_INS_SCALE : 0; + + /* Target */ + node->tba = (t_plan == BDISP_CBCR) ? dst->paddr[1] : dst->paddr[0]; + + node->tty = dst->bytesperline; + node->tty |= bdisp_hw_color_format(dst_fmt); + node->tty |= BLT_TTY_DITHER; + node->tty |= (t_plan == BDISP_CBCR) ? BLT_TTY_CHROMA : 0; + node->tty |= cfg->hflip ? BLT_TTY_HSO : 0; + node->tty |= cfg->vflip ? BLT_TTY_VSO : 0; + + if (cfg->dst_420 && (t_plan == BDISP_CBCR)) { + /* 420 chroma downsampling */ + dst_rect.height /= 2; + dst_rect.width /= 2; + dst_rect.left /= 2; + dst_rect.top /= 2; + dst_x_offset /= 2; + dst_width /= 2; + } + + node->txy = cfg->vflip ? (dst_rect.height - 1) : dst_rect.top; + node->txy <<= 16; + node->txy |= cfg->hflip ? (dst_width - dst_x_offset - 1) : + dst_rect.left; + + node->tsz = dst_rect.height << 16 | dst_rect.width; + + if (cfg->src_interlaced) { + /* handle only the top field which is half height of a frame */ + src_rect.top /= 2; + src_rect.height /= 2; + } + + if (cfg->src_nbp == 1) { + /* Src 2 : RGB */ + node->s2ba = src->paddr[0]; + + node->s2ty = src->bytesperline; + if (cfg->src_interlaced) + node->s2ty *= 2; + + node->s2ty |= bdisp_hw_color_format(src_fmt); + + node->s2xy = src_rect.top << 16 | src_rect.left; + node->s2sz = src_rect.height << 16 | src_rect.width; + } else { + /* Src 2 : Cb or CbCr */ + if (cfg->src_420) { + /* 420 chroma upsampling */ + src_rect.top /= 2; + src_rect.left /= 2; + src_rect.width /= 2; + src_rect.height /= 2; + } + + node->s2ba = src->paddr[1]; + + node->s2ty = src->bytesperline; + if (cfg->src_nbp == 3) + node->s2ty /= 2; + if (cfg->src_interlaced) + node->s2ty *= 2; + + node->s2ty |= bdisp_hw_color_format(src_fmt); + + node->s2xy = src_rect.top << 16 | src_rect.left; + node->s2sz = src_rect.height << 16 | src_rect.width; + + if (cfg->src_nbp == 3) { + /* Src 1 : Cr */ + node->s1ba = src->paddr[2]; + + node->s1ty = node->s2ty; + node->s1xy = node->s2xy; + } + + /* Src 3 : Y */ + node->s3ba = src->paddr[0]; + + node->s3ty = src->bytesperline; + if (cfg->src_interlaced) + node->s3ty *= 2; + node->s3ty |= bdisp_hw_color_format(src_fmt); + + if ((t_plan != BDISP_CBCR) && cfg->src_420) { + /* No chroma upsampling for output RGB / Y plane */ + node->s3xy = node->s2xy * 2; + node->s3sz = node->s2sz * 2; + } else { + /* No need to read Y (Src3) when writing Chroma */ + node->s3ty |= BLT_S3TY_BLANK_ACC; + node->s3xy = node->s2xy; + node->s3sz = node->s2sz; + } + } + + /* Resize (scale OR 4:2:0: chroma up/downsampling) */ + if (node->ins & BLT_INS_SCALE) { + /* no need to compute Y when writing CbCr from RGB input */ + bool skip_y = (t_plan == BDISP_CBCR) && !cfg->src_yuv; + + /* FCTL */ + if (cfg->scale) { + node->fctl = BLT_FCTL_HV_SCALE; + if (!skip_y) + node->fctl |= BLT_FCTL_Y_HV_SCALE; + } else { + node->fctl = BLT_FCTL_HV_SAMPLE; + if (!skip_y) + node->fctl |= BLT_FCTL_Y_HV_SAMPLE; + } + + /* RSF - Chroma may need to be up/downsampled */ + h_inc = cfg->h_inc; + v_inc = cfg->v_inc; + if (!cfg->src_420 && cfg->dst_420 && (t_plan == BDISP_CBCR)) { + /* RGB to 4:2:0 for Chroma: downsample */ + h_inc *= 2; + v_inc *= 2; + } else if (cfg->src_420 && !cfg->dst_420) { + /* 4:2:0: to RGB: upsample*/ + h_inc /= 2; + v_inc /= 2; + } + node->rsf = v_inc << 16 | h_inc; + + /* RZI */ + node->rzi = BLT_RZI_DEFAULT; + + /* Filter table physical addr */ + node->hfp = bdisp_hw_get_hf_addr(h_inc); + node->vfp = bdisp_hw_get_vf_addr(v_inc); + + /* Y version */ + if (!skip_y) { + yh_inc = cfg->h_inc; + yv_inc = cfg->v_inc; + + node->y_rsf = yv_inc << 16 | yh_inc; + node->y_rzi = BLT_RZI_DEFAULT; + node->y_hfp = bdisp_hw_get_hf_addr(yh_inc); + node->y_vfp = bdisp_hw_get_vf_addr(yv_inc); + } + } + + /* Versatile matrix for RGB / YUV conversion */ + if (cfg->cconv) { + ivmx = cfg->src_yuv ? bdisp_yuv_to_rgb : bdisp_rgb_to_yuv; + + node->ivmx0 = ivmx[0]; + node->ivmx1 = ivmx[1]; + node->ivmx2 = ivmx[2]; + node->ivmx3 = ivmx[3]; + } +} + +/** + * bdisp_hw_build_all_nodes + * @ctx: device context + * + * Build all the nodes for the blitter operation + * + * RETURNS: + * 0 on success + */ +static int bdisp_hw_build_all_nodes(struct bdisp_ctx *ctx) +{ + struct bdisp_op_cfg cfg; + unsigned int i, nid = 0; + int src_x_offset = 0; + + for (i = 0; i < MAX_NB_NODE; i++) + if (!ctx->node[i]) { + dev_err(ctx->bdisp_dev->dev, "node %d is null\n", i); + return -EINVAL; + } + + /* Get configuration (scale, flip, ...) */ + if (bdisp_hw_get_op_cfg(ctx, &cfg)) + return -EINVAL; + + /* Split source in vertical strides (HW constraint) */ + for (i = 0; i < MAX_VERTICAL_STRIDES; i++) { + /* Build RGB/Y node and link it to the previous node */ + bdisp_hw_build_node(ctx, &cfg, ctx->node[nid], + cfg.dst_nbp == 1 ? BDISP_RGB : BDISP_Y, + src_x_offset); + if (nid) + ctx->node[nid - 1]->nip = ctx->node_paddr[nid]; + nid++; + + /* Build additional Cb(Cr) node, link it to the previous one */ + if (cfg.dst_nbp > 1) { + bdisp_hw_build_node(ctx, &cfg, ctx->node[nid], + BDISP_CBCR, src_x_offset); + ctx->node[nid - 1]->nip = ctx->node_paddr[nid]; + nid++; + } + + /* Next stride until full width covered */ + src_x_offset += MAX_SRC_WIDTH; + if (src_x_offset >= ctx->src.crop.width) + break; + } + + /* Mark last node as the last */ + ctx->node[nid - 1]->nip = 0; + + return 0; +} + +/** + * bdisp_hw_update + * @ctx: device context + * + * Send the request to the HW + * + * RETURNS: + * 0 on success + */ +int bdisp_hw_update(struct bdisp_ctx *ctx) +{ + int ret; + struct bdisp_dev *bdisp = ctx->bdisp_dev; + struct device *dev = bdisp->dev; + unsigned int node_id; + + dev_dbg(dev, "%s\n", __func__); + + /* build nodes */ + ret = bdisp_hw_build_all_nodes(ctx); + if (ret) { + dev_err(dev, "cannot build nodes (%d)\n", ret); + return ret; + } + + /* Configure interrupt to 'Last Node Reached for AQ1' */ + writel(BLT_AQ1_CTL_CFG, bdisp->regs + BLT_AQ1_CTL); + writel(BLT_ITS_AQ1_LNA, bdisp->regs + BLT_ITM0); + + /* Write first node addr */ + writel(ctx->node_paddr[0], bdisp->regs + BLT_AQ1_IP); + + /* Find and write last node addr : this starts the HW processing */ + for (node_id = 0; node_id < MAX_NB_NODE - 1; node_id++) { + if (!ctx->node[node_id]->nip) + break; + } + writel(ctx->node_paddr[node_id], bdisp->regs + BLT_AQ1_LNA); + + return 0; +} diff --git a/drivers/media/platform/sti/bdisp/bdisp-reg.h b/drivers/media/platform/sti/bdisp/bdisp-reg.h new file mode 100644 index 000000000000..e7e1a425f65a --- /dev/null +++ b/drivers/media/platform/sti/bdisp/bdisp-reg.h @@ -0,0 +1,235 @@ +/* + * Copyright (C) STMicroelectronics SA 2014 + * Authors: Fabien Dessenne for STMicroelectronics. + * License terms: GNU General Public License (GPL), version 2 + */ + +struct bdisp_node { + /* 0 - General */ + u32 nip; + u32 cic; + u32 ins; + u32 ack; + /* 1 - Target */ + u32 tba; + u32 tty; + u32 txy; + u32 tsz; + /* 2 - Color Fill */ + u32 s1cf; + u32 s2cf; + /* 3 - Source 1 */ + u32 s1ba; + u32 s1ty; + u32 s1xy; + u32 s1sz_tsz; + /* 4 - Source 2 */ + u32 s2ba; + u32 s2ty; + u32 s2xy; + u32 s2sz; + /* 5 - Source 3 */ + u32 s3ba; + u32 s3ty; + u32 s3xy; + u32 s3sz; + /* 6 - Clipping */ + u32 cwo; + u32 cws; + /* 7 - CLUT */ + u32 cco; + u32 cml; + /* 8 - Filter & Mask */ + u32 fctl; + u32 pmk; + /* 9 - Chroma Filter */ + u32 rsf; + u32 rzi; + u32 hfp; + u32 vfp; + /* 10 - Luma Filter */ + u32 y_rsf; + u32 y_rzi; + u32 y_hfp; + u32 y_vfp; + /* 11 - Flicker */ + u32 ff0; + u32 ff1; + u32 ff2; + u32 ff3; + /* 12 - Color Key */ + u32 key1; + u32 key2; + /* 14 - Static Address & User */ + u32 sar; + u32 usr; + /* 15 - Input Versatile Matrix */ + u32 ivmx0; + u32 ivmx1; + u32 ivmx2; + u32 ivmx3; + /* 16 - Output Versatile Matrix */ + u32 ovmx0; + u32 ovmx1; + u32 ovmx2; + u32 ovmx3; + /* 17 - Pace */ + u32 pace; + /* 18 - VC1R & DEI */ + u32 vc1r; + u32 dei; + /* 19 - Gradient Fill */ + u32 hgf; + u32 vgf; +}; + +/* HW registers : static */ +#define BLT_CTL 0x0A00 +#define BLT_ITS 0x0A04 +#define BLT_STA1 0x0A08 +#define BLT_AQ1_CTL 0x0A60 +#define BLT_AQ1_IP 0x0A64 +#define BLT_AQ1_LNA 0x0A68 +#define BLT_AQ1_STA 0x0A6C +#define BLT_ITM0 0x0AD0 +/* HW registers : plugs */ +#define BLT_PLUGS1_OP2 0x0B04 +#define BLT_PLUGS1_CHZ 0x0B08 +#define BLT_PLUGS1_MSZ 0x0B0C +#define BLT_PLUGS1_PGZ 0x0B10 +#define BLT_PLUGS2_OP2 0x0B24 +#define BLT_PLUGS2_CHZ 0x0B28 +#define BLT_PLUGS2_MSZ 0x0B2C +#define BLT_PLUGS2_PGZ 0x0B30 +#define BLT_PLUGS3_OP2 0x0B44 +#define BLT_PLUGS3_CHZ 0x0B48 +#define BLT_PLUGS3_MSZ 0x0B4C +#define BLT_PLUGS3_PGZ 0x0B50 +#define BLT_PLUGT_OP2 0x0B84 +#define BLT_PLUGT_CHZ 0x0B88 +#define BLT_PLUGT_MSZ 0x0B8C +#define BLT_PLUGT_PGZ 0x0B90 +/* HW registers : node */ +#define BLT_NIP 0x0C00 +#define BLT_CIC 0x0C04 +#define BLT_INS 0x0C08 +#define BLT_ACK 0x0C0C +#define BLT_TBA 0x0C10 +#define BLT_TTY 0x0C14 +#define BLT_TXY 0x0C18 +#define BLT_TSZ 0x0C1C +#define BLT_S1BA 0x0C28 +#define BLT_S1TY 0x0C2C +#define BLT_S1XY 0x0C30 +#define BLT_S2BA 0x0C38 +#define BLT_S2TY 0x0C3C +#define BLT_S2XY 0x0C40 +#define BLT_S2SZ 0x0C44 +#define BLT_S3BA 0x0C48 +#define BLT_S3TY 0x0C4C +#define BLT_S3XY 0x0C50 +#define BLT_S3SZ 0x0C54 +#define BLT_FCTL 0x0C68 +#define BLT_RSF 0x0C70 +#define BLT_RZI 0x0C74 +#define BLT_HFP 0x0C78 +#define BLT_VFP 0x0C7C +#define BLT_Y_RSF 0x0C80 +#define BLT_Y_RZI 0x0C84 +#define BLT_Y_HFP 0x0C88 +#define BLT_Y_VFP 0x0C8C +#define BLT_IVMX0 0x0CC0 +#define BLT_IVMX1 0x0CC4 +#define BLT_IVMX2 0x0CC8 +#define BLT_IVMX3 0x0CCC +#define BLT_OVMX0 0x0CD0 +#define BLT_OVMX1 0x0CD4 +#define BLT_OVMX2 0x0CD8 +#define BLT_OVMX3 0x0CDC +#define BLT_DEI 0x0CEC +/* HW registers : filters */ +#define BLT_HFC_N 0x0D00 +#define BLT_VFC_N 0x0D90 +#define BLT_Y_HFC_N 0x0E00 +#define BLT_Y_VFC_N 0x0E90 +#define BLT_NB_H_COEF 16 +#define BLT_NB_V_COEF 10 + +/* Registers values */ +#define BLT_CTL_RESET BIT(31) /* Global soft reset */ + +#define BLT_ITS_AQ1_LNA BIT(12) /* AQ1 LNA reached */ + +#define BLT_STA1_IDLE BIT(0) /* BDISP idle */ + +#define BLT_AQ1_CTL_CFG 0x80400003 /* Enable, P3, LNA reached */ + +#define BLT_INS_S1_MASK (BIT(0) | BIT(1) | BIT(2)) +#define BLT_INS_S1_OFF 0x00000000 /* src1 disabled */ +#define BLT_INS_S1_MEM 0x00000001 /* src1 fetched from memory */ +#define BLT_INS_S1_CF 0x00000003 /* src1 color fill */ +#define BLT_INS_S1_COPY 0x00000004 /* src1 direct copy */ +#define BLT_INS_S1_FILL 0x00000007 /* src1 firect fill */ +#define BLT_INS_S2_MASK (BIT(3) | BIT(4)) +#define BLT_INS_S2_OFF 0x00000000 /* src2 disabled */ +#define BLT_INS_S2_MEM 0x00000008 /* src2 fetched from memory */ +#define BLT_INS_S2_CF 0x00000018 /* src2 color fill */ +#define BLT_INS_S3_MASK BIT(5) +#define BLT_INS_S3_OFF 0x00000000 /* src3 disabled */ +#define BLT_INS_S3_MEM 0x00000020 /* src3 fetched from memory */ +#define BLT_INS_IVMX BIT(6) /* Input versatile matrix */ +#define BLT_INS_CLUT BIT(7) /* Color Look Up Table */ +#define BLT_INS_SCALE BIT(8) /* Scaling */ +#define BLT_INS_FLICK BIT(9) /* Flicker filter */ +#define BLT_INS_CLIP BIT(10) /* Clipping */ +#define BLT_INS_CKEY BIT(11) /* Color key */ +#define BLT_INS_OVMX BIT(12) /* Output versatile matrix */ +#define BLT_INS_DEI BIT(13) /* Deinterlace */ +#define BLT_INS_PMASK BIT(14) /* Plane mask */ +#define BLT_INS_VC1R BIT(17) /* VC1 Range mapping */ +#define BLT_INS_ROTATE BIT(18) /* Rotation */ +#define BLT_INS_GRAD BIT(19) /* Gradient fill */ +#define BLT_INS_AQLOCK BIT(29) /* AQ lock */ +#define BLT_INS_PACE BIT(30) /* Pace down */ +#define BLT_INS_IRQ BIT(31) /* Raise IRQ when node done */ +#define BLT_CIC_ALL_GRP 0x000FDFFC /* all valid groups present */ +#define BLT_ACK_BYPASS_S2S3 0x00000007 /* Bypass src2 and src3 */ + +#define BLT_TTY_COL_SHIFT 16 /* Color format */ +#define BLT_TTY_COL_MASK 0x001F0000 /* Color format mask */ +#define BLT_TTY_ALPHA_R BIT(21) /* Alpha range */ +#define BLT_TTY_CR_NOT_CB BIT(22) /* CR not Cb */ +#define BLT_TTY_MB BIT(23) /* MB frame / field*/ +#define BLT_TTY_HSO BIT(24) /* H scan order */ +#define BLT_TTY_VSO BIT(25) /* V scan order */ +#define BLT_TTY_DITHER BIT(26) /* Dithering */ +#define BLT_TTY_CHROMA BIT(27) /* Write chroma / luma */ +#define BLT_TTY_BIG_END BIT(30) /* Big endianness */ + +#define BLT_S1TY_A1_SUBSET BIT(22) /* A1 subset */ +#define BLT_S1TY_CHROMA_EXT BIT(26) /* Chroma Extended */ +#define BTL_S1TY_SUBBYTE BIT(28) /* Sub-byte fmt, pixel order */ +#define BLT_S1TY_RGB_EXP BIT(29) /* RGB expansion mode */ + +#define BLT_S2TY_A1_SUBSET BIT(22) /* A1 subset */ +#define BLT_S2TY_CHROMA_EXT BIT(26) /* Chroma Extended */ +#define BTL_S2TY_SUBBYTE BIT(28) /* Sub-byte fmt, pixel order */ +#define BLT_S2TY_RGB_EXP BIT(29) /* RGB expansion mode */ + +#define BLT_S3TY_BLANK_ACC BIT(26) /* Blank access */ + +#define BLT_FCTL_HV_SCALE 0x00000055 /* H/V resize + color filter */ +#define BLT_FCTL_Y_HV_SCALE 0x33000000 /* Luma version */ + +#define BLT_FCTL_HV_SAMPLE 0x00000044 /* H/V resize */ +#define BLT_FCTL_Y_HV_SAMPLE 0x22000000 /* Luma version */ + +#define BLT_RZI_DEFAULT 0x20003000 /* H/VNB_repeat = 3/2 */ + +/* Color format */ +#define BDISP_RGB565 0x00 /* RGB565 */ +#define BDISP_RGB888 0x01 /* RGB888 */ +#define BDISP_XRGB8888 0x02 /* RGB888_32 */ +#define BDISP_ARGB8888 0x05 /* ARGB888 */ +#define BDISP_NV12 0x16 /* YCbCr42x R2B */ +#define BDISP_YUV_3B 0x1E /* YUV (3 buffer) */ diff --git a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c new file mode 100644 index 000000000000..6e8fd2747e8a --- /dev/null +++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c @@ -0,0 +1,1405 @@ +/* + * Copyright (C) STMicroelectronics SA 2014 + * Authors: Fabien Dessenne for STMicroelectronics. + * License terms: GNU General Public License (GPL), version 2 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "bdisp.h" + +#define BDISP_MAX_CTRL_NUM 10 + +#define BDISP_WORK_TIMEOUT ((100 * HZ) / 1000) + +/* User configuration change */ +#define BDISP_PARAMS BIT(0) /* Config updated */ +#define BDISP_SRC_FMT BIT(1) /* Source set */ +#define BDISP_DST_FMT BIT(2) /* Destination set */ +#define BDISP_CTX_STOP_REQ BIT(3) /* Stop request */ +#define BDISP_CTX_ABORT BIT(4) /* Abort while device run */ + +#define BDISP_MIN_W 1 +#define BDISP_MAX_W 8191 +#define BDISP_MIN_H 1 +#define BDISP_MAX_H 8191 + +#define fh_to_ctx(__fh) container_of(__fh, struct bdisp_ctx, fh) + +enum bdisp_dev_flags { + ST_M2M_OPEN, /* Driver opened */ + ST_M2M_RUNNING, /* HW device running */ + ST_M2M_SUSPENDED, /* Driver suspended */ + ST_M2M_SUSPENDING, /* Driver being suspended */ +}; + +static const struct bdisp_fmt bdisp_formats[] = { + /* ARGB888. [31:0] A:R:G:B 8:8:8:8 little endian */ + { + .pixelformat = V4L2_PIX_FMT_ABGR32, /* is actually ARGB */ + .nb_planes = 1, + .bpp = 32, + .bpp_plane0 = 32, + .w_align = 1, + .h_align = 1 + }, + /* XRGB888. [31:0] x:R:G:B 8:8:8:8 little endian */ + { + .pixelformat = V4L2_PIX_FMT_XBGR32, /* is actually xRGB */ + .nb_planes = 1, + .bpp = 32, + .bpp_plane0 = 32, + .w_align = 1, + .h_align = 1 + }, + /* RGB565. [15:0] R:G:B 5:6:5 little endian */ + { + .pixelformat = V4L2_PIX_FMT_RGB565, + .nb_planes = 1, + .bpp = 16, + .bpp_plane0 = 16, + .w_align = 1, + .h_align = 1 + }, + /* NV12. YUV420SP - 1 plane for Y + 1 plane for (CbCr) */ + { + .pixelformat = V4L2_PIX_FMT_NV12, + .nb_planes = 2, + .bpp = 12, + .bpp_plane0 = 8, + .w_align = 2, + .h_align = 2 + }, + /* RGB888. [23:0] B:G:R 8:8:8 little endian */ + { + .pixelformat = V4L2_PIX_FMT_RGB24, + .nb_planes = 1, + .bpp = 24, + .bpp_plane0 = 24, + .w_align = 1, + .h_align = 1 + }, + /* YU12. YUV420P - 1 plane for Y + 1 plane for Cb + 1 plane for Cr + * To keep as the LAST element of this table (no support on capture) + */ + { + .pixelformat = V4L2_PIX_FMT_YUV420, + .nb_planes = 3, + .bpp = 12, + .bpp_plane0 = 8, + .w_align = 2, + .h_align = 2 + } +}; + +/* Default format : HD ARGB32*/ +#define BDISP_DEF_WIDTH 1920 +#define BDISP_DEF_HEIGHT 1080 + +static const struct bdisp_frame bdisp_dflt_fmt = { + .width = BDISP_DEF_WIDTH, + .height = BDISP_DEF_HEIGHT, + .fmt = &bdisp_formats[0], + .field = V4L2_FIELD_NONE, + .bytesperline = BDISP_DEF_WIDTH * 4, + .sizeimage = BDISP_DEF_WIDTH * BDISP_DEF_HEIGHT * 4, + .colorspace = V4L2_COLORSPACE_REC709, + .crop = {0, 0, BDISP_DEF_WIDTH, BDISP_DEF_HEIGHT}, + .paddr = {0, 0, 0, 0} +}; + +static inline void bdisp_ctx_state_lock_set(u32 state, struct bdisp_ctx *ctx) +{ + unsigned long flags; + + spin_lock_irqsave(&ctx->bdisp_dev->slock, flags); + ctx->state |= state; + spin_unlock_irqrestore(&ctx->bdisp_dev->slock, flags); +} + +static inline void bdisp_ctx_state_lock_clear(u32 state, struct bdisp_ctx *ctx) +{ + unsigned long flags; + + spin_lock_irqsave(&ctx->bdisp_dev->slock, flags); + ctx->state &= ~state; + spin_unlock_irqrestore(&ctx->bdisp_dev->slock, flags); +} + +static inline bool bdisp_ctx_state_is_set(u32 mask, struct bdisp_ctx *ctx) +{ + unsigned long flags; + bool ret; + + spin_lock_irqsave(&ctx->bdisp_dev->slock, flags); + ret = (ctx->state & mask) == mask; + spin_unlock_irqrestore(&ctx->bdisp_dev->slock, flags); + + return ret; +} + +static const struct bdisp_fmt *bdisp_find_fmt(u32 pixelformat) +{ + const struct bdisp_fmt *fmt; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(bdisp_formats); i++) { + fmt = &bdisp_formats[i]; + if (fmt->pixelformat == pixelformat) + return fmt; + } + + return NULL; +} + +static struct bdisp_frame *ctx_get_frame(struct bdisp_ctx *ctx, + enum v4l2_buf_type type) +{ + switch (type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + return &ctx->src; + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + return &ctx->dst; + default: + dev_err(ctx->bdisp_dev->dev, + "Wrong buffer/video queue type (%d)\n", type); + break; + } + + return ERR_PTR(-EINVAL); +} + +static void bdisp_job_finish(struct bdisp_ctx *ctx, int vb_state) +{ + struct vb2_buffer *src_vb, *dst_vb; + + if (WARN(!ctx || !ctx->fh.m2m_ctx, "Null hardware context\n")) + return; + + dev_dbg(ctx->bdisp_dev->dev, "%s\n", __func__); + + src_vb = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + dst_vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + + if (src_vb && dst_vb) { + dst_vb->v4l2_buf.timestamp = src_vb->v4l2_buf.timestamp; + dst_vb->v4l2_buf.timecode = src_vb->v4l2_buf.timecode; + dst_vb->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK; + dst_vb->v4l2_buf.flags |= src_vb->v4l2_buf.flags & + V4L2_BUF_FLAG_TSTAMP_SRC_MASK; + + v4l2_m2m_buf_done(src_vb, vb_state); + v4l2_m2m_buf_done(dst_vb, vb_state); + + v4l2_m2m_job_finish(ctx->bdisp_dev->m2m.m2m_dev, + ctx->fh.m2m_ctx); + } +} + +static int bdisp_ctx_stop_req(struct bdisp_ctx *ctx) +{ + struct bdisp_ctx *curr_ctx; + struct bdisp_dev *bdisp = ctx->bdisp_dev; + int ret; + + dev_dbg(ctx->bdisp_dev->dev, "%s\n", __func__); + + cancel_delayed_work(&bdisp->timeout_work); + + curr_ctx = v4l2_m2m_get_curr_priv(bdisp->m2m.m2m_dev); + if (!test_bit(ST_M2M_RUNNING, &bdisp->state) || (curr_ctx != ctx)) + return 0; + + bdisp_ctx_state_lock_set(BDISP_CTX_STOP_REQ, ctx); + + ret = wait_event_timeout(bdisp->irq_queue, + !bdisp_ctx_state_is_set(BDISP_CTX_STOP_REQ, ctx), + BDISP_WORK_TIMEOUT); + + if (!ret) { + dev_err(ctx->bdisp_dev->dev, "%s IRQ timeout\n", __func__); + return -ETIMEDOUT; + } + + return 0; +} + +static void __bdisp_job_abort(struct bdisp_ctx *ctx) +{ + int ret; + + ret = bdisp_ctx_stop_req(ctx); + if ((ret == -ETIMEDOUT) || (ctx->state & BDISP_CTX_ABORT)) { + bdisp_ctx_state_lock_clear(BDISP_CTX_STOP_REQ | BDISP_CTX_ABORT, + ctx); + bdisp_job_finish(ctx, VB2_BUF_STATE_ERROR); + } +} + +static void bdisp_job_abort(void *priv) +{ + __bdisp_job_abort((struct bdisp_ctx *)priv); +} + +static int bdisp_get_addr(struct bdisp_ctx *ctx, struct vb2_buffer *vb, + struct bdisp_frame *frame, dma_addr_t *paddr) +{ + if (!vb || !frame) + return -EINVAL; + + paddr[0] = vb2_dma_contig_plane_dma_addr(vb, 0); + + if (frame->fmt->nb_planes > 1) + /* UV (NV12) or U (420P) */ + paddr[1] = (dma_addr_t)(paddr[0] + + frame->bytesperline * frame->height); + + if (frame->fmt->nb_planes > 2) + /* V (420P) */ + paddr[2] = (dma_addr_t)(paddr[1] + + (frame->bytesperline * frame->height) / 4); + + if (frame->fmt->nb_planes > 3) + dev_dbg(ctx->bdisp_dev->dev, "ignoring some planes\n"); + + dev_dbg(ctx->bdisp_dev->dev, + "%s plane[0]=%pad plane[1]=%pad plane[2]=%pad\n", + __func__, &paddr[0], &paddr[1], &paddr[2]); + + return 0; +} + +static int bdisp_get_bufs(struct bdisp_ctx *ctx) +{ + struct bdisp_frame *src, *dst; + struct vb2_buffer *src_vb, *dst_vb; + int ret; + + src = &ctx->src; + dst = &ctx->dst; + + src_vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); + ret = bdisp_get_addr(ctx, src_vb, src, src->paddr); + if (ret) + return ret; + + dst_vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); + ret = bdisp_get_addr(ctx, dst_vb, dst, dst->paddr); + if (ret) + return ret; + + dst_vb->v4l2_buf.timestamp = src_vb->v4l2_buf.timestamp; + + return 0; +} + +static void bdisp_device_run(void *priv) +{ + struct bdisp_ctx *ctx = priv; + struct bdisp_dev *bdisp; + unsigned long flags; + int err = 0; + + if (WARN(!ctx, "Null hardware context\n")) + return; + + bdisp = ctx->bdisp_dev; + dev_dbg(bdisp->dev, "%s\n", __func__); + spin_lock_irqsave(&bdisp->slock, flags); + + if (bdisp->m2m.ctx != ctx) { + dev_dbg(bdisp->dev, "ctx updated: %p -> %p\n", + bdisp->m2m.ctx, ctx); + ctx->state |= BDISP_PARAMS; + bdisp->m2m.ctx = ctx; + } + + if (ctx->state & BDISP_CTX_STOP_REQ) { + ctx->state &= ~BDISP_CTX_STOP_REQ; + ctx->state |= BDISP_CTX_ABORT; + wake_up(&bdisp->irq_queue); + goto out; + } + + err = bdisp_get_bufs(ctx); + if (err) { + dev_err(bdisp->dev, "cannot get address\n"); + goto out; + } + + err = bdisp_hw_reset(bdisp); + if (err) { + dev_err(bdisp->dev, "could not get HW ready\n"); + goto out; + } + + err = bdisp_hw_update(ctx); + if (err) { + dev_err(bdisp->dev, "could not send HW request\n"); + goto out; + } + + queue_delayed_work(bdisp->work_queue, &bdisp->timeout_work, + BDISP_WORK_TIMEOUT); + set_bit(ST_M2M_RUNNING, &bdisp->state); +out: + ctx->state &= ~BDISP_PARAMS; + spin_unlock_irqrestore(&bdisp->slock, flags); + if (err) + bdisp_job_finish(ctx, VB2_BUF_STATE_ERROR); +} + +static struct v4l2_m2m_ops bdisp_m2m_ops = { + .device_run = bdisp_device_run, + .job_abort = bdisp_job_abort, +}; + +static int __bdisp_s_ctrl(struct bdisp_ctx *ctx, struct v4l2_ctrl *ctrl) +{ + if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE) + return 0; + + switch (ctrl->id) { + case V4L2_CID_HFLIP: + ctx->hflip = ctrl->val; + break; + case V4L2_CID_VFLIP: + ctx->vflip = ctrl->val; + break; + default: + dev_err(ctx->bdisp_dev->dev, "unknown control %d\n", ctrl->id); + return -EINVAL; + } + + ctx->state |= BDISP_PARAMS; + + return 0; +} + +static int bdisp_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct bdisp_ctx *ctx = container_of(ctrl->handler, struct bdisp_ctx, + ctrl_handler); + unsigned long flags; + int ret; + + spin_lock_irqsave(&ctx->bdisp_dev->slock, flags); + ret = __bdisp_s_ctrl(ctx, ctrl); + spin_unlock_irqrestore(&ctx->bdisp_dev->slock, flags); + + return ret; +} + +static const struct v4l2_ctrl_ops bdisp_c_ops = { + .s_ctrl = bdisp_s_ctrl, +}; + +static int bdisp_ctrls_create(struct bdisp_ctx *ctx) +{ + if (ctx->ctrls_rdy) + return 0; + + v4l2_ctrl_handler_init(&ctx->ctrl_handler, BDISP_MAX_CTRL_NUM); + + ctx->bdisp_ctrls.hflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, + &bdisp_c_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); + ctx->bdisp_ctrls.vflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, + &bdisp_c_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); + + if (ctx->ctrl_handler.error) { + int err = ctx->ctrl_handler.error; + + v4l2_ctrl_handler_free(&ctx->ctrl_handler); + return err; + } + + ctx->ctrls_rdy = true; + + return 0; +} + +static void bdisp_ctrls_delete(struct bdisp_ctx *ctx) +{ + if (ctx->ctrls_rdy) { + v4l2_ctrl_handler_free(&ctx->ctrl_handler); + ctx->ctrls_rdy = false; + } +} + +static int bdisp_queue_setup(struct vb2_queue *vq, + const struct v4l2_format *fmt, + unsigned int *nb_buf, unsigned int *nb_planes, + unsigned int sizes[], void *allocators[]) +{ + struct bdisp_ctx *ctx = vb2_get_drv_priv(vq); + struct bdisp_frame *frame = ctx_get_frame(ctx, vq->type); + + if (IS_ERR(frame)) { + dev_err(ctx->bdisp_dev->dev, "Invalid frame (%p)\n", frame); + return PTR_ERR(frame); + } + + if (!frame->fmt) { + dev_err(ctx->bdisp_dev->dev, "Invalid format\n"); + return -EINVAL; + } + + if (fmt && fmt->fmt.pix.sizeimage < frame->sizeimage) + return -EINVAL; + + *nb_planes = 1; + sizes[0] = fmt ? fmt->fmt.pix.sizeimage : frame->sizeimage; + allocators[0] = ctx->bdisp_dev->alloc_ctx; + + return 0; +} + +static int bdisp_buf_prepare(struct vb2_buffer *vb) +{ + struct bdisp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct bdisp_frame *frame = ctx_get_frame(ctx, vb->vb2_queue->type); + + if (IS_ERR(frame)) { + dev_err(ctx->bdisp_dev->dev, "Invalid frame (%p)\n", frame); + return PTR_ERR(frame); + } + + if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + vb2_set_plane_payload(vb, 0, frame->sizeimage); + + return 0; +} + +static void bdisp_buf_queue(struct vb2_buffer *vb) +{ + struct bdisp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + + /* return to V4L2 any 0-size buffer so it can be dequeued by user */ + if (!vb2_get_plane_payload(vb, 0)) { + dev_dbg(ctx->bdisp_dev->dev, "0 data buffer, skip it\n"); + vb2_buffer_done(vb, VB2_BUF_STATE_DONE); + return; + } + + if (ctx->fh.m2m_ctx) + v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb); +} + +static int bdisp_start_streaming(struct vb2_queue *q, unsigned int count) +{ + struct bdisp_ctx *ctx = q->drv_priv; + struct vb2_buffer *buf; + int ret = pm_runtime_get_sync(ctx->bdisp_dev->dev); + + if (ret < 0) { + dev_err(ctx->bdisp_dev->dev, "failed to set runtime PM\n"); + + if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { + while ((buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx))) + v4l2_m2m_buf_done(buf, VB2_BUF_STATE_QUEUED); + } else { + while ((buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx))) + v4l2_m2m_buf_done(buf, VB2_BUF_STATE_QUEUED); + } + + return ret; + } + + return 0; +} + +static void bdisp_stop_streaming(struct vb2_queue *q) +{ + struct bdisp_ctx *ctx = q->drv_priv; + + __bdisp_job_abort(ctx); + + pm_runtime_put(ctx->bdisp_dev->dev); +} + +static struct vb2_ops bdisp_qops = { + .queue_setup = bdisp_queue_setup, + .buf_prepare = bdisp_buf_prepare, + .buf_queue = bdisp_buf_queue, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, + .stop_streaming = bdisp_stop_streaming, + .start_streaming = bdisp_start_streaming, +}; + +static int queue_init(void *priv, + struct vb2_queue *src_vq, struct vb2_queue *dst_vq) +{ + struct bdisp_ctx *ctx = priv; + int ret; + + memset(src_vq, 0, sizeof(*src_vq)); + src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + src_vq->io_modes = VB2_MMAP | VB2_DMABUF; + src_vq->drv_priv = ctx; + src_vq->ops = &bdisp_qops; + src_vq->mem_ops = &vb2_dma_contig_memops; + src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); + src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; + src_vq->lock = &ctx->bdisp_dev->lock; + + ret = vb2_queue_init(src_vq); + if (ret) + return ret; + + memset(dst_vq, 0, sizeof(*dst_vq)); + dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; + dst_vq->drv_priv = ctx; + dst_vq->ops = &bdisp_qops; + dst_vq->mem_ops = &vb2_dma_contig_memops; + dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); + dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; + dst_vq->lock = &ctx->bdisp_dev->lock; + + return vb2_queue_init(dst_vq); +} + +static int bdisp_open(struct file *file) +{ + struct bdisp_dev *bdisp = video_drvdata(file); + struct bdisp_ctx *ctx = NULL; + int ret; + + if (mutex_lock_interruptible(&bdisp->lock)) + return -ERESTARTSYS; + + /* Allocate memory for both context and node */ + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) { + ret = -ENOMEM; + goto unlock; + } + ctx->bdisp_dev = bdisp; + + if (bdisp_hw_alloc_nodes(ctx)) { + dev_err(bdisp->dev, "no memory for nodes\n"); + ret = -ENOMEM; + goto mem_ctx; + } + + v4l2_fh_init(&ctx->fh, bdisp->m2m.vdev); + + ret = bdisp_ctrls_create(ctx); + if (ret) { + dev_err(bdisp->dev, "Failed to create control\n"); + goto error_fh; + } + + /* Use separate control handler per file handle */ + ctx->fh.ctrl_handler = &ctx->ctrl_handler; + file->private_data = &ctx->fh; + v4l2_fh_add(&ctx->fh); + + /* Default format */ + ctx->src = bdisp_dflt_fmt; + ctx->dst = bdisp_dflt_fmt; + + /* Setup the device context for mem2mem mode. */ + ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(bdisp->m2m.m2m_dev, ctx, + queue_init); + if (IS_ERR(ctx->fh.m2m_ctx)) { + dev_err(bdisp->dev, "Failed to initialize m2m context\n"); + ret = PTR_ERR(ctx->fh.m2m_ctx); + goto error_ctrls; + } + + bdisp->m2m.refcnt++; + set_bit(ST_M2M_OPEN, &bdisp->state); + + dev_dbg(bdisp->dev, "driver opened, ctx = 0x%p\n", ctx); + + mutex_unlock(&bdisp->lock); + + return 0; + +error_ctrls: + bdisp_ctrls_delete(ctx); +error_fh: + v4l2_fh_del(&ctx->fh); + v4l2_fh_exit(&ctx->fh); + bdisp_hw_free_nodes(ctx); +mem_ctx: + kfree(ctx); +unlock: + mutex_unlock(&bdisp->lock); + + return ret; +} + +static int bdisp_release(struct file *file) +{ + struct bdisp_ctx *ctx = fh_to_ctx(file->private_data); + struct bdisp_dev *bdisp = ctx->bdisp_dev; + + dev_dbg(bdisp->dev, "%s\n", __func__); + + if (mutex_lock_interruptible(&bdisp->lock)) + return -ERESTARTSYS; + + v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); + + bdisp_ctrls_delete(ctx); + + v4l2_fh_del(&ctx->fh); + v4l2_fh_exit(&ctx->fh); + + if (--bdisp->m2m.refcnt <= 0) + clear_bit(ST_M2M_OPEN, &bdisp->state); + + bdisp_hw_free_nodes(ctx); + + kfree(ctx); + + mutex_unlock(&bdisp->lock); + + return 0; +} + +static const struct v4l2_file_operations bdisp_fops = { + .owner = THIS_MODULE, + .open = bdisp_open, + .release = bdisp_release, + .poll = v4l2_m2m_fop_poll, + .unlocked_ioctl = video_ioctl2, + .mmap = v4l2_m2m_fop_mmap, +}; + +static int bdisp_querycap(struct file *file, void *fh, + struct v4l2_capability *cap) +{ + struct bdisp_ctx *ctx = fh_to_ctx(fh); + struct bdisp_dev *bdisp = ctx->bdisp_dev; + + strlcpy(cap->driver, bdisp->pdev->name, sizeof(cap->driver)); + strlcpy(cap->card, bdisp->pdev->name, sizeof(cap->card)); + snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s%d", + BDISP_NAME, bdisp->id); + + cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M; + + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; + + return 0; +} + +static int bdisp_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f) +{ + struct bdisp_ctx *ctx = fh_to_ctx(fh); + const struct bdisp_fmt *fmt; + + if (f->index >= ARRAY_SIZE(bdisp_formats)) + return -EINVAL; + + fmt = &bdisp_formats[f->index]; + + if ((fmt->pixelformat == V4L2_PIX_FMT_YUV420) && + (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)) { + dev_dbg(ctx->bdisp_dev->dev, "No YU12 on capture\n"); + return -EINVAL; + } + f->pixelformat = fmt->pixelformat; + + return 0; +} + +static int bdisp_g_fmt(struct file *file, void *fh, struct v4l2_format *f) +{ + struct bdisp_ctx *ctx = fh_to_ctx(fh); + struct v4l2_pix_format *pix = &f->fmt.pix; + struct bdisp_frame *frame = ctx_get_frame(ctx, f->type); + + if (IS_ERR(frame)) { + dev_err(ctx->bdisp_dev->dev, "Invalid frame (%p)\n", frame); + return PTR_ERR(frame); + } + + pix = &f->fmt.pix; + pix->width = frame->width; + pix->height = frame->height; + pix->pixelformat = frame->fmt->pixelformat; + pix->field = frame->field; + pix->bytesperline = frame->bytesperline; + pix->sizeimage = frame->sizeimage; + pix->colorspace = (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ? + frame->colorspace : bdisp_dflt_fmt.colorspace; + + return 0; +} + +static int bdisp_try_fmt(struct file *file, void *fh, struct v4l2_format *f) +{ + struct bdisp_ctx *ctx = fh_to_ctx(fh); + struct v4l2_pix_format *pix = &f->fmt.pix; + const struct bdisp_fmt *format; + u32 in_w, in_h; + + format = bdisp_find_fmt(pix->pixelformat); + if (!format) { + dev_dbg(ctx->bdisp_dev->dev, "Unknown format 0x%x\n", + pix->pixelformat); + return -EINVAL; + } + + /* YUV420P only supported for VIDEO_OUTPUT */ + if ((format->pixelformat == V4L2_PIX_FMT_YUV420) && + (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)) { + dev_dbg(ctx->bdisp_dev->dev, "No YU12 on capture\n"); + return -EINVAL; + } + + /* Field (interlaced only supported on OUTPUT) */ + if ((f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) || + (pix->field != V4L2_FIELD_INTERLACED)) + pix->field = V4L2_FIELD_NONE; + + /* Adjust width & height */ + in_w = pix->width; + in_h = pix->height; + v4l_bound_align_image(&pix->width, + BDISP_MIN_W, BDISP_MAX_W, + ffs(format->w_align) - 1, + &pix->height, + BDISP_MIN_H, BDISP_MAX_H, + ffs(format->h_align) - 1, + 0); + if ((pix->width != in_w) || (pix->height != in_h)) + dev_dbg(ctx->bdisp_dev->dev, + "%s size updated: %dx%d -> %dx%d\n", __func__, + in_w, in_h, pix->width, pix->height); + + pix->bytesperline = (pix->width * format->bpp_plane0) / 8; + pix->sizeimage = (pix->width * pix->height * format->bpp) / 8; + + if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + pix->colorspace = bdisp_dflt_fmt.colorspace; + + return 0; +} + +static int bdisp_s_fmt(struct file *file, void *fh, struct v4l2_format *f) +{ + struct bdisp_ctx *ctx = fh_to_ctx(fh); + struct vb2_queue *vq; + struct bdisp_frame *frame; + struct v4l2_pix_format *pix; + int ret; + u32 state; + + ret = bdisp_try_fmt(file, fh, f); + if (ret) { + dev_err(ctx->bdisp_dev->dev, "Cannot set format\n"); + return ret; + } + + vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); + if (vb2_is_streaming(vq)) { + dev_err(ctx->bdisp_dev->dev, "queue (%d) busy\n", f->type); + return -EBUSY; + } + + frame = (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ? + &ctx->src : &ctx->dst; + pix = &f->fmt.pix; + frame->fmt = bdisp_find_fmt(pix->pixelformat); + if (!frame->fmt) { + dev_err(ctx->bdisp_dev->dev, "Unknown format 0x%x\n", + pix->pixelformat); + return -EINVAL; + } + + frame->width = pix->width; + frame->height = pix->height; + frame->bytesperline = pix->bytesperline; + frame->sizeimage = pix->sizeimage; + frame->field = pix->field; + if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) + frame->colorspace = pix->colorspace; + + frame->crop.width = frame->width; + frame->crop.height = frame->height; + frame->crop.left = 0; + frame->crop.top = 0; + + state = BDISP_PARAMS; + state |= (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) ? + BDISP_DST_FMT : BDISP_SRC_FMT; + bdisp_ctx_state_lock_set(state, ctx); + + return 0; +} + +static int bdisp_g_selection(struct file *file, void *fh, + struct v4l2_selection *s) +{ + struct bdisp_frame *frame; + struct bdisp_ctx *ctx = fh_to_ctx(fh); + + if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) { + /* Composing / capture is not supported */ + dev_dbg(ctx->bdisp_dev->dev, "Not supported for capture\n"); + return -EINVAL; + } + + frame = ctx_get_frame(ctx, s->type); + if (IS_ERR(frame)) { + dev_err(ctx->bdisp_dev->dev, "Invalid frame (%p)\n", frame); + return PTR_ERR(frame); + } + + switch (s->target) { + case V4L2_SEL_TGT_CROP: + /* cropped frame */ + s->r = frame->crop; + break; + case V4L2_SEL_TGT_CROP_DEFAULT: + case V4L2_SEL_TGT_CROP_BOUNDS: + /* complete frame */ + s->r.left = 0; + s->r.top = 0; + s->r.width = frame->width; + s->r.height = frame->height; + break; + default: + dev_dbg(ctx->bdisp_dev->dev, "Invalid target\n"); + return -EINVAL; + } + + return 0; +} + +static int is_rect_enclosed(struct v4l2_rect *a, struct v4l2_rect *b) +{ + /* Return 1 if a is enclosed in b, or 0 otherwise. */ + + if (a->left < b->left || a->top < b->top) + return 0; + + if (a->left + a->width > b->left + b->width) + return 0; + + if (a->top + a->height > b->top + b->height) + return 0; + + return 1; +} + +static int bdisp_s_selection(struct file *file, void *fh, + struct v4l2_selection *s) +{ + struct bdisp_frame *frame; + struct bdisp_ctx *ctx = fh_to_ctx(fh); + struct v4l2_rect *in, out; + + if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) { + /* Composing / capture is not supported */ + dev_dbg(ctx->bdisp_dev->dev, "Not supported for capture\n"); + return -EINVAL; + } + + if (s->target != V4L2_SEL_TGT_CROP) { + dev_dbg(ctx->bdisp_dev->dev, "Invalid target\n"); + return -EINVAL; + } + + frame = ctx_get_frame(ctx, s->type); + if (IS_ERR(frame)) { + dev_err(ctx->bdisp_dev->dev, "Invalid frame (%p)\n", frame); + return PTR_ERR(frame); + } + + in = &s->r; + out = *in; + + /* Align and check origin */ + out.left = ALIGN(in->left, frame->fmt->w_align); + out.top = ALIGN(in->top, frame->fmt->h_align); + + if ((out.left < 0) || (out.left >= frame->width) || + (out.top < 0) || (out.top >= frame->height)) { + dev_err(ctx->bdisp_dev->dev, + "Invalid crop: %dx%d@(%d,%d) vs frame: %dx%d\n", + out.width, out.height, out.left, out.top, + frame->width, frame->height); + return -EINVAL; + } + + /* Align and check size */ + out.width = ALIGN(in->width, frame->fmt->w_align); + out.height = ALIGN(in->height, frame->fmt->w_align); + + if ((out.width < 0) || (out.height < 0) || + ((out.left + out.width) > frame->width) || + ((out.top + out.height) > frame->height)) { + dev_err(ctx->bdisp_dev->dev, + "Invalid crop: %dx%d@(%d,%d) vs frame: %dx%d\n", + out.width, out.height, out.left, out.top, + frame->width, frame->height); + return -EINVAL; + } + + /* Checks adjust constraints flags */ + if (s->flags & V4L2_SEL_FLAG_LE && !is_rect_enclosed(&out, in)) + return -ERANGE; + + if (s->flags & V4L2_SEL_FLAG_GE && !is_rect_enclosed(in, &out)) + return -ERANGE; + + if ((out.left != in->left) || (out.top != in->top) || + (out.width != in->width) || (out.height != in->height)) { + dev_dbg(ctx->bdisp_dev->dev, + "%s crop updated: %dx%d@(%d,%d) -> %dx%d@(%d,%d)\n", + __func__, in->width, in->height, in->left, in->top, + out.width, out.height, out.left, out.top); + *in = out; + } + + frame->crop = out; + + bdisp_ctx_state_lock_set(BDISP_PARAMS, ctx); + + return 0; +} + +static int bdisp_streamon(struct file *file, void *fh, enum v4l2_buf_type type) +{ + struct bdisp_ctx *ctx = fh_to_ctx(fh); + + if ((type == V4L2_BUF_TYPE_VIDEO_OUTPUT) && + !bdisp_ctx_state_is_set(BDISP_SRC_FMT, ctx)) { + dev_err(ctx->bdisp_dev->dev, "src not defined\n"); + return -EINVAL; + } + + if ((type == V4L2_BUF_TYPE_VIDEO_CAPTURE) && + !bdisp_ctx_state_is_set(BDISP_DST_FMT, ctx)) { + dev_err(ctx->bdisp_dev->dev, "dst not defined\n"); + return -EINVAL; + } + + return v4l2_m2m_streamon(file, ctx->fh.m2m_ctx, type); +} + +static const struct v4l2_ioctl_ops bdisp_ioctl_ops = { + .vidioc_querycap = bdisp_querycap, + .vidioc_enum_fmt_vid_cap = bdisp_enum_fmt, + .vidioc_enum_fmt_vid_out = bdisp_enum_fmt, + .vidioc_g_fmt_vid_cap = bdisp_g_fmt, + .vidioc_g_fmt_vid_out = bdisp_g_fmt, + .vidioc_try_fmt_vid_cap = bdisp_try_fmt, + .vidioc_try_fmt_vid_out = bdisp_try_fmt, + .vidioc_s_fmt_vid_cap = bdisp_s_fmt, + .vidioc_s_fmt_vid_out = bdisp_s_fmt, + .vidioc_g_selection = bdisp_g_selection, + .vidioc_s_selection = bdisp_s_selection, + .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, + .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, + .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, + .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, + .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, + .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, + .vidioc_streamon = bdisp_streamon, + .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, +}; + +static int bdisp_register_device(struct bdisp_dev *bdisp) +{ + struct platform_device *pdev; + int ret; + + if (!bdisp) + return -ENODEV; + + pdev = bdisp->pdev; + + bdisp->vdev.fops = &bdisp_fops; + bdisp->vdev.ioctl_ops = &bdisp_ioctl_ops; + bdisp->vdev.release = video_device_release_empty; + bdisp->vdev.lock = &bdisp->lock; + bdisp->vdev.vfl_dir = VFL_DIR_M2M; + bdisp->vdev.v4l2_dev = &bdisp->v4l2_dev; + snprintf(bdisp->vdev.name, sizeof(bdisp->vdev.name), "%s.%d", + BDISP_NAME, bdisp->id); + + video_set_drvdata(&bdisp->vdev, bdisp); + + bdisp->m2m.vdev = &bdisp->vdev; + bdisp->m2m.m2m_dev = v4l2_m2m_init(&bdisp_m2m_ops); + if (IS_ERR(bdisp->m2m.m2m_dev)) { + dev_err(bdisp->dev, "failed to initialize v4l2-m2m device\n"); + return PTR_ERR(bdisp->m2m.m2m_dev); + } + + ret = video_register_device(&bdisp->vdev, VFL_TYPE_GRABBER, -1); + if (ret) { + dev_err(bdisp->dev, + "%s(): failed to register video device\n", __func__); + v4l2_m2m_release(bdisp->m2m.m2m_dev); + return ret; + } + + return 0; +} + +static void bdisp_unregister_device(struct bdisp_dev *bdisp) +{ + if (!bdisp) + return; + + if (bdisp->m2m.m2m_dev) + v4l2_m2m_release(bdisp->m2m.m2m_dev); + + video_unregister_device(bdisp->m2m.vdev); +} + +static irqreturn_t bdisp_irq_thread(int irq, void *priv) +{ + struct bdisp_dev *bdisp = priv; + struct bdisp_ctx *ctx; + + spin_lock(&bdisp->slock); + + cancel_delayed_work(&bdisp->timeout_work); + + if (!test_and_clear_bit(ST_M2M_RUNNING, &bdisp->state)) + goto isr_unlock; + + if (test_and_clear_bit(ST_M2M_SUSPENDING, &bdisp->state)) { + set_bit(ST_M2M_SUSPENDED, &bdisp->state); + wake_up(&bdisp->irq_queue); + goto isr_unlock; + } + + ctx = v4l2_m2m_get_curr_priv(bdisp->m2m.m2m_dev); + if (!ctx || !ctx->fh.m2m_ctx) + goto isr_unlock; + + spin_unlock(&bdisp->slock); + + bdisp_job_finish(ctx, VB2_BUF_STATE_DONE); + + if (bdisp_ctx_state_is_set(BDISP_CTX_STOP_REQ, ctx)) { + bdisp_ctx_state_lock_clear(BDISP_CTX_STOP_REQ, ctx); + wake_up(&bdisp->irq_queue); + } + + return IRQ_HANDLED; + +isr_unlock: + spin_unlock(&bdisp->slock); + + return IRQ_HANDLED; +} + +static irqreturn_t bdisp_irq_handler(int irq, void *priv) +{ + if (bdisp_hw_get_and_clear_irq((struct bdisp_dev *)priv)) + return IRQ_NONE; + else + return IRQ_WAKE_THREAD; +} + +static void bdisp_irq_timeout(struct work_struct *ptr) +{ + struct delayed_work *twork = to_delayed_work(ptr); + struct bdisp_dev *bdisp = container_of(twork, struct bdisp_dev, + timeout_work); + struct bdisp_ctx *ctx; + + ctx = v4l2_m2m_get_curr_priv(bdisp->m2m.m2m_dev); + + dev_err(ctx->bdisp_dev->dev, "Device work timeout\n"); + + spin_lock(&bdisp->slock); + clear_bit(ST_M2M_RUNNING, &bdisp->state); + spin_unlock(&bdisp->slock); + + bdisp_hw_reset(bdisp); + + bdisp_job_finish(ctx, VB2_BUF_STATE_ERROR); +} + +static int bdisp_m2m_suspend(struct bdisp_dev *bdisp) +{ + unsigned long flags; + int timeout; + + spin_lock_irqsave(&bdisp->slock, flags); + if (!test_bit(ST_M2M_RUNNING, &bdisp->state)) { + spin_unlock_irqrestore(&bdisp->slock, flags); + return 0; + } + clear_bit(ST_M2M_SUSPENDED, &bdisp->state); + set_bit(ST_M2M_SUSPENDING, &bdisp->state); + spin_unlock_irqrestore(&bdisp->slock, flags); + + timeout = wait_event_timeout(bdisp->irq_queue, + test_bit(ST_M2M_SUSPENDED, &bdisp->state), + BDISP_WORK_TIMEOUT); + + clear_bit(ST_M2M_SUSPENDING, &bdisp->state); + + if (!timeout) { + dev_err(bdisp->dev, "%s IRQ timeout\n", __func__); + return -EAGAIN; + } + + return 0; +} + +static int bdisp_m2m_resume(struct bdisp_dev *bdisp) +{ + struct bdisp_ctx *ctx; + unsigned long flags; + + spin_lock_irqsave(&bdisp->slock, flags); + ctx = bdisp->m2m.ctx; + bdisp->m2m.ctx = NULL; + spin_unlock_irqrestore(&bdisp->slock, flags); + + if (test_and_clear_bit(ST_M2M_SUSPENDED, &bdisp->state)) + bdisp_job_finish(ctx, VB2_BUF_STATE_ERROR); + + return 0; +} + +static int bdisp_runtime_resume(struct device *dev) +{ + struct bdisp_dev *bdisp = dev_get_drvdata(dev); + int ret = clk_enable(bdisp->clock); + + if (ret) + return ret; + + return bdisp_m2m_resume(bdisp); +} + +static int bdisp_runtime_suspend(struct device *dev) +{ + struct bdisp_dev *bdisp = dev_get_drvdata(dev); + int ret = bdisp_m2m_suspend(bdisp); + + if (!ret) + clk_disable(bdisp->clock); + + return ret; +} + +static int bdisp_resume(struct device *dev) +{ + struct bdisp_dev *bdisp = dev_get_drvdata(dev); + unsigned long flags; + int opened; + + spin_lock_irqsave(&bdisp->slock, flags); + opened = test_bit(ST_M2M_OPEN, &bdisp->state); + spin_unlock_irqrestore(&bdisp->slock, flags); + + if (!opened) + return 0; + + if (!pm_runtime_suspended(dev)) + return bdisp_runtime_resume(dev); + + return 0; +} + +static int bdisp_suspend(struct device *dev) +{ + if (!pm_runtime_suspended(dev)) + return bdisp_runtime_suspend(dev); + + return 0; +} + +static const struct dev_pm_ops bdisp_pm_ops = { + .suspend = bdisp_suspend, + .resume = bdisp_resume, + .runtime_suspend = bdisp_runtime_suspend, + .runtime_resume = bdisp_runtime_resume, +}; + +static int bdisp_remove(struct platform_device *pdev) +{ + struct bdisp_dev *bdisp = platform_get_drvdata(pdev); + + bdisp_unregister_device(bdisp); + + bdisp_hw_free_filters(bdisp->dev); + + vb2_dma_contig_cleanup_ctx(bdisp->alloc_ctx); + + pm_runtime_disable(&pdev->dev); + + v4l2_device_unregister(&bdisp->v4l2_dev); + + if (!IS_ERR(bdisp->clock)) + clk_unprepare(bdisp->clock); + + dev_dbg(&pdev->dev, "%s driver unloaded\n", pdev->name); + + return 0; +} + +static int bdisp_probe(struct platform_device *pdev) +{ + struct bdisp_dev *bdisp; + struct resource *res; + struct device *dev = &pdev->dev; + int ret; + + dev_dbg(dev, "%s\n", __func__); + + bdisp = devm_kzalloc(dev, sizeof(struct bdisp_dev), GFP_KERNEL); + if (!bdisp) + return -ENOMEM; + + bdisp->pdev = pdev; + bdisp->dev = dev; + platform_set_drvdata(pdev, bdisp); + + if (dev->of_node) + bdisp->id = of_alias_get_id(pdev->dev.of_node, BDISP_NAME); + else + bdisp->id = pdev->id; + + init_waitqueue_head(&bdisp->irq_queue); + INIT_DELAYED_WORK(&bdisp->timeout_work, bdisp_irq_timeout); + bdisp->work_queue = create_workqueue(BDISP_NAME); + + spin_lock_init(&bdisp->slock); + mutex_init(&bdisp->lock); + + /* get resources */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + bdisp->regs = devm_ioremap_resource(dev, res); + if (IS_ERR(bdisp->regs)) { + dev_err(dev, "failed to get regs\n"); + return PTR_ERR(bdisp->regs); + } + + bdisp->clock = devm_clk_get(dev, BDISP_NAME); + if (IS_ERR(bdisp->clock)) { + dev_err(dev, "failed to get clock\n"); + return PTR_ERR(bdisp->clock); + } + + ret = clk_prepare(bdisp->clock); + if (ret < 0) { + dev_err(dev, "clock prepare failed\n"); + bdisp->clock = ERR_PTR(-EINVAL); + return ret; + } + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res) { + dev_err(dev, "failed to get IRQ resource\n"); + goto err_clk; + } + + ret = devm_request_threaded_irq(dev, res->start, bdisp_irq_handler, + bdisp_irq_thread, IRQF_ONESHOT, + pdev->name, bdisp); + if (ret) { + dev_err(dev, "failed to install irq\n"); + goto err_clk; + } + + /* v4l2 register */ + ret = v4l2_device_register(dev, &bdisp->v4l2_dev); + if (ret) { + dev_err(dev, "failed to register\n"); + goto err_clk; + } + + /* Power management */ + pm_runtime_enable(dev); + ret = pm_runtime_get_sync(dev); + if (ret < 0) { + dev_err(dev, "failed to set PM\n"); + goto err_v4l2; + } + + /* Continuous memory allocator */ + bdisp->alloc_ctx = vb2_dma_contig_init_ctx(dev); + if (IS_ERR(bdisp->alloc_ctx)) { + ret = PTR_ERR(bdisp->alloc_ctx); + goto err_pm; + } + + /* Filters */ + if (bdisp_hw_alloc_filters(bdisp->dev)) { + dev_err(bdisp->dev, "no memory for filters\n"); + ret = -ENOMEM; + goto err_vb2_dma; + } + + /* Register */ + ret = bdisp_register_device(bdisp); + if (ret) { + dev_err(dev, "failed to register\n"); + goto err_filter; + } + + dev_info(dev, "%s%d registered as /dev/video%d\n", BDISP_NAME, + bdisp->id, bdisp->vdev.num); + + pm_runtime_put(dev); + + return 0; + +err_filter: + bdisp_hw_free_filters(bdisp->dev); +err_vb2_dma: + vb2_dma_contig_cleanup_ctx(bdisp->alloc_ctx); +err_pm: + pm_runtime_put(dev); +err_v4l2: + v4l2_device_unregister(&bdisp->v4l2_dev); +err_clk: + if (!IS_ERR(bdisp->clock)) + clk_unprepare(bdisp->clock); + + return ret; +} + +static const struct of_device_id bdisp_match_types[] = { + { + .compatible = "st,stih407-bdisp", + }, + { /* end node */ } +}; + +MODULE_DEVICE_TABLE(of, bdisp_match_types); + +static struct platform_driver bdisp_driver = { + .probe = bdisp_probe, + .remove = bdisp_remove, + .driver = { + .name = BDISP_NAME, + .of_match_table = bdisp_match_types, + .pm = &bdisp_pm_ops, + }, +}; + +module_platform_driver(bdisp_driver); + +MODULE_DESCRIPTION("2D blitter for STMicroelectronics SoC"); +MODULE_AUTHOR("Fabien Dessenne "); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/platform/sti/bdisp/bdisp.h b/drivers/media/platform/sti/bdisp/bdisp.h new file mode 100644 index 000000000000..013678a4428b --- /dev/null +++ b/drivers/media/platform/sti/bdisp/bdisp.h @@ -0,0 +1,186 @@ +/* + * Copyright (C) STMicroelectronics SA 2014 + * Authors: Fabien Dessenne for STMicroelectronics. + * License terms: GNU General Public License (GPL), version 2 + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#define BDISP_NAME "bdisp" + +/* + * Max nb of nodes in node-list: + * - 2 nodes to handle wide 4K pictures + * - 2 nodes to handle two planes (Y & CbCr) */ +#define MAX_OUTPUT_PLANES 2 +#define MAX_VERTICAL_STRIDES 2 +#define MAX_NB_NODE (MAX_OUTPUT_PLANES * MAX_VERTICAL_STRIDES) + +/* struct bdisp_ctrls - bdisp control set + * @hflip: horizontal flip + * @vflip: vertical flip + */ +struct bdisp_ctrls { + struct v4l2_ctrl *hflip; + struct v4l2_ctrl *vflip; +}; + +/** + * struct bdisp_fmt - driver's internal color format data + * @pixelformat:fourcc code for this format + * @nb_planes: number of planes (ex: [0]=RGB/Y - [1]=Cb/Cr, ...) + * @bpp: bits per pixel (general) + * @bpp_plane0: byte per pixel for the 1st plane + * @w_align: width alignment in pixel (multiple of) + * @h_align: height alignment in pixel (multiple of) + */ +struct bdisp_fmt { + u32 pixelformat; + u8 nb_planes; + u8 bpp; + u8 bpp_plane0; + u8 w_align; + u8 h_align; +}; + +/** + * struct bdisp_frame - frame properties + * + * @width: frame width (including padding) + * @height: frame height (including padding) + * @fmt: pointer to frame format descriptor + * @field: frame / field type + * @bytesperline: stride of the 1st plane + * @sizeimage: image size in bytes + * @colorspace: colorspace + * @crop: crop area + * @paddr: image physical addresses per plane ([0]=RGB/Y - [1]=Cb/Cr, ...) + */ +struct bdisp_frame { + u32 width; + u32 height; + const struct bdisp_fmt *fmt; + enum v4l2_field field; + u32 bytesperline; + u32 sizeimage; + enum v4l2_colorspace colorspace; + struct v4l2_rect crop; + dma_addr_t paddr[4]; +}; + +/** + * struct bdisp_request - bdisp request + * + * @src: source frame properties + * @dst: destination frame properties + * @hflip: horizontal flip + * @vflip: vertical flip + * @nb_req: number of run request + */ +struct bdisp_request { + struct bdisp_frame src; + struct bdisp_frame dst; + unsigned int hflip:1; + unsigned int vflip:1; + int nb_req; +}; + +/** + * struct bdisp_ctx - device context data + * + * @src: source frame properties + * @dst: destination frame properties + * @state: flags to keep track of user configuration + * @hflip: horizontal flip + * @vflip: vertical flip + * @bdisp_dev: the device this context applies to + * @node: node array + * @node_paddr: node physical address array + * @fh: v4l2 file handle + * @ctrl_handler: v4l2 controls handler + * @bdisp_ctrls: bdisp control set + * @ctrls_rdy: true if the control handler is initialized + */ +struct bdisp_ctx { + struct bdisp_frame src; + struct bdisp_frame dst; + u32 state; + unsigned int hflip:1; + unsigned int vflip:1; + struct bdisp_dev *bdisp_dev; + struct bdisp_node *node[MAX_NB_NODE]; + dma_addr_t node_paddr[MAX_NB_NODE]; + struct v4l2_fh fh; + struct v4l2_ctrl_handler ctrl_handler; + struct bdisp_ctrls bdisp_ctrls; + bool ctrls_rdy; +}; + +/** + * struct bdisp_m2m_device - v4l2 memory-to-memory device data + * + * @vdev: video device node for v4l2 m2m mode + * @m2m_dev: v4l2 m2m device data + * @ctx: hardware context data + * @refcnt: reference counter + */ +struct bdisp_m2m_device { + struct video_device *vdev; + struct v4l2_m2m_dev *m2m_dev; + struct bdisp_ctx *ctx; + int refcnt; +}; + +/** + * struct bdisp_dev - abstraction for bdisp entity + * + * @v4l2_dev: v4l2 device + * @vdev: video device + * @pdev: platform device + * @dev: device + * @lock: mutex protecting this data structure + * @slock: spinlock protecting this data structure + * @id: device index + * @m2m: memory-to-memory V4L2 device information + * @state: flags used to synchronize m2m and capture mode operation + * @alloc_ctx: videobuf2 memory allocator context + * @clock: IP clock + * @regs: registers + * @irq_queue: interrupt handler waitqueue + * @work_queue: workqueue to handle timeouts + * @timeout_work: IRQ timeout structure + */ +struct bdisp_dev { + struct v4l2_device v4l2_dev; + struct video_device vdev; + struct platform_device *pdev; + struct device *dev; + spinlock_t slock; + struct mutex lock; + u16 id; + struct bdisp_m2m_device m2m; + unsigned long state; + struct vb2_alloc_ctx *alloc_ctx; + struct clk *clock; + void __iomem *regs; + wait_queue_head_t irq_queue; + struct workqueue_struct *work_queue; + struct delayed_work timeout_work; +}; + +void bdisp_hw_free_nodes(struct bdisp_ctx *ctx); +int bdisp_hw_alloc_nodes(struct bdisp_ctx *ctx); +void bdisp_hw_free_filters(struct device *dev); +int bdisp_hw_alloc_filters(struct device *dev); +int bdisp_hw_reset(struct bdisp_dev *bdisp); +int bdisp_hw_get_and_clear_irq(struct bdisp_dev *bdisp); +int bdisp_hw_update(struct bdisp_ctx *ctx); -- cgit v1.2.3-59-g8ed1b From 34b6beb65beb7f7726baa771661c671310445265 Mon Sep 17 00:00:00 2001 From: Fabien Dessenne Date: Tue, 12 May 2015 13:02:11 -0300 Subject: [media] bdisp: add debug file system Creates 5 debugfs entries to dump the last HW request, the last HW node (=command), the HW registers and the recent HW performance (time & fps) Signed-off-by: Fabien Dessenne Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sti/bdisp/Makefile | 2 +- drivers/media/platform/sti/bdisp/bdisp-debug.c | 668 +++++++++++++++++++++++++ drivers/media/platform/sti/bdisp/bdisp-hw.c | 40 ++ drivers/media/platform/sti/bdisp/bdisp-v4l2.c | 17 +- drivers/media/platform/sti/bdisp/bdisp.h | 30 ++ 5 files changed, 755 insertions(+), 2 deletions(-) create mode 100644 drivers/media/platform/sti/bdisp/bdisp-debug.c (limited to 'drivers/media') diff --git a/drivers/media/platform/sti/bdisp/Makefile b/drivers/media/platform/sti/bdisp/Makefile index 260509483aaf..bc53496fa74c 100644 --- a/drivers/media/platform/sti/bdisp/Makefile +++ b/drivers/media/platform/sti/bdisp/Makefile @@ -1,3 +1,3 @@ obj-$(CONFIG_VIDEO_STI_BDISP) := bdisp.o -bdisp-objs := bdisp-v4l2.o bdisp-hw.o +bdisp-objs := bdisp-v4l2.o bdisp-hw.o bdisp-debug.o diff --git a/drivers/media/platform/sti/bdisp/bdisp-debug.c b/drivers/media/platform/sti/bdisp/bdisp-debug.c new file mode 100644 index 000000000000..7c3a632746ba --- /dev/null +++ b/drivers/media/platform/sti/bdisp/bdisp-debug.c @@ -0,0 +1,668 @@ +/* + * Copyright (C) STMicroelectronics SA 2014 + * Authors: Fabien Dessenne for STMicroelectronics. + * License terms: GNU General Public License (GPL), version 2 + */ + +#include +#include + +#include "bdisp.h" +#include "bdisp-filter.h" +#include "bdisp-reg.h" + +void bdisp_dbg_perf_begin(struct bdisp_dev *bdisp) +{ + bdisp->dbg.hw_start = ktime_get(); +} + +void bdisp_dbg_perf_end(struct bdisp_dev *bdisp) +{ + s64 time_us; + + time_us = ktime_us_delta(ktime_get(), bdisp->dbg.hw_start); + + if (!bdisp->dbg.min_duration) + bdisp->dbg.min_duration = time_us; + else + bdisp->dbg.min_duration = min(time_us, bdisp->dbg.min_duration); + + bdisp->dbg.last_duration = time_us; + bdisp->dbg.max_duration = max(time_us, bdisp->dbg.max_duration); + bdisp->dbg.tot_duration += time_us; +} + +static void bdisp_dbg_dump_ins(struct seq_file *s, u32 val) +{ + seq_printf(s, "INS\t0x%08X\t", val); + + switch (val & BLT_INS_S1_MASK) { + case BLT_INS_S1_OFF: + break; + case BLT_INS_S1_MEM: + seq_puts(s, "SRC1=mem - "); + break; + case BLT_INS_S1_CF: + seq_puts(s, "SRC1=ColorFill - "); + break; + case BLT_INS_S1_COPY: + seq_puts(s, "SRC1=copy - "); + break; + case BLT_INS_S1_FILL: + seq_puts(s, "SRC1=fil - "); + break; + default: + seq_puts(s, "SRC1=??? - "); + break; + } + + switch (val & BLT_INS_S2_MASK) { + case BLT_INS_S2_OFF: + break; + case BLT_INS_S2_MEM: + seq_puts(s, "SRC2=mem - "); + break; + case BLT_INS_S2_CF: + seq_puts(s, "SRC2=ColorFill - "); + break; + default: + seq_puts(s, "SRC2=??? - "); + break; + } + + if ((val & BLT_INS_S3_MASK) == BLT_INS_S3_MEM) + seq_puts(s, "SRC3=mem - "); + + if (val & BLT_INS_IVMX) + seq_puts(s, "IVMX - "); + if (val & BLT_INS_CLUT) + seq_puts(s, "CLUT - "); + if (val & BLT_INS_SCALE) + seq_puts(s, "Scale - "); + if (val & BLT_INS_FLICK) + seq_puts(s, "Flicker - "); + if (val & BLT_INS_CLIP) + seq_puts(s, "Clip - "); + if (val & BLT_INS_CKEY) + seq_puts(s, "ColorKey - "); + if (val & BLT_INS_OVMX) + seq_puts(s, "OVMX - "); + if (val & BLT_INS_DEI) + seq_puts(s, "Deint - "); + if (val & BLT_INS_PMASK) + seq_puts(s, "PlaneMask - "); + if (val & BLT_INS_VC1R) + seq_puts(s, "VC1R - "); + if (val & BLT_INS_ROTATE) + seq_puts(s, "Rotate - "); + if (val & BLT_INS_GRAD) + seq_puts(s, "GradFill - "); + if (val & BLT_INS_AQLOCK) + seq_puts(s, "AQLock - "); + if (val & BLT_INS_PACE) + seq_puts(s, "Pace - "); + if (val & BLT_INS_IRQ) + seq_puts(s, "IRQ - "); + + seq_puts(s, "\n"); +} + +static void bdisp_dbg_dump_tty(struct seq_file *s, u32 val) +{ + seq_printf(s, "TTY\t0x%08X\t", val); + seq_printf(s, "Pitch=%d - ", val & 0xFFFF); + + switch ((val & BLT_TTY_COL_MASK) >> BLT_TTY_COL_SHIFT) { + case BDISP_RGB565: + seq_puts(s, "RGB565 - "); + break; + case BDISP_XRGB8888: + seq_puts(s, "xRGB888 - "); + break; + case BDISP_ARGB8888: + seq_puts(s, "ARGB8888 - "); + break; + case BDISP_NV12: + seq_puts(s, "NV12 - "); + break; + case BDISP_YUV_3B: + seq_puts(s, "YUV420P - "); + break; + default: + seq_puts(s, "ColorFormat ??? - "); + break; + } + + if (val & BLT_TTY_ALPHA_R) + seq_puts(s, "AlphaRange - "); + if (val & BLT_TTY_CR_NOT_CB) + seq_puts(s, "CrNotCb - "); + if (val & BLT_TTY_MB) + seq_puts(s, "MB - "); + if (val & BLT_TTY_HSO) + seq_puts(s, "HSO inverse - "); + if (val & BLT_TTY_VSO) + seq_puts(s, "VSO inverse - "); + if (val & BLT_TTY_DITHER) + seq_puts(s, "Dither - "); + if (val & BLT_TTY_CHROMA) + seq_puts(s, "Write CHROMA - "); + if (val & BLT_TTY_BIG_END) + seq_puts(s, "BigEndian - "); + + seq_puts(s, "\n"); +} + +static void bdisp_dbg_dump_xy(struct seq_file *s, u32 val, char *name) +{ + seq_printf(s, "%s\t0x%08X\t", name, val); + seq_printf(s, "(%d,%d)\n", val & 0xFFFF, (val >> 16)); +} + +static void bdisp_dbg_dump_sz(struct seq_file *s, u32 val, char *name) +{ + seq_printf(s, "%s\t0x%08X\t", name, val); + seq_printf(s, "%dx%d\n", val & 0x1FFF, (val >> 16) & 0x1FFF); +} + +static void bdisp_dbg_dump_sty(struct seq_file *s, + u32 val, u32 addr, char *name) +{ + bool s1, s2, s3; + + seq_printf(s, "%s\t0x%08X\t", name, val); + + if (!addr || !name || (strlen(name) < 2)) + goto done; + + s1 = name[strlen(name) - 1] == '1'; + s2 = name[strlen(name) - 1] == '2'; + s3 = name[strlen(name) - 1] == '3'; + + seq_printf(s, "Pitch=%d - ", val & 0xFFFF); + + switch ((val & BLT_TTY_COL_MASK) >> BLT_TTY_COL_SHIFT) { + case BDISP_RGB565: + seq_puts(s, "RGB565 - "); + break; + case BDISP_XRGB8888: + seq_puts(s, "xRGB888 - "); + break; + case BDISP_ARGB8888: + seq_puts(s, "ARGB888 - "); + break; + case BDISP_NV12: + seq_puts(s, "NV12 - "); + break; + case BDISP_YUV_3B: + seq_puts(s, "YUV420P - "); + break; + default: + seq_puts(s, "ColorFormat ??? - "); + break; + } + + if ((val & BLT_TTY_ALPHA_R) && !s3) + seq_puts(s, "AlphaRange - "); + if ((val & BLT_S1TY_A1_SUBSET) && !s3) + seq_puts(s, "A1SubSet - "); + if ((val & BLT_TTY_MB) && !s1) + seq_puts(s, "MB - "); + if (val & BLT_TTY_HSO) + seq_puts(s, "HSO inverse - "); + if (val & BLT_TTY_VSO) + seq_puts(s, "VSO inverse - "); + if ((val & BLT_S1TY_CHROMA_EXT) && (s1 || s2)) + seq_puts(s, "ChromaExt - "); + if ((val & BLT_S3TY_BLANK_ACC) && s3) + seq_puts(s, "Blank Acc - "); + if ((val & BTL_S1TY_SUBBYTE) && !s3) + seq_puts(s, "SubByte - "); + if ((val & BLT_S1TY_RGB_EXP) && !s3) + seq_puts(s, "RGBExpand - "); + if ((val & BLT_TTY_BIG_END) && !s3) + seq_puts(s, "BigEndian - "); + +done: + seq_puts(s, "\n"); +} + +static void bdisp_dbg_dump_fctl(struct seq_file *s, u32 val) +{ + seq_printf(s, "FCTL\t0x%08X\t", val); + + if ((val & BLT_FCTL_Y_HV_SCALE) == BLT_FCTL_Y_HV_SCALE) + seq_puts(s, "Resize Luma - "); + else if ((val & BLT_FCTL_Y_HV_SCALE) == BLT_FCTL_Y_HV_SAMPLE) + seq_puts(s, "Sample Luma - "); + + if ((val & BLT_FCTL_HV_SCALE) == BLT_FCTL_HV_SCALE) + seq_puts(s, "Resize Chroma"); + else if ((val & BLT_FCTL_HV_SCALE) == BLT_FCTL_HV_SAMPLE) + seq_puts(s, "Sample Chroma"); + + seq_puts(s, "\n"); +} + +static void bdisp_dbg_dump_rsf(struct seq_file *s, u32 val, char *name) +{ + u32 inc; + + seq_printf(s, "%s\t0x%08X\t", name, val); + + if (!val) + goto done; + + inc = val & 0xFFFF; + seq_printf(s, "H: %d(6.10) / scale~%dx0.1 - ", inc, 1024 * 10 / inc); + + inc = val >> 16; + seq_printf(s, "V: %d(6.10) / scale~%dx0.1", inc, 1024 * 10 / inc); + +done: + seq_puts(s, "\n"); +} + +static void bdisp_dbg_dump_rzi(struct seq_file *s, u32 val, char *name) +{ + seq_printf(s, "%s\t0x%08X\t", name, val); + + if (!val) + goto done; + + seq_printf(s, "H: init=%d repeat=%d - ", val & 0x3FF, (val >> 12) & 7); + val >>= 16; + seq_printf(s, "V: init=%d repeat=%d", val & 0x3FF, (val >> 12) & 7); + +done: + seq_puts(s, "\n"); +} + +static void bdisp_dbg_dump_ivmx(struct seq_file *s, + u32 c0, u32 c1, u32 c2, u32 c3) +{ + seq_printf(s, "IVMX0\t0x%08X\n", c0); + seq_printf(s, "IVMX1\t0x%08X\n", c1); + seq_printf(s, "IVMX2\t0x%08X\n", c2); + seq_printf(s, "IVMX3\t0x%08X\t", c3); + + if (!c0 && !c1 && !c2 && !c3) { + seq_puts(s, "\n"); + return; + } + + if ((c0 == bdisp_rgb_to_yuv[0]) && + (c1 == bdisp_rgb_to_yuv[1]) && + (c2 == bdisp_rgb_to_yuv[2]) && + (c3 == bdisp_rgb_to_yuv[3])) { + seq_puts(s, "RGB to YUV\n"); + return; + } + + if ((c0 == bdisp_yuv_to_rgb[0]) && + (c1 == bdisp_yuv_to_rgb[1]) && + (c2 == bdisp_yuv_to_rgb[2]) && + (c3 == bdisp_yuv_to_rgb[3])) { + seq_puts(s, "YUV to RGB\n"); + return; + } + seq_puts(s, "Unknown conversion\n"); +} + +static int bdisp_dbg_last_nodes(struct seq_file *s, void *data) +{ + /* Not dumping all fields, focusing on significant ones */ + struct bdisp_dev *bdisp = s->private; + struct bdisp_node *node; + int i = 0; + + if (!bdisp->dbg.copy_node[0]) { + seq_puts(s, "No node built yet\n"); + return 0; + } + + do { + node = bdisp->dbg.copy_node[i]; + if (!node) + break; + seq_printf(s, "--------\nNode %d:\n", i); + seq_puts(s, "-- General --\n"); + seq_printf(s, "NIP\t0x%08X\n", node->nip); + seq_printf(s, "CIC\t0x%08X\n", node->cic); + bdisp_dbg_dump_ins(s, node->ins); + seq_printf(s, "ACK\t0x%08X\n", node->ack); + seq_puts(s, "-- Target --\n"); + seq_printf(s, "TBA\t0x%08X\n", node->tba); + bdisp_dbg_dump_tty(s, node->tty); + bdisp_dbg_dump_xy(s, node->txy, "TXY"); + bdisp_dbg_dump_sz(s, node->tsz, "TSZ"); + /* Color Fill not dumped */ + seq_puts(s, "-- Source 1 --\n"); + seq_printf(s, "S1BA\t0x%08X\n", node->s1ba); + bdisp_dbg_dump_sty(s, node->s1ty, node->s1ba, "S1TY"); + bdisp_dbg_dump_xy(s, node->s1xy, "S1XY"); + seq_puts(s, "-- Source 2 --\n"); + seq_printf(s, "S2BA\t0x%08X\n", node->s2ba); + bdisp_dbg_dump_sty(s, node->s2ty, node->s2ba, "S2TY"); + bdisp_dbg_dump_xy(s, node->s2xy, "S2XY"); + bdisp_dbg_dump_sz(s, node->s2sz, "S2SZ"); + seq_puts(s, "-- Source 3 --\n"); + seq_printf(s, "S3BA\t0x%08X\n", node->s3ba); + bdisp_dbg_dump_sty(s, node->s3ty, node->s3ba, "S3TY"); + bdisp_dbg_dump_xy(s, node->s3xy, "S3XY"); + bdisp_dbg_dump_sz(s, node->s3sz, "S3SZ"); + /* Clipping not dumped */ + /* CLUT not dumped */ + seq_puts(s, "-- Filter & Mask --\n"); + bdisp_dbg_dump_fctl(s, node->fctl); + /* PMK not dumped */ + seq_puts(s, "-- Chroma Filter --\n"); + bdisp_dbg_dump_rsf(s, node->rsf, "RSF"); + bdisp_dbg_dump_rzi(s, node->rzi, "RZI"); + seq_printf(s, "HFP\t0x%08X\n", node->hfp); + seq_printf(s, "VFP\t0x%08X\n", node->vfp); + seq_puts(s, "-- Luma Filter --\n"); + bdisp_dbg_dump_rsf(s, node->y_rsf, "Y_RSF"); + bdisp_dbg_dump_rzi(s, node->y_rzi, "Y_RZI"); + seq_printf(s, "Y_HFP\t0x%08X\n", node->y_hfp); + seq_printf(s, "Y_VFP\t0x%08X\n", node->y_vfp); + /* Flicker not dumped */ + /* Color key not dumped */ + /* Reserved not dumped */ + /* Static Address & User not dumped */ + seq_puts(s, "-- Input Versatile Matrix --\n"); + bdisp_dbg_dump_ivmx(s, node->ivmx0, node->ivmx1, + node->ivmx2, node->ivmx3); + /* Output Versatile Matrix not dumped */ + /* Pace not dumped */ + /* VC1R & DEI not dumped */ + /* Gradient Fill not dumped */ + } while ((++i < MAX_NB_NODE) && node->nip); + + return 0; +} + +static int bdisp_dbg_last_nodes_raw(struct seq_file *s, void *data) +{ + struct bdisp_dev *bdisp = s->private; + struct bdisp_node *node; + u32 *val; + int j, i = 0; + + if (!bdisp->dbg.copy_node[0]) { + seq_puts(s, "No node built yet\n"); + return 0; + } + + do { + node = bdisp->dbg.copy_node[i]; + if (!node) + break; + + seq_printf(s, "--------\nNode %d:\n", i); + val = (u32 *)node; + for (j = 0; j < sizeof(struct bdisp_node) / sizeof(u32); j++) + seq_printf(s, "0x%08X\n", *val++); + } while ((++i < MAX_NB_NODE) && node->nip); + + return 0; +} + +static const char *bdisp_fmt_to_str(struct bdisp_frame frame) +{ + switch (frame.fmt->pixelformat) { + case V4L2_PIX_FMT_YUV420: + return "YUV420P"; + case V4L2_PIX_FMT_NV12: + if (frame.field == V4L2_FIELD_INTERLACED) + return "NV12 interlaced"; + else + return "NV12"; + case V4L2_PIX_FMT_RGB565: + return "RGB16"; + case V4L2_PIX_FMT_XBGR32: + return "XRGB"; + case V4L2_PIX_FMT_ABGR32: + return "ARGB"; + default: + return "????"; + } +} + +static int bdisp_dbg_last_request(struct seq_file *s, void *data) +{ + struct bdisp_dev *bdisp = s->private; + struct bdisp_request *request = &bdisp->dbg.copy_request; + struct bdisp_frame src, dst; + + if (!request->nb_req) { + seq_puts(s, "No request\n"); + return 0; + } + + src = request->src; + dst = request->dst; + + seq_printf(s, "\nRequest #%d\n", request->nb_req); + + seq_printf(s, "Format: %s\t\t\t%s\n", + bdisp_fmt_to_str(src), bdisp_fmt_to_str(dst)); + seq_printf(s, "Crop area: %dx%d @ %d,%d ==>\t%dx%d @ %d,%d\n", + src.crop.width, src.crop.height, + src.crop.left, src.crop.top, + dst.crop.width, dst.crop.height, + dst.crop.left, dst.crop.top); + seq_printf(s, "Buff size: %dx%d\t\t%dx%d\n\n", + src.width, src.height, dst.width, dst.height); + + if (request->hflip) + seq_puts(s, "Horizontal flip\n\n"); + + if (request->vflip) + seq_puts(s, "Vertical flip\n\n"); + + return 0; +} + +#define DUMP(reg) seq_printf(s, #reg " \t0x%08X\n", readl(bdisp->regs + reg)) + +static int bdisp_dbg_regs(struct seq_file *s, void *data) +{ + struct bdisp_dev *bdisp = s->private; + int ret; + unsigned int i; + + ret = pm_runtime_get_sync(bdisp->dev); + if (ret < 0) { + seq_puts(s, "Cannot wake up IP\n"); + return 0; + } + + seq_printf(s, "Reg @ = 0x%p\n", bdisp->regs); + + seq_puts(s, "\nStatic:\n"); + DUMP(BLT_CTL); + DUMP(BLT_ITS); + DUMP(BLT_STA1); + DUMP(BLT_AQ1_CTL); + DUMP(BLT_AQ1_IP); + DUMP(BLT_AQ1_LNA); + DUMP(BLT_AQ1_STA); + DUMP(BLT_ITM0); + + seq_puts(s, "\nPlugs:\n"); + DUMP(BLT_PLUGS1_OP2); + DUMP(BLT_PLUGS1_CHZ); + DUMP(BLT_PLUGS1_MSZ); + DUMP(BLT_PLUGS1_PGZ); + DUMP(BLT_PLUGS2_OP2); + DUMP(BLT_PLUGS2_CHZ); + DUMP(BLT_PLUGS2_MSZ); + DUMP(BLT_PLUGS2_PGZ); + DUMP(BLT_PLUGS3_OP2); + DUMP(BLT_PLUGS3_CHZ); + DUMP(BLT_PLUGS3_MSZ); + DUMP(BLT_PLUGS3_PGZ); + DUMP(BLT_PLUGT_OP2); + DUMP(BLT_PLUGT_CHZ); + DUMP(BLT_PLUGT_MSZ); + DUMP(BLT_PLUGT_PGZ); + + seq_puts(s, "\nNode:\n"); + DUMP(BLT_NIP); + DUMP(BLT_CIC); + DUMP(BLT_INS); + DUMP(BLT_ACK); + DUMP(BLT_TBA); + DUMP(BLT_TTY); + DUMP(BLT_TXY); + DUMP(BLT_TSZ); + DUMP(BLT_S1BA); + DUMP(BLT_S1TY); + DUMP(BLT_S1XY); + DUMP(BLT_S2BA); + DUMP(BLT_S2TY); + DUMP(BLT_S2XY); + DUMP(BLT_S2SZ); + DUMP(BLT_S3BA); + DUMP(BLT_S3TY); + DUMP(BLT_S3XY); + DUMP(BLT_S3SZ); + DUMP(BLT_FCTL); + DUMP(BLT_RSF); + DUMP(BLT_RZI); + DUMP(BLT_HFP); + DUMP(BLT_VFP); + DUMP(BLT_Y_RSF); + DUMP(BLT_Y_RZI); + DUMP(BLT_Y_HFP); + DUMP(BLT_Y_VFP); + DUMP(BLT_IVMX0); + DUMP(BLT_IVMX1); + DUMP(BLT_IVMX2); + DUMP(BLT_IVMX3); + DUMP(BLT_OVMX0); + DUMP(BLT_OVMX1); + DUMP(BLT_OVMX2); + DUMP(BLT_OVMX3); + DUMP(BLT_DEI); + + seq_puts(s, "\nFilter:\n"); + for (i = 0; i < BLT_NB_H_COEF; i++) { + seq_printf(s, "BLT_HFC%d \t0x%08X\n", i, + readl(bdisp->regs + BLT_HFC_N + i * 4)); + } + for (i = 0; i < BLT_NB_V_COEF; i++) { + seq_printf(s, "BLT_VFC%d \t0x%08X\n", i, + readl(bdisp->regs + BLT_VFC_N + i * 4)); + } + + seq_puts(s, "\nLuma filter:\n"); + for (i = 0; i < BLT_NB_H_COEF; i++) { + seq_printf(s, "BLT_Y_HFC%d \t0x%08X\n", i, + readl(bdisp->regs + BLT_Y_HFC_N + i * 4)); + } + for (i = 0; i < BLT_NB_V_COEF; i++) { + seq_printf(s, "BLT_Y_VFC%d \t0x%08X\n", i, + readl(bdisp->regs + BLT_Y_VFC_N + i * 4)); + } + + pm_runtime_put(bdisp->dev); + + return 0; +} + +static int bdisp_dbg_perf(struct seq_file *s, void *data) +{ + struct bdisp_dev *bdisp = s->private; + struct bdisp_request *request = &bdisp->dbg.copy_request; + s64 avg_time_us; + int avg_fps, min_fps, max_fps, last_fps; + + if (!request->nb_req) { + seq_puts(s, "No request\n"); + return 0; + } + + avg_time_us = bdisp->dbg.tot_duration; + do_div(avg_time_us, request->nb_req); + + avg_fps = 1000000; + min_fps = 1000000; + max_fps = 1000000; + last_fps = 1000000; + do_div(avg_fps, avg_time_us); + do_div(min_fps, bdisp->dbg.min_duration); + do_div(max_fps, bdisp->dbg.max_duration); + do_div(last_fps, bdisp->dbg.last_duration); + + seq_printf(s, "HW processing (%d requests):\n", request->nb_req); + seq_printf(s, " Average: %5lld us (%3d fps)\n", + avg_time_us, avg_fps); + seq_printf(s, " Min-Max: %5lld us (%3d fps) - %5lld us (%3d fps)\n", + bdisp->dbg.min_duration, min_fps, + bdisp->dbg.max_duration, max_fps); + seq_printf(s, " Last: %5lld us (%3d fps)\n", + bdisp->dbg.last_duration, last_fps); + + return 0; +} + +#define bdisp_dbg_declare(name) \ + static int bdisp_dbg_##name##_open(struct inode *i, struct file *f) \ + { \ + return single_open(f, bdisp_dbg_##name, i->i_private); \ + } \ + static const struct file_operations bdisp_dbg_##name##_fops = { \ + .open = bdisp_dbg_##name##_open, \ + .read = seq_read, \ + .llseek = seq_lseek, \ + .release = single_release, \ + } + +#define bdisp_dbg_create_entry(name) \ + debugfs_create_file(#name, S_IRUGO, bdisp->dbg.debugfs_entry, bdisp, \ + &bdisp_dbg_##name##_fops) + +bdisp_dbg_declare(regs); +bdisp_dbg_declare(last_nodes); +bdisp_dbg_declare(last_nodes_raw); +bdisp_dbg_declare(last_request); +bdisp_dbg_declare(perf); + +int bdisp_debugfs_create(struct bdisp_dev *bdisp) +{ + char dirname[16]; + + snprintf(dirname, sizeof(dirname), "%s%d", BDISP_NAME, bdisp->id); + bdisp->dbg.debugfs_entry = debugfs_create_dir(dirname, NULL); + if (!bdisp->dbg.debugfs_entry) + goto err; + + if (!bdisp_dbg_create_entry(regs)) + goto err; + + if (!bdisp_dbg_create_entry(last_nodes)) + goto err; + + if (!bdisp_dbg_create_entry(last_nodes_raw)) + goto err; + + if (!bdisp_dbg_create_entry(last_request)) + goto err; + + if (!bdisp_dbg_create_entry(perf)) + goto err; + + return 0; + +err: + bdisp_debugfs_remove(bdisp); + return 0; +} + +void bdisp_debugfs_remove(struct bdisp_dev *bdisp) +{ + debugfs_remove_recursive(bdisp->dbg.debugfs_entry); + bdisp->dbg.debugfs_entry = NULL; +} diff --git a/drivers/media/platform/sti/bdisp/bdisp-hw.c b/drivers/media/platform/sti/bdisp/bdisp-hw.c index 9c288acd835d..465828e859e2 100644 --- a/drivers/media/platform/sti/bdisp/bdisp-hw.c +++ b/drivers/media/platform/sti/bdisp/bdisp-hw.c @@ -740,6 +740,43 @@ static int bdisp_hw_build_all_nodes(struct bdisp_ctx *ctx) return 0; } +/** + * bdisp_hw_save_request + * @ctx: device context + * + * Save a copy of the request and of the built nodes + * + * RETURNS: + * None + */ +static void bdisp_hw_save_request(struct bdisp_ctx *ctx) +{ + struct bdisp_node **copy_node = ctx->bdisp_dev->dbg.copy_node; + struct bdisp_request *request = &ctx->bdisp_dev->dbg.copy_request; + struct bdisp_node **node = ctx->node; + int i; + + /* Request copy */ + request->src = ctx->src; + request->dst = ctx->dst; + request->hflip = ctx->hflip; + request->vflip = ctx->vflip; + request->nb_req++; + + /* Nodes copy */ + for (i = 0; i < MAX_NB_NODE; i++) { + /* Allocate memory if not done yet */ + if (!copy_node[i]) { + copy_node[i] = devm_kzalloc(ctx->bdisp_dev->dev, + sizeof(*copy_node), + GFP_KERNEL); + if (!copy_node[i]) + return; + } + copy_node[i] = node[i]; + } +} + /** * bdisp_hw_update * @ctx: device context @@ -765,6 +802,9 @@ int bdisp_hw_update(struct bdisp_ctx *ctx) return ret; } + /* Save a copy of the request */ + bdisp_hw_save_request(ctx); + /* Configure interrupt to 'Last Node Reached for AQ1' */ writel(BLT_AQ1_CTL_CFG, bdisp->regs + BLT_AQ1_CTL); writel(BLT_ITS_AQ1_LNA, bdisp->regs + BLT_ITM0); diff --git a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c index 6e8fd2747e8a..89d7a2279bc6 100644 --- a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c +++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c @@ -336,6 +336,8 @@ static void bdisp_device_run(void *priv) goto out; } + bdisp_dbg_perf_begin(bdisp); + err = bdisp_hw_reset(bdisp); if (err) { dev_err(bdisp->dev, "could not get HW ready\n"); @@ -1075,6 +1077,8 @@ static irqreturn_t bdisp_irq_thread(int irq, void *priv) spin_lock(&bdisp->slock); + bdisp_dbg_perf_end(bdisp); + cancel_delayed_work(&bdisp->timeout_work); if (!test_and_clear_bit(ST_M2M_RUNNING, &bdisp->state)) @@ -1247,6 +1251,8 @@ static int bdisp_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); + bdisp_debugfs_remove(bdisp); + v4l2_device_unregister(&bdisp->v4l2_dev); if (!IS_ERR(bdisp->clock)) @@ -1328,12 +1334,19 @@ static int bdisp_probe(struct platform_device *pdev) goto err_clk; } + /* Debug */ + ret = bdisp_debugfs_create(bdisp); + if (ret) { + dev_err(dev, "failed to create debugfs\n"); + goto err_v4l2; + } + /* Power management */ pm_runtime_enable(dev); ret = pm_runtime_get_sync(dev); if (ret < 0) { dev_err(dev, "failed to set PM\n"); - goto err_v4l2; + goto err_dbg; } /* Continuous memory allocator */ @@ -1370,6 +1383,8 @@ err_vb2_dma: vb2_dma_contig_cleanup_ctx(bdisp->alloc_ctx); err_pm: pm_runtime_put(dev); +err_dbg: + bdisp_debugfs_remove(bdisp); err_v4l2: v4l2_device_unregister(&bdisp->v4l2_dev); err_clk: diff --git a/drivers/media/platform/sti/bdisp/bdisp.h b/drivers/media/platform/sti/bdisp/bdisp.h index 013678a4428b..0cf98577222c 100644 --- a/drivers/media/platform/sti/bdisp/bdisp.h +++ b/drivers/media/platform/sti/bdisp/bdisp.h @@ -140,6 +140,29 @@ struct bdisp_m2m_device { int refcnt; }; +/** + * struct bdisp_dbg - debug info + * + * @debugfs_entry: debugfs + * @copy_node: array of last used nodes + * @copy_request: last bdisp request + * @hw_start: start time of last HW request + * @last_duration: last HW processing duration in microsecs + * @min_duration: min HW processing duration in microsecs + * @max_duration: max HW processing duration in microsecs + * @tot_duration: total HW processing duration in microsecs + */ +struct bdisp_dbg { + struct dentry *debugfs_entry; + struct bdisp_node *copy_node[MAX_NB_NODE]; + struct bdisp_request copy_request; + ktime_t hw_start; + s64 last_duration; + s64 min_duration; + s64 max_duration; + s64 tot_duration; +}; + /** * struct bdisp_dev - abstraction for bdisp entity * @@ -158,6 +181,7 @@ struct bdisp_m2m_device { * @irq_queue: interrupt handler waitqueue * @work_queue: workqueue to handle timeouts * @timeout_work: IRQ timeout structure + * @dbg: debug info */ struct bdisp_dev { struct v4l2_device v4l2_dev; @@ -175,6 +199,7 @@ struct bdisp_dev { wait_queue_head_t irq_queue; struct workqueue_struct *work_queue; struct delayed_work timeout_work; + struct bdisp_dbg dbg; }; void bdisp_hw_free_nodes(struct bdisp_ctx *ctx); @@ -184,3 +209,8 @@ int bdisp_hw_alloc_filters(struct device *dev); int bdisp_hw_reset(struct bdisp_dev *bdisp); int bdisp_hw_get_and_clear_irq(struct bdisp_dev *bdisp); int bdisp_hw_update(struct bdisp_ctx *ctx); + +void bdisp_debugfs_remove(struct bdisp_dev *bdisp); +int bdisp_debugfs_create(struct bdisp_dev *bdisp); +void bdisp_dbg_perf_begin(struct bdisp_dev *bdisp); +void bdisp_dbg_perf_end(struct bdisp_dev *bdisp); -- cgit v1.2.3-59-g8ed1b From fa8cb6444c3236d2bad7460bdfdb2685f82b7ee4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 14 May 2015 19:27:45 -0300 Subject: [media] ov2659: Don't depend on subdev API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The subdev API is optional. No driver should depend on it. Avoid compilation breakages if subdev API is not selected: drivers/media/i2c/ov2659.c: In function ‘ov2659_get_fmt’: drivers/media/i2c/ov2659.c:1054:3: error: implicit declaration of function ‘v4l2_subdev_get_try_format’ [-Werror=implicit-function-declaration] mf = v4l2_subdev_get_try_format(sd, cfg, 0); ^ drivers/media/i2c/ov2659.c:1054:6: warning: assignment makes pointer from integer without a cast mf = v4l2_subdev_get_try_format(sd, cfg, 0); ^ drivers/media/i2c/ov2659.c: In function ‘ov2659_set_fmt’: drivers/media/i2c/ov2659.c:1129:6: warning: assignment makes pointer from integer without a cast mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); ^ drivers/media/i2c/ov2659.c: In function ‘ov2659_open’: drivers/media/i2c/ov2659.c:1264:38: error: ‘struct v4l2_subdev_fh’ has no member named ‘pad’ v4l2_subdev_get_try_format(sd, fh->pad, 0); ^ Signed-off-by: Mauro Carvalho Chehab Tested-by: Lad, Prabhakar --- drivers/media/i2c/ov2659.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c index c8615f7f2627..6edffc7b74e3 100644 --- a/drivers/media/i2c/ov2659.c +++ b/drivers/media/i2c/ov2659.c @@ -1046,16 +1046,21 @@ static int ov2659_get_fmt(struct v4l2_subdev *sd, { struct i2c_client *client = v4l2_get_subdevdata(sd); struct ov2659 *ov2659 = to_ov2659(sd); - struct v4l2_mbus_framefmt *mf; dev_dbg(&client->dev, "ov2659_get_fmt\n"); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API + struct v4l2_mbus_framefmt *mf; + mf = v4l2_subdev_get_try_format(sd, cfg, 0); mutex_lock(&ov2659->lock); fmt->format = *mf; mutex_unlock(&ov2659->lock); return 0; +#else + return -ENOTTY; +#endif } mutex_lock(&ov2659->lock); @@ -1126,8 +1131,12 @@ static int ov2659_set_fmt(struct v4l2_subdev *sd, mutex_lock(&ov2659->lock); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); *mf = fmt->format; +#else + return -ENOTTY; +#endif } else { s64 val; @@ -1257,6 +1266,7 @@ static const char * const ov2659_test_pattern_menu[] = { * V4L2 subdev internal operations */ +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API static int ov2659_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -1269,6 +1279,7 @@ static int ov2659_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) return 0; } +#endif static const struct v4l2_subdev_core_ops ov2659_subdev_core_ops = { .log_status = v4l2_ctrl_subdev_log_status, @@ -1287,6 +1298,7 @@ static const struct v4l2_subdev_pad_ops ov2659_subdev_pad_ops = { .set_fmt = ov2659_set_fmt, }; +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API static const struct v4l2_subdev_ops ov2659_subdev_ops = { .core = &ov2659_subdev_core_ops, .video = &ov2659_subdev_video_ops, @@ -1296,6 +1308,7 @@ static const struct v4l2_subdev_ops ov2659_subdev_ops = { static const struct v4l2_subdev_internal_ops ov2659_subdev_internal_ops = { .open = ov2659_open, }; +#endif static int ov2659_detect(struct v4l2_subdev *sd) { @@ -1426,11 +1439,13 @@ static int ov2659_probe(struct i2c_client *client, sd = &ov2659->sd; client->flags |= I2C_CLIENT_SCCB; +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API v4l2_i2c_subdev_init(sd, client, &ov2659_subdev_ops); sd->internal_ops = &ov2659_subdev_internal_ops; sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; +#endif #if defined(CONFIG_MEDIA_CONTROLLER) ov2659->pad.flags = MEDIA_PAD_FL_SOURCE; -- cgit v1.2.3-59-g8ed1b From 09f2082e23ad8e89e10152b8701d3511ace45290 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 May 2015 08:00:56 -0300 Subject: [media] usb drivers: use BUG_ON() instead of if () BUG Some USB drivers have a logic at the VB buffer handling like: if (in_interrupt()) BUG(); Use, instead: BUG_ON(in_interrupt()); Btw, this logic looks weird on my eyes. We should convert them to use VB2, in order to avoid those crappy things. Signed-off-by: Mauro Carvalho Chehab Acked-by: Lad, Prabhakar Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-417.c | 3 +-- drivers/media/usb/cx231xx/cx231xx-vbi.c | 3 +-- drivers/media/usb/cx231xx/cx231xx-video.c | 3 +-- drivers/media/usb/tm6000/tm6000-video.c | 3 +-- drivers/media/usb/zr364xx/zr364xx.c | 3 +-- 5 files changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index 855a708387c6..47a98a2014a5 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c @@ -1249,8 +1249,7 @@ static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf) struct cx231xx *dev = fh->dev; unsigned long flags = 0; - if (in_interrupt()) - BUG(); + BUG_ON(in_interrupt()); spin_lock_irqsave(&dev->video_mode.slock, flags); if (dev->USE_ISO) { diff --git a/drivers/media/usb/cx231xx/cx231xx-vbi.c b/drivers/media/usb/cx231xx/cx231xx-vbi.c index 80261ac40208..a08014d20a5c 100644 --- a/drivers/media/usb/cx231xx/cx231xx-vbi.c +++ b/drivers/media/usb/cx231xx/cx231xx-vbi.c @@ -192,8 +192,7 @@ static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf) struct cx231xx_fh *fh = vq->priv_data; struct cx231xx *dev = fh->dev; unsigned long flags = 0; - if (in_interrupt()) - BUG(); + BUG_ON(in_interrupt()); /* We used to wait for the buffer to finish here, but this didn't work because, as we were keeping the state as VIDEOBUF_QUEUED, diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index af44f2d1c0a1..c6ff8968286a 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -749,8 +749,7 @@ static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf) struct cx231xx *dev = fh->dev; unsigned long flags = 0; - if (in_interrupt()) - BUG(); + BUG_ON(in_interrupt()); /* We used to wait for the buffer to finish here, but this didn't work because, as we were keeping the state as VIDEOBUF_QUEUED, diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c index 5287d2960282..fa5e8bda2ae4 100644 --- a/drivers/media/usb/tm6000/tm6000-video.c +++ b/drivers/media/usb/tm6000/tm6000-video.c @@ -714,8 +714,7 @@ static void free_buffer(struct videobuf_queue *vq, struct tm6000_buffer *buf) struct tm6000_core *dev = fh->dev; unsigned long flags; - if (in_interrupt()) - BUG(); + BUG_ON(in_interrupt()); /* We used to wait for the buffer to finish here, but this didn't work because, as we were keeping the state as VIDEOBUF_QUEUED, diff --git a/drivers/media/usb/zr364xx/zr364xx.c b/drivers/media/usb/zr364xx/zr364xx.c index ca850316d379..7433ba5c4bad 100644 --- a/drivers/media/usb/zr364xx/zr364xx.c +++ b/drivers/media/usb/zr364xx/zr364xx.c @@ -377,8 +377,7 @@ static void free_buffer(struct videobuf_queue *vq, struct zr364xx_buffer *buf) { _DBG("%s\n", __func__); - if (in_interrupt()) - BUG(); + BUG_ON(in_interrupt()); videobuf_vmalloc_free(&buf->vb); buf->vb.state = VIDEOBUF_NEEDS_INIT; -- cgit v1.2.3-59-g8ed1b From ae1c75d6ce3aeb0515701fbd68182ea19fed8e8f Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 19 May 2015 18:34:33 -0300 Subject: [media] coda: remove extraneous TRACE_SYSTEM_STRING The coda tracing code causes lots of warnings like In file included from /git/arm-soc/include/trace/define_trace.h:90:0, from /git/arm-soc/drivers/media/platform/coda/trace.h:203, from /git/arm-soc/drivers/media/platform/coda/coda-bit.c:34: /git/arm-soc/include/trace/ftrace.h:28:0: warning: "TRACE_SYSTEM_STRING" redefined #define TRACE_SYSTEM_STRING __app(TRACE_SYSTEM_VAR,__trace_system_name) ^ In file included from /git/arm-soc/include/trace/define_trace.h:83:0, from /git/arm-soc/drivers/media/platform/coda/trace.h:203, from /git/arm-soc/drivers/media/platform/coda/coda-bit.c:34: /git/arm-soc/drivers/media/platform/coda/./trace.h:12:0: note: this is the location of the previous definition #define TRACE_SYSTEM_STRING __stringify(TRACE_SYSTEM) >From what I can tell, this is just the result of a bogus TRACE_SYSTEM_STRING definition, and removing that one makes the warnings go away. Fixes: 9a1a8f9953f ("[media] coda: Add tracing support") Signed-off-by: Arnd Bergmann Acked-by: Philipp Zabel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/trace.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/coda/trace.h b/drivers/media/platform/coda/trace.h index d1d06cbd1f6a..781bf7286d53 100644 --- a/drivers/media/platform/coda/trace.h +++ b/drivers/media/platform/coda/trace.h @@ -9,8 +9,6 @@ #include "coda.h" -#define TRACE_SYSTEM_STRING __stringify(TRACE_SYSTEM) - TRACE_EVENT(coda_bit_run, TP_PROTO(struct coda_ctx *ctx, int cmd), -- cgit v1.2.3-59-g8ed1b From eee1d06dc2ac81bc6307326f286932c04136c1af Mon Sep 17 00:00:00 2001 From: Tommi Rantala Date: Wed, 20 May 2015 04:51:29 -0300 Subject: [media] cx231xx: Add support for Terratec Grabby Add support for the Terratec Grabby with USB ID 0ccd:00a6. Signed-off-by: Tommi Rantala Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-cards.c | 28 ++++++++++++++++++++++++++++ drivers/media/usb/cx231xx/cx231xx.h | 1 + 2 files changed, 29 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index a4aa2851339a..4a117a58c39a 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -815,6 +815,32 @@ struct cx231xx_board cx231xx_boards[] = { .gpio = NULL, } }, }, + [CX231XX_BOARD_TERRATEC_GRABBY] = { + .name = "Terratec Grabby", + .tuner_type = TUNER_ABSENT, + .decoder = CX231XX_AVDECODER, + .output_mode = OUT_MODE_VIP11, + .demod_xfer_mode = 0, + .ctl_pin_status_mask = 0xFFFFFFC4, + .agc_analog_digital_select_gpio = 0x0c, + .gpio_pin_status_mask = 0x4001000, + .norm = V4L2_STD_PAL, + .no_alt_vanc = 1, + .external_av = 1, + .input = {{ + .type = CX231XX_VMUX_COMPOSITE1, + .vmux = CX231XX_VIN_2_1, + .amux = CX231XX_AMUX_LINE_IN, + .gpio = NULL, + }, { + .type = CX231XX_VMUX_SVIDEO, + .vmux = CX231XX_VIN_1_1 | + (CX231XX_VIN_1_2 << 8) | + CX25840_SVIDEO_ON, + .amux = CX231XX_AMUX_LINE_IN, + .gpio = NULL, + } }, + }, }; const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); @@ -880,6 +906,8 @@ struct usb_device_id cx231xx_id_table[] = { .driver_info = CX231XX_BOARD_ELGATO_VIDEO_CAPTURE_V2}, {USB_DEVICE(0x1f4d, 0x0102), .driver_info = CX231XX_BOARD_OTG102}, + {USB_DEVICE(USB_VID_TERRATEC, 0x00a6), + .driver_info = CX231XX_BOARD_TERRATEC_GRABBY}, {}, }; diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index 00d3bce9a690..54790fbe8fdc 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -77,6 +77,7 @@ #define CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx 19 #define CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx 20 #define CX231XX_BOARD_HAUPPAUGE_955Q 21 +#define CX231XX_BOARD_TERRATEC_GRABBY 22 /* Limits minimum and default number of buffers */ #define CX231XX_MIN_BUF 4 -- cgit v1.2.3-59-g8ed1b From 4b7574fb3cac1507b12af9f8e22d50cd1ec9673b Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Thu, 21 May 2015 06:29:23 -0300 Subject: [media] b2c2: Mismatch in config ifdefs for SkystarS2 Compilation warning issued by kbuild test robot: >> drivers/media/common/b2c2/flexcop-fe-tuner.c:31:12: warning: 'flexcop_fe_request_firmware' defined but not used [-Wunused-function] static int flexcop_fe_request_firmware(struct dvb_frontend *fe, This patch fixes a mismatch in Kconfig define checks. One had a check for just CX24120, the other is checking for both CX24120 and ISL6421. Signed-off-by: Jemma Denson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/b2c2/flexcop-fe-tuner.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/common/b2c2/flexcop-fe-tuner.c b/drivers/media/common/b2c2/flexcop-fe-tuner.c index 5e5696729eca..b4e545956c2d 100644 --- a/drivers/media/common/b2c2/flexcop-fe-tuner.c +++ b/drivers/media/common/b2c2/flexcop-fe-tuner.c @@ -27,7 +27,7 @@ #define FE_SUPPORTED(fe) (defined(CONFIG_DVB_##fe) || \ (defined(CONFIG_DVB_##fe##_MODULE) && defined(MODULE))) -#if FE_SUPPORTED(BCM3510) || FE_SUPPORTED(CX24120) +#if FE_SUPPORTED(BCM3510) || (FE_SUPPORTED(CX24120) && FE_SUPPORTED(ISL6421)) static int flexcop_fe_request_firmware(struct dvb_frontend *fe, const struct firmware **fw, char *name) { -- cgit v1.2.3-59-g8ed1b From de983454d6bd1c050679ceeb70189161d569c488 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 21 May 2015 15:53:01 -0300 Subject: [media] saa7134: add AverMedia AverTV/505 card support Add AverMedia AverTV/505 card to saa7134 driver. It is a card bearing SAA7130HL chip and FQ1216ME/IH-3 tuner. Working: Composite, TV and IR remote control. Untested: S-Video. [mchehab@osg.samsung.com: fix CodingStyle] Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.saa7134 | 1 + drivers/media/pci/saa7134/saa7134-cards.c | 42 +++++++++++++++++++++++++++++- drivers/media/pci/saa7134/saa7134-input.c | 2 ++ drivers/media/pci/saa7134/saa7134.h | 1 + 4 files changed, 45 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index a93d86455233..f4b395bdc090 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 @@ -192,3 +192,4 @@ 191 -> Hawell HW-9004V1 192 -> AverMedia AverTV Satellite Hybrid+FM A706 [1461:2055] 193 -> WIS Voyager or compatible [1905:7007] +194 -> AverMedia AverTV/505 [1461:a10a] diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c index c52032940af6..c7405766609c 100644 --- a/drivers/media/pci/saa7134/saa7134-cards.c +++ b/drivers/media/pci/saa7134/saa7134-cards.c @@ -5851,6 +5851,39 @@ struct saa7134_board saa7134_boards[] = { .amux = LINE1, } }, }, + [SAA7134_BOARD_AVERMEDIA_505] = { + /* much like the "studio" version but without radio + * and another tuner (dbaryshkov@gmail.com) */ + .name = "AverMedia AverTV/505", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FQ1216ME, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .inputs = {{ + .name = name_tv, + .vmux = 1, + .amux = LINE2, + .tv = 1, + }, { + .name = name_comp1, + .vmux = 0, + .amux = LINE2, + }, { + .name = name_comp2, + .vmux = 3, + .amux = LINE2, + }, { + .name = name_svideo, + .vmux = 8, + .amux = LINE2, + } }, + .mute = { + .name = name_mute, + .amux = LINE1, + }, + }, }; @@ -7109,6 +7142,12 @@ struct pci_device_id saa7134_pci_tbl[] = { .subvendor = 0x1905, /* WIS */ .subdevice = 0x7007, .driver_data = SAA7134_BOARD_WIS_VOYAGER, + }, { + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7130, + .subvendor = 0x1461, /* Avermedia Technologies Inc */ + .subdevice = 0xa10a, + .driver_data = SAA7134_BOARD_AVERMEDIA_505, }, { /* --- boards without eeprom + subsystem ID --- */ .vendor = PCI_VENDOR_ID_PHILIPS, @@ -7449,8 +7488,9 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_KWORLD_VSTREAM_XPERT: case SAA7134_BOARD_KWORLD_XPERT: case SAA7134_BOARD_AVERMEDIA_STUDIO_305: - case SAA7134_BOARD_AVERMEDIA_STUDIO_505: case SAA7134_BOARD_AVERMEDIA_305: + case SAA7134_BOARD_AVERMEDIA_STUDIO_505: + case SAA7134_BOARD_AVERMEDIA_505: case SAA7134_BOARD_AVERMEDIA_STUDIO_307: case SAA7134_BOARD_AVERMEDIA_307: case SAA7134_BOARD_AVERMEDIA_STUDIO_507: diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c index e92bcfe9bbcb..11a172000291 100644 --- a/drivers/media/pci/saa7134/saa7134-input.c +++ b/drivers/media/pci/saa7134/saa7134-input.c @@ -485,6 +485,7 @@ static int __saa7134_ir_start(void *priv) case SAA7134_BOARD_KWORLD_VSTREAM_XPERT: case SAA7134_BOARD_AVERMEDIA_305: case SAA7134_BOARD_AVERMEDIA_307: + case SAA7134_BOARD_AVERMEDIA_505: case SAA7134_BOARD_AVERMEDIA_STUDIO_305: case SAA7134_BOARD_AVERMEDIA_STUDIO_505: case SAA7134_BOARD_AVERMEDIA_STUDIO_307: @@ -633,6 +634,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) case SAA7134_BOARD_KWORLD_VSTREAM_XPERT: case SAA7134_BOARD_AVERMEDIA_305: case SAA7134_BOARD_AVERMEDIA_307: + case SAA7134_BOARD_AVERMEDIA_505: case SAA7134_BOARD_AVERMEDIA_STUDIO_305: case SAA7134_BOARD_AVERMEDIA_STUDIO_505: case SAA7134_BOARD_AVERMEDIA_STUDIO_307: diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h index f682ba9b34a7..6b5f6f45d285 100644 --- a/drivers/media/pci/saa7134/saa7134.h +++ b/drivers/media/pci/saa7134/saa7134.h @@ -341,6 +341,7 @@ struct saa7134_card_ir { #define SAA7134_BOARD_HAWELL_HW_9004V1 191 #define SAA7134_BOARD_AVERMEDIA_A706 192 #define SAA7134_BOARD_WIS_VOYAGER 193 +#define SAA7134_BOARD_AVERMEDIA_505 194 #define SAA7134_MAXBOARDS 32 #define SAA7134_INPUT_MAX 8 -- cgit v1.2.3-59-g8ed1b From 25e057fdde3b33c0d18605ed27b59336a3441925 Mon Sep 17 00:00:00 2001 From: Takeshi Yoshimura Date: Wed, 27 May 2015 11:28:14 -0300 Subject: [media] ddbridge: Do not free_irq() if request_irq() failed My static checker detected that free_irq() is called even after request_irq() failed in ddb_probe(). In this case, the kernel may try to free dev->pdev->irq although the IRQ is not assigned. This event rarely occurs, but always introduces a warning if it happens. "goto fail1" always results in disabling enabled MSI and releasing a requested IRQ. It seems like the former handling is necessary. So I added a conditional branch before the free_irq() (stat == 0 means request_irq() succeeds). Signed-off-by: Takeshi Yoshimura Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 9e3492e20766..0ac2dd35fe50 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -1630,7 +1630,8 @@ fail1: printk(KERN_ERR "fail1\n"); if (dev->msi) pci_disable_msi(dev->pdev); - free_irq(dev->pdev->irq, dev); + if (stat == 0) + free_irq(dev->pdev->irq, dev); fail: printk(KERN_ERR "fail\n"); ddb_unmap(dev); -- cgit v1.2.3-59-g8ed1b From d3525b632a0b5e113fb78b7db84598e082cf903b Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Sat, 30 May 2015 15:10:06 -0300 Subject: [media] b2c2: Add option to skip the first 6 pid filters The flexcop bridge chip has two banks of hardware pid filters - an initial 6, and on some chip revisions an additional bank of 32. A bug is present on the initial 6 - when changing transponders one of two PAT packets from the old transponder would be included in the initial packets from the new transponder. This usually transpired with userspace programs complaining about services missing, because they are seeing a PAT that they would not be expecting. Running in full TS mode does not exhibit this problem, neither does using just the additional 32. This patch adds in an option to not use the inital 6 and solely use just the additional 32, and enables this option for the SkystarS2 card. Other cards can be added as required if they also have this bug. Signed-off-by: Jemma Denson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/b2c2/flexcop-common.h | 1 + drivers/media/common/b2c2/flexcop-fe-tuner.c | 3 +++ drivers/media/common/b2c2/flexcop-hw-filter.c | 16 ++++++++++++++-- 3 files changed, 18 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/b2c2/flexcop-common.h b/drivers/media/common/b2c2/flexcop-common.h index 437912e49824..2b2460e9e6b4 100644 --- a/drivers/media/common/b2c2/flexcop-common.h +++ b/drivers/media/common/b2c2/flexcop-common.h @@ -91,6 +91,7 @@ struct flexcop_device { int feedcount; int pid_filtering; int fullts_streaming_state; + int skip_6_hw_pid_filter; /* bus specific callbacks */ flexcop_ibi_value(*read_ibi_reg) (struct flexcop_device *, diff --git a/drivers/media/common/b2c2/flexcop-fe-tuner.c b/drivers/media/common/b2c2/flexcop-fe-tuner.c index b4e545956c2d..9c59f4306883 100644 --- a/drivers/media/common/b2c2/flexcop-fe-tuner.c +++ b/drivers/media/common/b2c2/flexcop-fe-tuner.c @@ -652,6 +652,9 @@ static int skystarS2_rev33_attach(struct flexcop_device *fc, } info("ISL6421 successfully attached."); + if (fc->has_32_hw_pid_filter) + fc->skip_6_hw_pid_filter = 1; + return 1; } #else diff --git a/drivers/media/common/b2c2/flexcop-hw-filter.c b/drivers/media/common/b2c2/flexcop-hw-filter.c index 77e45475f4c7..8220257903ef 100644 --- a/drivers/media/common/b2c2/flexcop-hw-filter.c +++ b/drivers/media/common/b2c2/flexcop-hw-filter.c @@ -117,6 +117,10 @@ static void flexcop_pid_control(struct flexcop_device *fc, deb_ts("setting pid: %5d %04x at index %d '%s'\n", pid, pid, index, onoff ? "on" : "off"); + /* First 6 can be buggy - skip over them if option set */ + if (fc->skip_6_hw_pid_filter) + index += 6; + /* We could use bit magic here to reduce source code size. * I decided against it, but to use the real register names */ switch (index) { @@ -170,7 +174,10 @@ static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc, int onoff) int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff) { - int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32; + int max_pid_filter = 6; + + max_pid_filter -= 6 * fc->skip_6_hw_pid_filter; + max_pid_filter += 32 * fc->has_32_hw_pid_filter; fc->feedcount += onoff ? 1 : -1; /* the number of PIDs/Feed currently requested */ if (dvbdmxfeed->index >= max_pid_filter) @@ -217,7 +224,12 @@ void flexcop_hw_filter_init(struct flexcop_device *fc) { int i; flexcop_ibi_value v; - for (i = 0; i < 6 + 32*fc->has_32_hw_pid_filter; i++) + int max_pid_filter = 6; + + max_pid_filter -= 6 * fc->skip_6_hw_pid_filter; + max_pid_filter += 32 * fc->has_32_hw_pid_filter; + + for (i = 0; i < max_pid_filter; i++) flexcop_pid_control(fc, i, 0x1fff, 0); flexcop_pid_group_filter(fc, 0, 0x1fe0); -- cgit v1.2.3-59-g8ed1b From 9056a23ba19d911d4a079b8ca543fb8ebffa7c56 Mon Sep 17 00:00:00 2001 From: Tina Ruchandani Date: Sun, 31 May 2015 04:17:06 -0300 Subject: [media] dvb-frontend: Replace timeval with ktime_t struct timeval uses a 32-bit seconds representation which will overflow in the year 2038 and beyond. This patch replaces the usage of struct timeval with ktime_t which is a 64-bit timestamp and is year 2038 safe. This patch is part of a larger attempt to remove all instances of 32-bit timekeeping variables (timeval, timespec, time_t) which are not year 2038 safe, from the kernel. [mchehab@osg.samsung.com: add a missing parenthesis, breaking compilation] Suggested-by: Arnd Bergmann Signed-off-by: Tina Ruchandani Reviewed-by: Arnd Bergmann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_frontend.c | 41 ++++++++++------------------------- drivers/media/dvb-core/dvb_frontend.h | 3 +-- drivers/media/dvb-frontends/stv0299.c | 12 +++++----- 3 files changed, 19 insertions(+), 37 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 55a6b0500615..b30ca59de04f 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include "dvb_frontend.h" @@ -890,42 +891,21 @@ static void dvb_frontend_stop(struct dvb_frontend *fe) fepriv->thread); } -s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime) -{ - return ((curtime.tv_usec < lasttime.tv_usec) ? - 1000000 - lasttime.tv_usec + curtime.tv_usec : - curtime.tv_usec - lasttime.tv_usec); -} -EXPORT_SYMBOL(timeval_usec_diff); - -static inline void timeval_usec_add(struct timeval *curtime, u32 add_usec) -{ - curtime->tv_usec += add_usec; - if (curtime->tv_usec >= 1000000) { - curtime->tv_usec -= 1000000; - curtime->tv_sec++; - } -} - /* * Sleep until gettimeofday() > waketime + add_usec * This needs to be as precise as possible, but as the delay is * usually between 2ms and 32ms, it is done using a scheduled msleep * followed by usleep (normally a busy-wait loop) for the remainder */ -void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec) +void dvb_frontend_sleep_until(ktime_t *waketime, u32 add_usec) { - struct timeval lasttime; s32 delta, newdelta; - timeval_usec_add(waketime, add_usec); - - do_gettimeofday(&lasttime); - delta = timeval_usec_diff(lasttime, *waketime); + ktime_add_us(*waketime, add_usec); + delta = ktime_us_delta(ktime_get_real(), *waketime); if (delta > 2500) { msleep((delta - 1500) / 1000); - do_gettimeofday(&lasttime); - newdelta = timeval_usec_diff(lasttime, *waketime); + newdelta = ktime_us_delta(ktime_get_real(), *waketime); delta = (newdelta > delta) ? 0 : newdelta; } if (delta > 0) @@ -2463,13 +2443,13 @@ static int dvb_frontend_ioctl_legacy(struct file *file, * include the initialization or start bit */ unsigned long swcmd = ((unsigned long) parg) << 1; - struct timeval nexttime; - struct timeval tv[10]; + ktime_t nexttime; + ktime_t tv[10]; int i; u8 last = 1; if (dvb_frontend_debug) printk("%s switch command: 0x%04lx\n", __func__, swcmd); - do_gettimeofday(&nexttime); + nexttime = ktime_get_real(); if (dvb_frontend_debug) tv[0] = nexttime; /* before sending a command, initialize by sending @@ -2480,7 +2460,7 @@ static int dvb_frontend_ioctl_legacy(struct file *file, for (i = 0; i < 9; i++) { if (dvb_frontend_debug) - do_gettimeofday(&tv[i + 1]); + tv[i+1] = ktime_get_real(); if ((swcmd & 0x01) != last) { /* set voltage to (last ? 13V : 18V) */ fe->ops.set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18); @@ -2494,7 +2474,8 @@ static int dvb_frontend_ioctl_legacy(struct file *file, printk("%s(%d): switch delay (should be 32k followed by all 8k\n", __func__, fe->dvb->num); for (i = 1; i < 10; i++) - printk("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i])); + printk("%d: %d\n", i, + (int) ktime_us_delta(tv[i], tv[i-1])); } err = 0; fepriv->state = FESTATE_DISEQC; diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h index 4ff82041fdfd..4816947294fe 100644 --- a/drivers/media/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb-core/dvb_frontend.h @@ -441,7 +441,6 @@ extern void dvb_frontend_reinitialise(struct dvb_frontend *fe); extern int dvb_frontend_suspend(struct dvb_frontend *fe); extern int dvb_frontend_resume(struct dvb_frontend *fe); -extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec); -extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime); +extern void dvb_frontend_sleep_until(ktime_t *waketime, u32 add_usec); #endif diff --git a/drivers/media/dvb-frontends/stv0299.c b/drivers/media/dvb-frontends/stv0299.c index 0ca5d9f0d851..a8177807fb65 100644 --- a/drivers/media/dvb-frontends/stv0299.c +++ b/drivers/media/dvb-frontends/stv0299.c @@ -44,6 +44,7 @@ #include #include +#include #include #include #include @@ -407,8 +408,8 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long u8 lv_mask = 0x40; u8 last = 1; int i; - struct timeval nexttime; - struct timeval tv[10]; + ktime_t nexttime; + ktime_t tv[10]; reg0x08 = stv0299_readreg (state, 0x08); reg0x0c = stv0299_readreg (state, 0x0c); @@ -421,7 +422,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long if (debug_legacy_dish_switch) printk ("%s switch command: 0x%04lx\n",__func__, cmd); - do_gettimeofday (&nexttime); + nexttime = ktime_get_real(); if (debug_legacy_dish_switch) tv[0] = nexttime; stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */ @@ -430,7 +431,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long for (i=0; i<9; i++) { if (debug_legacy_dish_switch) - do_gettimeofday (&tv[i+1]); + tv[i+1] = ktime_get_real(); if((cmd & 0x01) != last) { /* set voltage to (last ? 13V : 18V) */ stv0299_writeregI (state, 0x0c, reg0x0c | (last ? lv_mask : 0x50)); @@ -446,7 +447,8 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long printk ("%s(%d): switch delay (should be 32k followed by all 8k\n", __func__, fe->dvb->num); for (i = 1; i < 10; i++) - printk ("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i])); + printk("%d: %d\n", i, + (int) ktime_us_delta(tv[i], tv[i-1])); } return 0; -- cgit v1.2.3-59-g8ed1b From 64657066f51355461b634a0aa6a1171d50c355c9 Mon Sep 17 00:00:00 2001 From: Heiko Stübner Date: Tue, 2 Jun 2015 11:43:50 -0300 Subject: [media] rc: gpio-ir-recv: don't sleep in irq handler Don't allow sleep when getting the gpio value in the irq-handler. On my rk3288 board this results in might_sleep warnings when receiving data like: BUG: sleeping function called from invalid context at drivers/gpio/gpiolib.c:1531 in_atomic(): 1, irqs_disabled(): 128, pid: 0, name: swapper/0 CPU: 0 PID: 0 Comm: swapper/0 Tainted: P 4.1.0-rc5+ #2011 Hardware name: Rockchip (Device Tree) [] (unwind_backtrace) from [] (show_stack+0x20/0x24) [] (show_stack) from [] (dump_stack+0x8c/0xbc) [] (dump_stack) from [] (___might_sleep+0x238/0x284) [] (___might_sleep) from [] (__might_sleep+0x90/0xa4) [] (__might_sleep) from [] (gpiod_get_raw_value_cansleep+0x28/0x44) [] (gpiod_get_raw_value_cansleep) from [] (gpio_ir_recv_irq+0x24/0x6c [gpio_ir_recv]) [] (gpio_ir_recv_irq [gpio_ir_recv]) from [] (handle_irq_event_percpu+0x164/0x550) [] (handle_irq_event_percpu) from [] (handle_irq_event+0x4c/0x6c) [] (handle_irq_event) from [] (handle_edge_irq+0x128/0x150) [] (handle_edge_irq) from [] (generic_handle_irq+0x30/0x40) [] (generic_handle_irq) from [] (rockchip_irq_demux+0x158/0x210) [] (rockchip_irq_demux) from [] (generic_handle_irq+0x30/0x40) [] (generic_handle_irq) from [] (__handle_domain_irq+0x98/0xc0) [] (__handle_domain_irq) from [] (gic_handle_irq+0x4c/0x70) [] (gic_handle_irq) from [] (__irq_svc+0x44/0x5c) Signed-off-by: Heiko Stuebner Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/gpio-ir-recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c index 707df5422666..7dbc9ca6d885 100644 --- a/drivers/media/rc/gpio-ir-recv.c +++ b/drivers/media/rc/gpio-ir-recv.c @@ -78,7 +78,7 @@ static irqreturn_t gpio_ir_recv_irq(int irq, void *dev_id) int rc = 0; enum raw_event_type type = IR_SPACE; - gval = gpio_get_value_cansleep(gpio_dev->gpio_nr); + gval = gpio_get_value(gpio_dev->gpio_nr); if (gval < 0) goto err_get_value; -- cgit v1.2.3-59-g8ed1b From 95a86e43183eeeef72105372074f4ef127b27807 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 10 Jun 2015 02:45:45 -0300 Subject: [media] cobalt: fix 64-bit division There are still some 64-bit division problems in the cobalt code. Replace it by div_u64. [mchehab@osg.samsung.com: folded with an additional diff sent by Hans via a priv e-mail] Signed-off-by: Hans Verkuil Reported-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cobalt/cobalt-cpld.c | 14 +++++++------- drivers/media/pci/cobalt/cobalt-v4l2.c | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/cobalt/cobalt-cpld.c b/drivers/media/pci/cobalt/cobalt-cpld.c index 5a28d9b28dc9..e83f5c9f7e7d 100644 --- a/drivers/media/pci/cobalt/cobalt-cpld.c +++ b/drivers/media/pci/cobalt/cobalt-cpld.c @@ -240,8 +240,8 @@ static const struct multiplier multipliers[] = { bool cobalt_cpld_set_freq(struct cobalt *cobalt, unsigned f_out) { const unsigned f_xtal = 39170000; /* xtal for si598 */ - unsigned long long dco; - unsigned long long rfreq; + u64 dco; + u64 rfreq; unsigned delta = 0xffffffff; unsigned i_best = 0; unsigned i; @@ -253,12 +253,12 @@ bool cobalt_cpld_set_freq(struct cobalt *cobalt, unsigned f_out) for (i = 0; i < ARRAY_SIZE(multipliers); i++) { unsigned mult = multipliers[i].mult; - unsigned d; + u32 d; - dco = (unsigned long long)f_out * mult; + dco = (u64)f_out * mult; if (dco < DCO_MIN || dco > DCO_MAX) continue; - d = ((dco << 28) + f_xtal / 2) % f_xtal; + div_u64_rem((dco << 28) + f_xtal / 2, f_xtal, &d); if (d < delta) { found = 1; i_best = i; @@ -267,10 +267,10 @@ bool cobalt_cpld_set_freq(struct cobalt *cobalt, unsigned f_out) } if (!found) return false; - dco = (unsigned long long)f_out * multipliers[i_best].mult; + dco = (u64)f_out * multipliers[i_best].mult; n1 = multipliers[i_best].n1 - 1; hsdiv = multipliers[i_best].hsdiv - 4; - rfreq = (dco << 28) / f_xtal; + rfreq = div_u64(dco << 28, f_xtal); clock_ctrl = cpld_read(cobalt, SI570_CLOCK_CTRL); clock_ctrl |= S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_FPGA_CTRL; diff --git a/drivers/media/pci/cobalt/cobalt-v4l2.c b/drivers/media/pci/cobalt/cobalt-v4l2.c index 6fb8812990f4..b40c2d141b58 100644 --- a/drivers/media/pci/cobalt/cobalt-v4l2.c +++ b/drivers/media/pci/cobalt/cobalt-v4l2.c @@ -327,7 +327,7 @@ static int cobalt_start_streaming(struct vb2_queue *q, unsigned int count) iowrite32(clk_freq / 1000000, &clkloss->ref_clk_cnt_val); /* The lower bound for the clock frequency is 0.5% lower as is * allowed by the spec */ - iowrite32((((u64)bt->pixelclock * 995) / 1000) / 1000000, + iowrite32(div_u64(bt->pixelclock * 995, 1000000000), &clkloss->test_clk_cnt_val); /* will be enabled after the first frame has been received */ iowrite32(bt->width * bt->height, &fw->active_length); -- cgit v1.2.3-59-g8ed1b From af9d52555304979c7a3ce254e026bc76bd878f74 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 26 Mar 2015 10:04:09 -0300 Subject: [media] ts2020: re-implement PLL calculations Used frequency synthesizer is simple Integer-N PLL, with configurable reference divider, output divider and of course N itself. Old calculations were working fine, but not so easy to understand. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/ts2020.c | 76 +++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 32 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c index 90164a38cd36..bc48388906d3 100644 --- a/drivers/media/dvb-frontends/ts2020.c +++ b/drivers/media/dvb-frontends/ts2020.c @@ -32,8 +32,8 @@ struct ts2020_priv { struct i2c_adapter *i2c; u8 clk_out:2; u8 clk_out_div:5; - u32 frequency; - u32 frequency_div; + u32 frequency_div; /* LO output divider switch frequency */ + u32 frequency_khz; /* actual used LO frequency */ #define TS2020_M88TS2020 0 #define TS2020_M88TS2022 1 u8 tuner; @@ -233,45 +233,62 @@ static int ts2020_set_params(struct dvb_frontend *fe) struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct ts2020_priv *priv = fe->tuner_priv; int ret; - u32 frequency = c->frequency; - s32 offset_khz; u32 symbol_rate = (c->symbol_rate / 1000); u32 f3db, gdiv28; - u16 value, ndiv, lpf_coeff; - u8 lpf_mxdiv, mlpf_max, mlpf_min, nlpf; - u8 lo = 0x01, div4 = 0x0; - - /* Calculate frequency divider */ - if (frequency < priv->frequency_div) { - lo |= 0x10; - div4 = 0x1; - ndiv = (frequency * 14 * 4) / TS2020_XTAL_FREQ; - } else - ndiv = (frequency * 14 * 2) / TS2020_XTAL_FREQ; - ndiv = ndiv + ndiv % 2; - ndiv = ndiv - 1024; + u16 u16tmp, value, lpf_coeff; + u8 buf[3], reg10, lpf_mxdiv, mlpf_max, mlpf_min, nlpf; + unsigned int f_ref_khz, f_vco_khz, div_ref, div_out, pll_n; + unsigned int frequency_khz = c->frequency; + + /* + * Integer-N PLL synthesizer + * kHz is used for all calculations to keep calculations within 32-bit + */ + f_ref_khz = TS2020_XTAL_FREQ; + div_ref = DIV_ROUND_CLOSEST(f_ref_khz, 2000); + + /* select LO output divider */ + if (frequency_khz < priv->frequency_div) { + div_out = 4; + reg10 = 0x10; + } else { + div_out = 2; + reg10 = 0x00; + } + + f_vco_khz = frequency_khz * div_out; + pll_n = f_vco_khz * div_ref / f_ref_khz; + pll_n += pll_n % 2; + priv->frequency_khz = pll_n * f_ref_khz / div_ref / div_out; + + pr_debug("frequency=%u offset=%d f_vco_khz=%u pll_n=%u div_ref=%u div_out=%u\n", + priv->frequency_khz, priv->frequency_khz - c->frequency, + f_vco_khz, pll_n, div_ref, div_out); if (priv->tuner == TS2020_M88TS2020) { lpf_coeff = 2766; - ret = ts2020_writereg(fe, 0x10, 0x80 | lo); + reg10 |= 0x01; + ret = ts2020_writereg(fe, 0x10, reg10); } else { lpf_coeff = 3200; - ret = ts2020_writereg(fe, 0x10, 0x0b); + reg10 |= 0x0b; + ret = ts2020_writereg(fe, 0x10, reg10); ret |= ts2020_writereg(fe, 0x11, 0x40); } - /* Set frequency divider */ - ret |= ts2020_writereg(fe, 0x01, (ndiv >> 8) & 0xf); - ret |= ts2020_writereg(fe, 0x02, ndiv & 0xff); + u16tmp = pll_n - 1024; + buf[0] = (u16tmp >> 8) & 0xff; + buf[1] = (u16tmp >> 0) & 0xff; + buf[2] = div_ref - 8; + + ret |= ts2020_writereg(fe, 0x01, buf[0]); + ret |= ts2020_writereg(fe, 0x02, buf[1]); + ret |= ts2020_writereg(fe, 0x03, buf[2]); - ret |= ts2020_writereg(fe, 0x03, 0x06); ret |= ts2020_tuner_gate_ctrl(fe, 0x10); if (ret < 0) return -ENODEV; - /* Tuner Frequency Range */ - ret = ts2020_writereg(fe, 0x10, lo); - ret |= ts2020_tuner_gate_ctrl(fe, 0x08); /* Tuner RF */ @@ -335,11 +352,6 @@ static int ts2020_set_params(struct dvb_frontend *fe) ret |= ts2020_tuner_gate_ctrl(fe, 0x01); msleep(80); - /* calculate offset assuming 96000kHz*/ - offset_khz = (ndiv - ndiv % 2 + 1024) * TS2020_XTAL_FREQ - / (6 + 8) / (div4 + 1) / 2; - - priv->frequency = offset_khz; return (ret < 0) ? -EINVAL : 0; } @@ -347,8 +359,8 @@ static int ts2020_set_params(struct dvb_frontend *fe) static int ts2020_get_frequency(struct dvb_frontend *fe, u32 *frequency) { struct ts2020_priv *priv = fe->tuner_priv; - *frequency = priv->frequency; + *frequency = priv->frequency_khz; return 0; } -- cgit v1.2.3-59-g8ed1b From 2ca58f45cc986952dc2b2942fb170d9d7644735a Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 26 Mar 2015 10:49:17 -0300 Subject: [media] ts2020: improve filter limit calc * We don't need calculate channel bandwidth from symbol rate as it is calculated by DVB core. * Use clamp() to force upper/lower limit of filter 3dB frequency. Upper limit should never exceeded 40MHz (80MHz BW) in any case, though... Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/ts2020.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c index bc48388906d3..590f7e1b56f3 100644 --- a/drivers/media/dvb-frontends/ts2020.c +++ b/drivers/media/dvb-frontends/ts2020.c @@ -233,7 +233,6 @@ static int ts2020_set_params(struct dvb_frontend *fe) struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct ts2020_priv *priv = fe->tuner_priv; int ret; - u32 symbol_rate = (c->symbol_rate / 1000); u32 f3db, gdiv28; u16 u16tmp, value, lpf_coeff; u8 buf[3], reg10, lpf_mxdiv, mlpf_max, mlpf_min, nlpf; @@ -312,12 +311,9 @@ static int ts2020_set_params(struct dvb_frontend *fe) value = ts2020_readreg(fe, 0x26); - f3db = (symbol_rate * 135) / 200 + 2000; - f3db += FREQ_OFFSET_LOW_SYM_RATE; - if (f3db < 7000) - f3db = 7000; - if (f3db > 40000) - f3db = 40000; + f3db = (c->bandwidth_hz / 1000 / 2) + 2000; + f3db += FREQ_OFFSET_LOW_SYM_RATE; /* FIXME: ~always too wide filter */ + f3db = clamp(f3db, 7000U, 40000U); gdiv28 = gdiv28 * 207 / (value * 2 + 151); mlpf_max = gdiv28 * 135 / 100; -- cgit v1.2.3-59-g8ed1b From e6ad9ce3e96bb446c6cf0e83a43888e7f30b84ad Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 26 Mar 2015 20:20:42 -0300 Subject: [media] ts2020: register I2C driver from legacy media attach Register driver using I2C bindings internally when legacy media attach is used. That is done by registering driver using I2C binding from legacy attach. That way we can get valid I2C client, which is needed for proper dev_() logging and regmap for example even legacy binding is used. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/ts2020.c | 73 ++++++++++++------------------------ drivers/media/dvb-frontends/ts2020.h | 7 +++- 2 files changed, 30 insertions(+), 50 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c index 590f7e1b56f3..7b2f301b1d5c 100644 --- a/drivers/media/dvb-frontends/ts2020.c +++ b/drivers/media/dvb-frontends/ts2020.c @@ -26,6 +26,7 @@ #define FREQ_OFFSET_LOW_SYM_RATE 3000 struct ts2020_priv { + struct i2c_client *client; struct dvb_frontend *fe; /* i2c details */ int i2c_address; @@ -47,8 +48,12 @@ struct ts2020_reg_val { static int ts2020_release(struct dvb_frontend *fe) { - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; + struct ts2020_priv *priv = fe->tuner_priv; + struct i2c_client *client = priv->client; + + dev_dbg(&client->dev, "\n"); + + i2c_unregister_device(client); return 0; } @@ -410,50 +415,22 @@ struct dvb_frontend *ts2020_attach(struct dvb_frontend *fe, const struct ts2020_config *config, struct i2c_adapter *i2c) { - struct ts2020_priv *priv = NULL; - u8 buf; - - priv = kzalloc(sizeof(struct ts2020_priv), GFP_KERNEL); - if (priv == NULL) + struct i2c_client *client; + struct i2c_board_info board_info; + struct ts2020_config pdata; + + memcpy(&pdata, config, sizeof(pdata)); + pdata.fe = fe; + pdata.attach_in_use = true; + + memset(&board_info, 0, sizeof(board_info)); + strlcpy(board_info.type, "ts2020", I2C_NAME_SIZE); + board_info.addr = config->tuner_address; + board_info.platform_data = &pdata; + client = i2c_new_device(i2c, &board_info); + if (!client || !client->dev.driver) return NULL; - priv->i2c_address = config->tuner_address; - priv->i2c = i2c; - priv->clk_out = config->clk_out; - priv->clk_out_div = config->clk_out_div; - priv->frequency_div = config->frequency_div; - priv->fe = fe; - fe->tuner_priv = priv; - - if (!priv->frequency_div) - priv->frequency_div = 1060000; - - /* Wake Up the tuner */ - if ((0x03 & ts2020_readreg(fe, 0x00)) == 0x00) { - ts2020_writereg(fe, 0x00, 0x01); - msleep(2); - } - - ts2020_writereg(fe, 0x00, 0x03); - msleep(2); - - /* Check the tuner version */ - buf = ts2020_readreg(fe, 0x00); - if ((buf == 0x01) || (buf == 0x41) || (buf == 0x81)) { - printk(KERN_INFO "%s: Find tuner TS2020!\n", __func__); - priv->tuner = TS2020_M88TS2020; - } else if ((buf == 0x83) || (buf == 0xc3)) { - printk(KERN_INFO "%s: Find tuner TS2022!\n", __func__); - priv->tuner = TS2020_M88TS2022; - } else { - printk(KERN_ERR "%s: Read tuner reg[0] = %d\n", __func__, buf); - kfree(priv); - return NULL; - } - - memcpy(&fe->ops.tuner_ops, &ts2020_tuner_ops, - sizeof(struct dvb_tuner_ops)); - return fe; } EXPORT_SYMBOL(ts2020_attach); @@ -482,6 +459,7 @@ static int ts2020_probe(struct i2c_client *client, dev->frequency_div = pdata->frequency_div; dev->fe = fe; fe->tuner_priv = dev; + dev->client = client; /* check if the tuner is there */ ret = ts2020_readreg(fe, 0x00); @@ -574,7 +552,8 @@ static int ts2020_probe(struct i2c_client *client, memcpy(&fe->ops.tuner_ops, &ts2020_tuner_ops, sizeof(struct dvb_tuner_ops)); - fe->ops.tuner_ops.release = NULL; + if (!pdata->attach_in_use) + fe->ops.tuner_ops.release = NULL; i2c_set_clientdata(client, dev); return 0; @@ -587,14 +566,10 @@ err: static int ts2020_remove(struct i2c_client *client) { struct ts2020_priv *dev = i2c_get_clientdata(client); - struct dvb_frontend *fe = dev->fe; dev_dbg(&client->dev, "\n"); - memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops)); - fe->tuner_priv = NULL; kfree(dev); - return 0; } diff --git a/drivers/media/dvb-frontends/ts2020.h b/drivers/media/dvb-frontends/ts2020.h index 1714af94eca2..f40bbcf9f6eb 100644 --- a/drivers/media/dvb-frontends/ts2020.h +++ b/drivers/media/dvb-frontends/ts2020.h @@ -52,10 +52,15 @@ struct ts2020_config { * pointer to DVB frontend */ struct dvb_frontend *fe; + + /* + * driver private, do not set value + */ + u8 attach_in_use:1; }; +/* Do not add new ts2020_attach() users! Use I2C bindings instead. */ #if IS_REACHABLE(CONFIG_DVB_TS2020) - extern struct dvb_frontend *ts2020_attach( struct dvb_frontend *fe, const struct ts2020_config *config, -- cgit v1.2.3-59-g8ed1b From f158cbceb165f318a89a8bb831dc3ea27823b3f8 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Fri, 27 Mar 2015 18:14:25 -0300 Subject: [media] ts2020: convert to regmap I2C API Use regmap to cover I2C register access. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/Kconfig | 3 +- drivers/media/dvb-frontends/ts2020.c | 260 ++++++++++++++++------------------- 2 files changed, 124 insertions(+), 139 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index 65034a82b24e..ba65a001ba25 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -239,7 +239,8 @@ config DVB_SI21XX config DVB_TS2020 tristate "Montage Tehnology TS2020 based tuners" - depends on DVB_CORE && I2C + depends on DVB_CORE + select REGMAP_I2C default m if !MEDIA_SUBDRV_AUTOSELECT help A DVB-S/S2 silicon tuner. Say Y when you want to support this tuner. diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c index 7b2f301b1d5c..797112bbbaa8 100644 --- a/drivers/media/dvb-frontends/ts2020.c +++ b/drivers/media/dvb-frontends/ts2020.c @@ -21,12 +21,16 @@ #include "dvb_frontend.h" #include "ts2020.h" +#include #define TS2020_XTAL_FREQ 27000 /* in kHz */ #define FREQ_OFFSET_LOW_SYM_RATE 3000 struct ts2020_priv { struct i2c_client *client; + struct mutex regmap_mutex; + struct regmap_config regmap_config; + struct regmap *regmap; struct dvb_frontend *fe; /* i2c details */ int i2c_address; @@ -57,74 +61,6 @@ static int ts2020_release(struct dvb_frontend *fe) return 0; } -static int ts2020_writereg(struct dvb_frontend *fe, int reg, int data) -{ - struct ts2020_priv *priv = fe->tuner_priv; - u8 buf[] = { reg, data }; - struct i2c_msg msg[] = { - { - .addr = priv->i2c_address, - .flags = 0, - .buf = buf, - .len = 2 - } - }; - int err; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - err = i2c_transfer(priv->i2c, msg, 1); - if (err != 1) { - printk(KERN_ERR - "%s: writereg error(err == %i, reg == 0x%02x, value == 0x%02x)\n", - __func__, err, reg, data); - return -EREMOTEIO; - } - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - return 0; -} - -static int ts2020_readreg(struct dvb_frontend *fe, u8 reg) -{ - struct ts2020_priv *priv = fe->tuner_priv; - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - struct i2c_msg msg[] = { - { - .addr = priv->i2c_address, - .flags = 0, - .buf = b0, - .len = 1 - }, { - .addr = priv->i2c_address, - .flags = I2C_M_RD, - .buf = b1, - .len = 1 - } - }; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - ret = i2c_transfer(priv->i2c, msg, 2); - - if (ret != 2) { - printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", - __func__, reg, ret); - return ret; - } - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - return b1[0]; -} - static int ts2020_sleep(struct dvb_frontend *fe) { struct ts2020_priv *priv = fe->tuner_priv; @@ -135,7 +71,7 @@ static int ts2020_sleep(struct dvb_frontend *fe) else u8tmp = 0x00; - return ts2020_writereg(fe, u8tmp, 0x00); + return regmap_write(priv->regmap, u8tmp, 0x00); } static int ts2020_init(struct dvb_frontend *fe) @@ -145,14 +81,14 @@ static int ts2020_init(struct dvb_frontend *fe) u8 u8tmp; if (priv->tuner == TS2020_M88TS2020) { - ts2020_writereg(fe, 0x42, 0x73); - ts2020_writereg(fe, 0x05, priv->clk_out_div); - ts2020_writereg(fe, 0x20, 0x27); - ts2020_writereg(fe, 0x07, 0x02); - ts2020_writereg(fe, 0x11, 0xff); - ts2020_writereg(fe, 0x60, 0xf9); - ts2020_writereg(fe, 0x08, 0x01); - ts2020_writereg(fe, 0x00, 0x41); + regmap_write(priv->regmap, 0x42, 0x73); + regmap_write(priv->regmap, 0x05, priv->clk_out_div); + regmap_write(priv->regmap, 0x20, 0x27); + regmap_write(priv->regmap, 0x07, 0x02); + regmap_write(priv->regmap, 0x11, 0xff); + regmap_write(priv->regmap, 0x60, 0xf9); + regmap_write(priv->regmap, 0x08, 0x01); + regmap_write(priv->regmap, 0x00, 0x41); } else { static const struct ts2020_reg_val reg_vals[] = { {0x7d, 0x9d}, @@ -168,8 +104,8 @@ static int ts2020_init(struct dvb_frontend *fe) {0x12, 0xa0}, }; - ts2020_writereg(fe, 0x00, 0x01); - ts2020_writereg(fe, 0x00, 0x03); + regmap_write(priv->regmap, 0x00, 0x01); + regmap_write(priv->regmap, 0x00, 0x03); switch (priv->clk_out) { case TS2020_CLK_OUT_DISABLED: @@ -177,7 +113,7 @@ static int ts2020_init(struct dvb_frontend *fe) break; case TS2020_CLK_OUT_ENABLED: u8tmp = 0x70; - ts2020_writereg(fe, 0x05, priv->clk_out_div); + regmap_write(priv->regmap, 0x05, priv->clk_out_div); break; case TS2020_CLK_OUT_ENABLED_XTALOUT: u8tmp = 0x6c; @@ -187,17 +123,18 @@ static int ts2020_init(struct dvb_frontend *fe) break; } - ts2020_writereg(fe, 0x42, u8tmp); + regmap_write(priv->regmap, 0x42, u8tmp); if (priv->loop_through) u8tmp = 0xec; else u8tmp = 0x6c; - ts2020_writereg(fe, 0x62, u8tmp); + regmap_write(priv->regmap, 0x62, u8tmp); for (i = 0; i < ARRAY_SIZE(reg_vals); i++) - ts2020_writereg(fe, reg_vals[i].reg, reg_vals[i].val); + regmap_write(priv->regmap, reg_vals[i].reg, + reg_vals[i].val); } return 0; @@ -205,32 +142,35 @@ static int ts2020_init(struct dvb_frontend *fe) static int ts2020_tuner_gate_ctrl(struct dvb_frontend *fe, u8 offset) { + struct ts2020_priv *priv = fe->tuner_priv; int ret; - ret = ts2020_writereg(fe, 0x51, 0x1f - offset); - ret |= ts2020_writereg(fe, 0x51, 0x1f); - ret |= ts2020_writereg(fe, 0x50, offset); - ret |= ts2020_writereg(fe, 0x50, 0x00); + ret = regmap_write(priv->regmap, 0x51, 0x1f - offset); + ret |= regmap_write(priv->regmap, 0x51, 0x1f); + ret |= regmap_write(priv->regmap, 0x50, offset); + ret |= regmap_write(priv->regmap, 0x50, 0x00); msleep(20); return ret; } static int ts2020_set_tuner_rf(struct dvb_frontend *fe) { - int reg; - - reg = ts2020_readreg(fe, 0x3d); - reg &= 0x7f; - if (reg < 0x16) - reg = 0xa1; - else if (reg == 0x16) - reg = 0x99; + struct ts2020_priv *dev = fe->tuner_priv; + int ret; + unsigned int utmp; + + ret = regmap_read(dev->regmap, 0x3d, &utmp); + utmp &= 0x7f; + if (utmp < 0x16) + utmp = 0xa1; + else if (utmp == 0x16) + utmp = 0x99; else - reg = 0xf9; + utmp = 0xf9; - ts2020_writereg(fe, 0x60, reg); - reg = ts2020_tuner_gate_ctrl(fe, 0x08); + regmap_write(dev->regmap, 0x60, utmp); + ret = ts2020_tuner_gate_ctrl(fe, 0x08); - return reg; + return ret; } static int ts2020_set_params(struct dvb_frontend *fe) @@ -238,6 +178,7 @@ static int ts2020_set_params(struct dvb_frontend *fe) struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct ts2020_priv *priv = fe->tuner_priv; int ret; + unsigned int utmp; u32 f3db, gdiv28; u16 u16tmp, value, lpf_coeff; u8 buf[3], reg10, lpf_mxdiv, mlpf_max, mlpf_min, nlpf; @@ -272,12 +213,12 @@ static int ts2020_set_params(struct dvb_frontend *fe) if (priv->tuner == TS2020_M88TS2020) { lpf_coeff = 2766; reg10 |= 0x01; - ret = ts2020_writereg(fe, 0x10, reg10); + ret = regmap_write(priv->regmap, 0x10, reg10); } else { lpf_coeff = 3200; reg10 |= 0x0b; - ret = ts2020_writereg(fe, 0x10, reg10); - ret |= ts2020_writereg(fe, 0x11, 0x40); + ret = regmap_write(priv->regmap, 0x10, reg10); + ret |= regmap_write(priv->regmap, 0x11, 0x40); } u16tmp = pll_n - 1024; @@ -285,9 +226,9 @@ static int ts2020_set_params(struct dvb_frontend *fe) buf[1] = (u16tmp >> 0) & 0xff; buf[2] = div_ref - 8; - ret |= ts2020_writereg(fe, 0x01, buf[0]); - ret |= ts2020_writereg(fe, 0x02, buf[1]); - ret |= ts2020_writereg(fe, 0x03, buf[2]); + ret |= regmap_write(priv->regmap, 0x01, buf[0]); + ret |= regmap_write(priv->regmap, 0x02, buf[1]); + ret |= regmap_write(priv->regmap, 0x03, buf[2]); ret |= ts2020_tuner_gate_ctrl(fe, 0x10); if (ret < 0) @@ -300,21 +241,22 @@ static int ts2020_set_params(struct dvb_frontend *fe) ret |= ts2020_set_tuner_rf(fe); gdiv28 = (TS2020_XTAL_FREQ / 1000 * 1694 + 500) / 1000; - ret |= ts2020_writereg(fe, 0x04, gdiv28 & 0xff); + ret |= regmap_write(priv->regmap, 0x04, gdiv28 & 0xff); ret |= ts2020_tuner_gate_ctrl(fe, 0x04); if (ret < 0) return -ENODEV; if (priv->tuner == TS2020_M88TS2022) { - ret = ts2020_writereg(fe, 0x25, 0x00); - ret |= ts2020_writereg(fe, 0x27, 0x70); - ret |= ts2020_writereg(fe, 0x41, 0x09); - ret |= ts2020_writereg(fe, 0x08, 0x0b); + ret = regmap_write(priv->regmap, 0x25, 0x00); + ret |= regmap_write(priv->regmap, 0x27, 0x70); + ret |= regmap_write(priv->regmap, 0x41, 0x09); + ret |= regmap_write(priv->regmap, 0x08, 0x0b); if (ret < 0) return -ENODEV; } - value = ts2020_readreg(fe, 0x26); + regmap_read(priv->regmap, 0x26, &utmp); + value = utmp; f3db = (c->bandwidth_hz / 1000 / 2) + 2000; f3db += FREQ_OFFSET_LOW_SYM_RATE; /* FIXME: ~always too wide filter */ @@ -345,8 +287,8 @@ static int ts2020_set_params(struct dvb_frontend *fe) if (lpf_mxdiv > mlpf_max) lpf_mxdiv = mlpf_max; - ret = ts2020_writereg(fe, 0x04, lpf_mxdiv); - ret |= ts2020_writereg(fe, 0x06, nlpf); + ret = regmap_write(priv->regmap, 0x04, lpf_mxdiv); + ret |= regmap_write(priv->regmap, 0x06, nlpf); ret |= ts2020_tuner_gate_ctrl(fe, 0x04); @@ -375,11 +317,15 @@ static int ts2020_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) static int ts2020_read_signal_strength(struct dvb_frontend *fe, u16 *signal_strength) { + struct ts2020_priv *priv = fe->tuner_priv; + unsigned int utmp; u16 sig_reading, sig_strength; u8 rfgain, bbgain; - rfgain = ts2020_readreg(fe, 0x3d) & 0x1f; - bbgain = ts2020_readreg(fe, 0x21) & 0x1f; + regmap_read(priv->regmap, 0x3d, &utmp); + rfgain = utmp & 0x1f; + regmap_read(priv->regmap, 0x21, &utmp); + bbgain = utmp & 0x1f; if (rfgain > 15) rfgain = 15; @@ -435,6 +381,29 @@ struct dvb_frontend *ts2020_attach(struct dvb_frontend *fe, } EXPORT_SYMBOL(ts2020_attach); +/* + * We implement own regmap locking due to legacy DVB attach which uses frontend + * gate control callback to control I2C bus access. We can open / close gate and + * serialize whole open / I2C-operation / close sequence at the same. + */ +static void ts2020_regmap_lock(void *__dev) +{ + struct ts2020_priv *dev = __dev; + + mutex_lock(&dev->regmap_mutex); + if (dev->fe->ops.i2c_gate_ctrl) + dev->fe->ops.i2c_gate_ctrl(dev->fe, 1); +} + +static void ts2020_regmap_unlock(void *__dev) +{ + struct ts2020_priv *dev = __dev; + + if (dev->fe->ops.i2c_gate_ctrl) + dev->fe->ops.i2c_gate_ctrl(dev->fe, 0); + mutex_unlock(&dev->regmap_mutex); +} + static int ts2020_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -452,6 +421,19 @@ static int ts2020_probe(struct i2c_client *client, goto err; } + /* create regmap */ + mutex_init(&dev->regmap_mutex); + dev->regmap_config.reg_bits = 8, + dev->regmap_config.val_bits = 8, + dev->regmap_config.lock = ts2020_regmap_lock, + dev->regmap_config.unlock = ts2020_regmap_unlock, + dev->regmap_config.lock_arg = dev, + dev->regmap = regmap_init_i2c(client, &dev->regmap_config); + if (IS_ERR(dev->regmap)) { + ret = PTR_ERR(dev->regmap); + goto err_kfree; + } + dev->i2c = client->adapter; dev->i2c_address = client->addr; dev->clk_out = pdata->clk_out; @@ -462,29 +444,27 @@ static int ts2020_probe(struct i2c_client *client, dev->client = client; /* check if the tuner is there */ - ret = ts2020_readreg(fe, 0x00); - if (ret < 0) - goto err; - utmp = ret; + ret = regmap_read(dev->regmap, 0x00, &utmp); + if (ret) + goto err_regmap_exit; if ((utmp & 0x03) == 0x00) { - ret = ts2020_writereg(fe, 0x00, 0x01); + ret = regmap_write(dev->regmap, 0x00, 0x01); if (ret) - goto err; + goto err_regmap_exit; usleep_range(2000, 50000); } - ret = ts2020_writereg(fe, 0x00, 0x03); + ret = regmap_write(dev->regmap, 0x00, 0x03); if (ret) - goto err; + goto err_regmap_exit; usleep_range(2000, 50000); - ret = ts2020_readreg(fe, 0x00); - if (ret < 0) - goto err; - utmp = ret; + ret = regmap_read(dev->regmap, 0x00, &utmp); + if (ret) + goto err_regmap_exit; dev_dbg(&client->dev, "chip_id=%02x\n", utmp); @@ -506,7 +486,7 @@ static int ts2020_probe(struct i2c_client *client, break; default: ret = -ENODEV; - goto err; + goto err_regmap_exit; } if (dev->tuner == TS2020_M88TS2022) { @@ -516,36 +496,36 @@ static int ts2020_probe(struct i2c_client *client, break; case TS2020_CLK_OUT_ENABLED: u8tmp = 0x70; - ret = ts2020_writereg(fe, 0x05, dev->clk_out_div); + ret = regmap_write(dev->regmap, 0x05, dev->clk_out_div); if (ret) - goto err; + goto err_regmap_exit; break; case TS2020_CLK_OUT_ENABLED_XTALOUT: u8tmp = 0x6c; break; default: ret = -EINVAL; - goto err; + goto err_regmap_exit; } - ret = ts2020_writereg(fe, 0x42, u8tmp); + ret = regmap_write(dev->regmap, 0x42, u8tmp); if (ret) - goto err; + goto err_regmap_exit; if (dev->loop_through) u8tmp = 0xec; else u8tmp = 0x6c; - ret = ts2020_writereg(fe, 0x62, u8tmp); + ret = regmap_write(dev->regmap, 0x62, u8tmp); if (ret) - goto err; + goto err_regmap_exit; } /* sleep */ - ret = ts2020_writereg(fe, 0x00, 0x00); + ret = regmap_write(dev->regmap, 0x00, 0x00); if (ret) - goto err; + goto err_regmap_exit; dev_info(&client->dev, "Montage Technology %s successfully identified\n", chip_str); @@ -557,9 +537,12 @@ static int ts2020_probe(struct i2c_client *client, i2c_set_clientdata(client, dev); return 0; +err_regmap_exit: + regmap_exit(dev->regmap); +err_kfree: + kfree(dev); err: dev_dbg(&client->dev, "failed=%d\n", ret); - kfree(dev); return ret; } @@ -569,6 +552,7 @@ static int ts2020_remove(struct i2c_client *client) dev_dbg(&client->dev, "\n"); + regmap_exit(dev->regmap); kfree(dev); return 0; } -- cgit v1.2.3-59-g8ed1b From 80868c8e5c04bb725e411b078881b65ebbecd142 Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 2 Apr 2015 08:03:11 -0300 Subject: [media] ts2020: Add a comment about lifetime of on-stack pdata in ts2020_attach() ts2020_attach() allocates a variable pdata on the stack and then passes a pointer to it to i2c_new_device() which stashes the pointer in persistent structures. Add a comment to the effect that this isn't actually an error because the contents of the variable are only used in ts2020_probe() and this is only called ts2020_attach()'s stack frame exists. Signed-off-by: David Howells Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/ts2020.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c index 797112bbbaa8..f674717fa921 100644 --- a/drivers/media/dvb-frontends/ts2020.c +++ b/drivers/media/dvb-frontends/ts2020.c @@ -363,6 +363,8 @@ struct dvb_frontend *ts2020_attach(struct dvb_frontend *fe, { struct i2c_client *client; struct i2c_board_info board_info; + + /* This is only used by ts2020_probe() so can be on the stack */ struct ts2020_config pdata; memcpy(&pdata, config, sizeof(pdata)); -- cgit v1.2.3-59-g8ed1b From 7978b8a1bc8ae0f2aea1e4f36ef7642a1b86b9c6 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 16 Apr 2015 21:36:00 -0300 Subject: [media] m88ds3103: rename variables and correct logging Rename driver state from priv to dev. Use I2C client for correct logging. Use adapter and address from I2C client structure where needed. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/Kconfig | 2 +- drivers/media/dvb-frontends/m88ds3103.c | 538 +++++++++++++-------------- drivers/media/dvb-frontends/m88ds3103.h | 2 +- drivers/media/dvb-frontends/m88ds3103_priv.h | 5 +- 4 files changed, 267 insertions(+), 280 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index ba65a001ba25..b7627caba1e7 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -36,7 +36,7 @@ config DVB_STV6110x A Silicon tuner that supports DVB-S and DVB-S2 modes config DVB_M88DS3103 - tristate "Montage M88DS3103" + tristate "Montage Technology M88DS3103" depends on DVB_CORE && I2C && I2C_MUX default m if !MEDIA_SUBDRV_AUTOSELECT help diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index c24b15238a8e..c4acf7754a74 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -1,5 +1,5 @@ /* - * Montage M88DS3103/M88RS6000 demodulator driver + * Montage Technology M88DS3103/M88RS6000 demodulator driver * * Copyright (C) 2013 Antti Palosaari * @@ -19,16 +19,17 @@ static struct dvb_frontend_ops m88ds3103_ops; /* write multiple registers */ -static int m88ds3103_wr_regs(struct m88ds3103_priv *priv, +static int m88ds3103_wr_regs(struct m88ds3103_dev *dev, u8 reg, const u8 *val, int len) { #define MAX_WR_LEN 32 #define MAX_WR_XFER_LEN (MAX_WR_LEN + 1) + struct i2c_client *client = dev->client; int ret; u8 buf[MAX_WR_XFER_LEN]; struct i2c_msg msg[1] = { { - .addr = priv->cfg->i2c_addr, + .addr = client->addr, .flags = 0, .len = 1 + len, .buf = buf, @@ -41,15 +42,14 @@ static int m88ds3103_wr_regs(struct m88ds3103_priv *priv, buf[0] = reg; memcpy(&buf[1], val, len); - mutex_lock(&priv->i2c_mutex); - ret = i2c_transfer(priv->i2c, msg, 1); - mutex_unlock(&priv->i2c_mutex); + mutex_lock(&dev->i2c_mutex); + ret = i2c_transfer(client->adapter, msg, 1); + mutex_unlock(&dev->i2c_mutex); if (ret == 1) { ret = 0; } else { - dev_warn(&priv->i2c->dev, - "%s: i2c wr failed=%d reg=%02x len=%d\n", - KBUILD_MODNAME, ret, reg, len); + dev_warn(&client->dev, "i2c wr failed=%d reg=%02x len=%d\n", + ret, reg, len); ret = -EREMOTEIO; } @@ -57,21 +57,22 @@ static int m88ds3103_wr_regs(struct m88ds3103_priv *priv, } /* read multiple registers */ -static int m88ds3103_rd_regs(struct m88ds3103_priv *priv, +static int m88ds3103_rd_regs(struct m88ds3103_dev *dev, u8 reg, u8 *val, int len) { #define MAX_RD_LEN 3 #define MAX_RD_XFER_LEN (MAX_RD_LEN) + struct i2c_client *client = dev->client; int ret; u8 buf[MAX_RD_XFER_LEN]; struct i2c_msg msg[2] = { { - .addr = priv->cfg->i2c_addr, + .addr = client->addr, .flags = 0, .len = 1, .buf = ®, }, { - .addr = priv->cfg->i2c_addr, + .addr = client->addr, .flags = I2C_M_RD, .len = len, .buf = buf, @@ -81,16 +82,15 @@ static int m88ds3103_rd_regs(struct m88ds3103_priv *priv, if (WARN_ON(len > MAX_RD_LEN)) return -EINVAL; - mutex_lock(&priv->i2c_mutex); - ret = i2c_transfer(priv->i2c, msg, 2); - mutex_unlock(&priv->i2c_mutex); + mutex_lock(&dev->i2c_mutex); + ret = i2c_transfer(client->adapter, msg, 2); + mutex_unlock(&dev->i2c_mutex); if (ret == 2) { memcpy(val, buf, len); ret = 0; } else { - dev_warn(&priv->i2c->dev, - "%s: i2c rd failed=%d reg=%02x len=%d\n", - KBUILD_MODNAME, ret, reg, len); + dev_warn(&client->dev, "i2c rd failed=%d reg=%02x len=%d\n", + ret, reg, len); ret = -EREMOTEIO; } @@ -98,19 +98,19 @@ static int m88ds3103_rd_regs(struct m88ds3103_priv *priv, } /* write single register */ -static int m88ds3103_wr_reg(struct m88ds3103_priv *priv, u8 reg, u8 val) +static int m88ds3103_wr_reg(struct m88ds3103_dev *dev, u8 reg, u8 val) { - return m88ds3103_wr_regs(priv, reg, &val, 1); + return m88ds3103_wr_regs(dev, reg, &val, 1); } /* read single register */ -static int m88ds3103_rd_reg(struct m88ds3103_priv *priv, u8 reg, u8 *val) +static int m88ds3103_rd_reg(struct m88ds3103_dev *dev, u8 reg, u8 *val) { - return m88ds3103_rd_regs(priv, reg, val, 1); + return m88ds3103_rd_regs(dev, reg, val, 1); } /* write single register with mask */ -static int m88ds3103_wr_reg_mask(struct m88ds3103_priv *priv, +static int m88ds3103_wr_reg_mask(struct m88ds3103_dev *dev, u8 reg, u8 val, u8 mask) { int ret; @@ -118,7 +118,7 @@ static int m88ds3103_wr_reg_mask(struct m88ds3103_priv *priv, /* no need for read if whole reg is written */ if (mask != 0xff) { - ret = m88ds3103_rd_regs(priv, reg, &u8tmp, 1); + ret = m88ds3103_rd_regs(dev, reg, &u8tmp, 1); if (ret) return ret; @@ -127,17 +127,17 @@ static int m88ds3103_wr_reg_mask(struct m88ds3103_priv *priv, val |= u8tmp; } - return m88ds3103_wr_regs(priv, reg, &val, 1); + return m88ds3103_wr_regs(dev, reg, &val, 1); } /* read single register with mask */ -static int m88ds3103_rd_reg_mask(struct m88ds3103_priv *priv, +static int m88ds3103_rd_reg_mask(struct m88ds3103_dev *dev, u8 reg, u8 *val, u8 mask) { int ret, i; u8 u8tmp; - ret = m88ds3103_rd_regs(priv, reg, &u8tmp, 1); + ret = m88ds3103_rd_regs(dev, reg, &u8tmp, 1); if (ret) return ret; @@ -154,13 +154,14 @@ static int m88ds3103_rd_reg_mask(struct m88ds3103_priv *priv, } /* write reg val table using reg addr auto increment */ -static int m88ds3103_wr_reg_val_tab(struct m88ds3103_priv *priv, +static int m88ds3103_wr_reg_val_tab(struct m88ds3103_dev *dev, const struct m88ds3103_reg_val *tab, int tab_len) { + struct i2c_client *client = dev->client; int ret, i, j; u8 buf[83]; - dev_dbg(&priv->i2c->dev, "%s: tab_len=%d\n", __func__, tab_len); + dev_dbg(&client->dev, "tab_len=%d\n", tab_len); if (tab_len > 86) { ret = -EINVAL; @@ -171,8 +172,8 @@ static int m88ds3103_wr_reg_val_tab(struct m88ds3103_priv *priv, buf[j] = tab[i].val; if (i == tab_len - 1 || tab[i].reg != tab[i + 1].reg - 1 || - !((j + 1) % (priv->cfg->i2c_wr_max - 1))) { - ret = m88ds3103_wr_regs(priv, tab[i].reg - j, buf, j + 1); + !((j + 1) % (dev->cfg->i2c_wr_max - 1))) { + ret = m88ds3103_wr_regs(dev, tab[i].reg - j, buf, j + 1); if (ret) goto err; @@ -182,14 +183,15 @@ static int m88ds3103_wr_reg_val_tab(struct m88ds3103_priv *priv, return 0; err: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int m88ds3103_read_status(struct dvb_frontend *fe, enum fe_status *status) { - struct m88ds3103_priv *priv = fe->demodulator_priv; + struct m88ds3103_dev *dev = fe->demodulator_priv; + struct i2c_client *client = dev->client; struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, i, itmp; u8 u8tmp; @@ -197,14 +199,14 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, *status = 0; - if (!priv->warm) { + if (!dev->warm) { ret = -EAGAIN; goto err; } switch (c->delivery_system) { case SYS_DVBS: - ret = m88ds3103_rd_reg_mask(priv, 0xd1, &u8tmp, 0x07); + ret = m88ds3103_rd_reg_mask(dev, 0xd1, &u8tmp, 0x07); if (ret) goto err; @@ -214,7 +216,7 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, FE_HAS_LOCK; break; case SYS_DVBS2: - ret = m88ds3103_rd_reg_mask(priv, 0x0d, &u8tmp, 0x8f); + ret = m88ds3103_rd_reg_mask(dev, 0x0d, &u8tmp, 0x8f); if (ret) goto err; @@ -224,19 +226,17 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, FE_HAS_LOCK; break; default: - dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n", - __func__); + dev_dbg(&client->dev, "invalid delivery_system\n"); ret = -EINVAL; goto err; } - priv->fe_status = *status; + dev->fe_status = *status; - dev_dbg(&priv->i2c->dev, "%s: lock=%02x status=%02x\n", - __func__, u8tmp, *status); + dev_dbg(&client->dev, "lock=%02x status=%02x\n", u8tmp, *status); /* CNR */ - if (priv->fe_status & FE_HAS_VITERBI) { + if (dev->fe_status & FE_HAS_VITERBI) { unsigned int cnr, noise, signal, noise_tot, signal_tot; cnr = 0; @@ -248,7 +248,7 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, itmp = 0; for (i = 0; i < M88DS3103_SNR_ITERATIONS; i++) { - ret = m88ds3103_rd_reg(priv, 0xff, &buf[0]); + ret = m88ds3103_rd_reg(dev, 0xff, &buf[0]); if (ret) goto err; @@ -266,7 +266,7 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, signal_tot = 0; for (i = 0; i < M88DS3103_SNR_ITERATIONS; i++) { - ret = m88ds3103_rd_regs(priv, 0x8c, buf, 3); + ret = m88ds3103_rd_regs(dev, 0x8c, buf, 3); if (ret) goto err; @@ -290,8 +290,7 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, } break; default: - dev_dbg(&priv->i2c->dev, - "%s: invalid delivery_system\n", __func__); + dev_dbg(&client->dev, "invalid delivery_system\n"); ret = -EINVAL; goto err; } @@ -307,40 +306,40 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, } /* BER */ - if (priv->fe_status & FE_HAS_LOCK) { + if (dev->fe_status & FE_HAS_LOCK) { unsigned int utmp, post_bit_error, post_bit_count; switch (c->delivery_system) { case SYS_DVBS: - ret = m88ds3103_wr_reg(priv, 0xf9, 0x04); + ret = m88ds3103_wr_reg(dev, 0xf9, 0x04); if (ret) goto err; - ret = m88ds3103_rd_reg(priv, 0xf8, &u8tmp); + ret = m88ds3103_rd_reg(dev, 0xf8, &u8tmp); if (ret) goto err; /* measurement ready? */ if (!(u8tmp & 0x10)) { - ret = m88ds3103_rd_regs(priv, 0xf6, buf, 2); + ret = m88ds3103_rd_regs(dev, 0xf6, buf, 2); if (ret) goto err; post_bit_error = buf[1] << 8 | buf[0] << 0; post_bit_count = 0x800000; - priv->post_bit_error += post_bit_error; - priv->post_bit_count += post_bit_count; - priv->dvbv3_ber = post_bit_error; + dev->post_bit_error += post_bit_error; + dev->post_bit_count += post_bit_count; + dev->dvbv3_ber = post_bit_error; /* restart measurement */ u8tmp |= 0x10; - ret = m88ds3103_wr_reg(priv, 0xf8, u8tmp); + ret = m88ds3103_wr_reg(dev, 0xf8, u8tmp); if (ret) goto err; } break; case SYS_DVBS2: - ret = m88ds3103_rd_regs(priv, 0xd5, buf, 3); + ret = m88ds3103_rd_regs(dev, 0xd5, buf, 3); if (ret) goto err; @@ -348,45 +347,44 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, /* enough data? */ if (utmp > 4000) { - ret = m88ds3103_rd_regs(priv, 0xf7, buf, 2); + ret = m88ds3103_rd_regs(dev, 0xf7, buf, 2); if (ret) goto err; post_bit_error = buf[1] << 8 | buf[0] << 0; post_bit_count = 32 * utmp; /* TODO: FEC */ - priv->post_bit_error += post_bit_error; - priv->post_bit_count += post_bit_count; - priv->dvbv3_ber = post_bit_error; + dev->post_bit_error += post_bit_error; + dev->post_bit_count += post_bit_count; + dev->dvbv3_ber = post_bit_error; /* restart measurement */ - ret = m88ds3103_wr_reg(priv, 0xd1, 0x01); + ret = m88ds3103_wr_reg(dev, 0xd1, 0x01); if (ret) goto err; - ret = m88ds3103_wr_reg(priv, 0xf9, 0x01); + ret = m88ds3103_wr_reg(dev, 0xf9, 0x01); if (ret) goto err; - ret = m88ds3103_wr_reg(priv, 0xf9, 0x00); + ret = m88ds3103_wr_reg(dev, 0xf9, 0x00); if (ret) goto err; - ret = m88ds3103_wr_reg(priv, 0xd1, 0x00); + ret = m88ds3103_wr_reg(dev, 0xd1, 0x00); if (ret) goto err; } break; default: - dev_dbg(&priv->i2c->dev, - "%s: invalid delivery_system\n", __func__); + dev_dbg(&client->dev, "invalid delivery_system\n"); ret = -EINVAL; goto err; } c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; - c->post_bit_error.stat[0].uvalue = priv->post_bit_error; + c->post_bit_error.stat[0].uvalue = dev->post_bit_error; c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; - c->post_bit_count.stat[0].uvalue = priv->post_bit_count; + c->post_bit_count.stat[0].uvalue = dev->post_bit_count; } else { c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; @@ -394,13 +392,14 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, return 0; err: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int m88ds3103_set_frontend(struct dvb_frontend *fe) { - struct m88ds3103_priv *priv = fe->demodulator_priv; + struct m88ds3103_dev *dev = fe->demodulator_priv; + struct i2c_client *client = dev->client; struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, len; const struct m88ds3103_reg_val *init; @@ -410,29 +409,28 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) u32 tuner_frequency, target_mclk; s32 s32tmp; - dev_dbg(&priv->i2c->dev, - "%s: delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d pilot=%d rolloff=%d\n", - __func__, c->delivery_system, - c->modulation, c->frequency, c->symbol_rate, - c->inversion, c->pilot, c->rolloff); + dev_dbg(&client->dev, + "delivery_system=%d modulation=%d frequency=%u symbol_rate=%d inversion=%d pilot=%d rolloff=%d\n", + c->delivery_system, c->modulation, c->frequency, c->symbol_rate, + c->inversion, c->pilot, c->rolloff); - if (!priv->warm) { + if (!dev->warm) { ret = -EAGAIN; goto err; } /* reset */ - ret = m88ds3103_wr_reg(priv, 0x07, 0x80); + ret = m88ds3103_wr_reg(dev, 0x07, 0x80); if (ret) goto err; - ret = m88ds3103_wr_reg(priv, 0x07, 0x00); + ret = m88ds3103_wr_reg(dev, 0x07, 0x00); if (ret) goto err; /* Disable demod clock path */ - if (priv->chip_id == M88RS6000_CHIP_ID) { - ret = m88ds3103_wr_reg(priv, 0x06, 0xe0); + if (dev->chip_id == M88RS6000_CHIP_ID) { + ret = m88ds3103_wr_reg(dev, 0x06, 0xe0); if (ret) goto err; } @@ -458,11 +456,11 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) } /* select M88RS6000 demod main mclk and ts mclk from tuner die. */ - if (priv->chip_id == M88RS6000_CHIP_ID) { + if (dev->chip_id == M88RS6000_CHIP_ID) { if (c->symbol_rate > 45010000) - priv->mclk_khz = 110250; + dev->mclk_khz = 110250; else - priv->mclk_khz = 96000; + dev->mclk_khz = 96000; if (c->delivery_system == SYS_DVBS) target_mclk = 96000; @@ -470,18 +468,18 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) target_mclk = 144000; /* Enable demod clock path */ - ret = m88ds3103_wr_reg(priv, 0x06, 0x00); + ret = m88ds3103_wr_reg(dev, 0x06, 0x00); if (ret) goto err; usleep_range(10000, 20000); } else { /* set M88DS3103 mclk and ts mclk. */ - priv->mclk_khz = 96000; + dev->mclk_khz = 96000; - switch (priv->cfg->ts_mode) { + switch (dev->cfg->ts_mode) { case M88DS3103_TS_SERIAL: case M88DS3103_TS_SERIAL_D7: - target_mclk = priv->cfg->ts_clk; + target_mclk = dev->cfg->ts_clk; break; case M88DS3103_TS_PARALLEL: case M88DS3103_TS_CI: @@ -497,8 +495,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) } break; default: - dev_dbg(&priv->i2c->dev, "%s: invalid ts_mode\n", - __func__); + dev_dbg(&client->dev, "invalid ts_mode\n"); ret = -EINVAL; goto err; } @@ -517,25 +514,25 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) u8tmp2 = 0x00; /* 0b00 */ break; } - ret = m88ds3103_wr_reg_mask(priv, 0x22, u8tmp1 << 6, 0xc0); + ret = m88ds3103_wr_reg_mask(dev, 0x22, u8tmp1 << 6, 0xc0); if (ret) goto err; - ret = m88ds3103_wr_reg_mask(priv, 0x24, u8tmp2 << 6, 0xc0); + ret = m88ds3103_wr_reg_mask(dev, 0x24, u8tmp2 << 6, 0xc0); if (ret) goto err; } - ret = m88ds3103_wr_reg(priv, 0xb2, 0x01); + ret = m88ds3103_wr_reg(dev, 0xb2, 0x01); if (ret) goto err; - ret = m88ds3103_wr_reg(priv, 0x00, 0x01); + ret = m88ds3103_wr_reg(dev, 0x00, 0x01); if (ret) goto err; switch (c->delivery_system) { case SYS_DVBS: - if (priv->chip_id == M88RS6000_CHIP_ID) { + if (dev->chip_id == M88RS6000_CHIP_ID) { len = ARRAY_SIZE(m88rs6000_dvbs_init_reg_vals); init = m88rs6000_dvbs_init_reg_vals; } else { @@ -544,7 +541,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) } break; case SYS_DVBS2: - if (priv->chip_id == M88RS6000_CHIP_ID) { + if (dev->chip_id == M88RS6000_CHIP_ID) { len = ARRAY_SIZE(m88rs6000_dvbs2_init_reg_vals); init = m88rs6000_dvbs2_init_reg_vals; } else { @@ -553,44 +550,43 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) } break; default: - dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n", - __func__); + dev_dbg(&client->dev, "invalid delivery_system\n"); ret = -EINVAL; goto err; } /* program init table */ - if (c->delivery_system != priv->delivery_system) { - ret = m88ds3103_wr_reg_val_tab(priv, init, len); + if (c->delivery_system != dev->delivery_system) { + ret = m88ds3103_wr_reg_val_tab(dev, init, len); if (ret) goto err; } - if (priv->chip_id == M88RS6000_CHIP_ID) { + if (dev->chip_id == M88RS6000_CHIP_ID) { if ((c->delivery_system == SYS_DVBS2) && ((c->symbol_rate / 1000) <= 5000)) { - ret = m88ds3103_wr_reg(priv, 0xc0, 0x04); + ret = m88ds3103_wr_reg(dev, 0xc0, 0x04); if (ret) goto err; buf[0] = 0x09; buf[1] = 0x22; buf[2] = 0x88; - ret = m88ds3103_wr_regs(priv, 0x8a, buf, 3); + ret = m88ds3103_wr_regs(dev, 0x8a, buf, 3); if (ret) goto err; } - ret = m88ds3103_wr_reg_mask(priv, 0x9d, 0x08, 0x08); + ret = m88ds3103_wr_reg_mask(dev, 0x9d, 0x08, 0x08); if (ret) goto err; - ret = m88ds3103_wr_reg(priv, 0xf1, 0x01); + ret = m88ds3103_wr_reg(dev, 0xf1, 0x01); if (ret) goto err; - ret = m88ds3103_wr_reg_mask(priv, 0x30, 0x80, 0x80); + ret = m88ds3103_wr_reg_mask(dev, 0x30, 0x80, 0x80); if (ret) goto err; } - switch (priv->cfg->ts_mode) { + switch (dev->cfg->ts_mode) { case M88DS3103_TS_SERIAL: u8tmp1 = 0x00; u8tmp = 0x06; @@ -606,39 +602,39 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) u8tmp = 0x03; break; default: - dev_dbg(&priv->i2c->dev, "%s: invalid ts_mode\n", __func__); + dev_dbg(&client->dev, "invalid ts_mode\n"); ret = -EINVAL; goto err; } - if (priv->cfg->ts_clk_pol) + if (dev->cfg->ts_clk_pol) u8tmp |= 0x40; /* TS mode */ - ret = m88ds3103_wr_reg(priv, 0xfd, u8tmp); + ret = m88ds3103_wr_reg(dev, 0xfd, u8tmp); if (ret) goto err; - switch (priv->cfg->ts_mode) { + switch (dev->cfg->ts_mode) { case M88DS3103_TS_SERIAL: case M88DS3103_TS_SERIAL_D7: - ret = m88ds3103_wr_reg_mask(priv, 0x29, u8tmp1, 0x20); + ret = m88ds3103_wr_reg_mask(dev, 0x29, u8tmp1, 0x20); if (ret) goto err; u8tmp1 = 0; u8tmp2 = 0; break; default: - if (priv->cfg->ts_clk) { - divide_ratio = DIV_ROUND_UP(target_mclk, priv->cfg->ts_clk); + if (dev->cfg->ts_clk) { + divide_ratio = DIV_ROUND_UP(target_mclk, dev->cfg->ts_clk); u8tmp1 = divide_ratio / 2; u8tmp2 = DIV_ROUND_UP(divide_ratio, 2); } } - dev_dbg(&priv->i2c->dev, - "%s: target_mclk=%d ts_clk=%d divide_ratio=%d\n", - __func__, target_mclk, priv->cfg->ts_clk, divide_ratio); + dev_dbg(&client->dev, + "target_mclk=%d ts_clk=%d divide_ratio=%d\n", + target_mclk, dev->cfg->ts_clk, divide_ratio); u8tmp1--; u8tmp2--; @@ -647,17 +643,17 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) /* u8tmp2[5:0] => ea[5:0] */ u8tmp2 &= 0x3f; - ret = m88ds3103_rd_reg(priv, 0xfe, &u8tmp); + ret = m88ds3103_rd_reg(dev, 0xfe, &u8tmp); if (ret) goto err; u8tmp = ((u8tmp & 0xf0) << 0) | u8tmp1 >> 2; - ret = m88ds3103_wr_reg(priv, 0xfe, u8tmp); + ret = m88ds3103_wr_reg(dev, 0xfe, u8tmp); if (ret) goto err; u8tmp = ((u8tmp1 & 0x03) << 6) | u8tmp2 >> 0; - ret = m88ds3103_wr_reg(priv, 0xea, u8tmp); + ret = m88ds3103_wr_reg(dev, 0xea, u8tmp); if (ret) goto err; @@ -668,182 +664,181 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) else u8tmp = 0x06; - ret = m88ds3103_wr_reg(priv, 0xc3, 0x08); + ret = m88ds3103_wr_reg(dev, 0xc3, 0x08); if (ret) goto err; - ret = m88ds3103_wr_reg(priv, 0xc8, u8tmp); + ret = m88ds3103_wr_reg(dev, 0xc8, u8tmp); if (ret) goto err; - ret = m88ds3103_wr_reg(priv, 0xc4, 0x08); + ret = m88ds3103_wr_reg(dev, 0xc4, 0x08); if (ret) goto err; - ret = m88ds3103_wr_reg(priv, 0xc7, 0x00); + ret = m88ds3103_wr_reg(dev, 0xc7, 0x00); if (ret) goto err; - u16tmp = DIV_ROUND_CLOSEST((c->symbol_rate / 1000) << 15, priv->mclk_khz / 2); + u16tmp = DIV_ROUND_CLOSEST((c->symbol_rate / 1000) << 15, dev->mclk_khz / 2); buf[0] = (u16tmp >> 0) & 0xff; buf[1] = (u16tmp >> 8) & 0xff; - ret = m88ds3103_wr_regs(priv, 0x61, buf, 2); + ret = m88ds3103_wr_regs(dev, 0x61, buf, 2); if (ret) goto err; - ret = m88ds3103_wr_reg_mask(priv, 0x4d, priv->cfg->spec_inv << 1, 0x02); + ret = m88ds3103_wr_reg_mask(dev, 0x4d, dev->cfg->spec_inv << 1, 0x02); if (ret) goto err; - ret = m88ds3103_wr_reg_mask(priv, 0x30, priv->cfg->agc_inv << 4, 0x10); + ret = m88ds3103_wr_reg_mask(dev, 0x30, dev->cfg->agc_inv << 4, 0x10); if (ret) goto err; - ret = m88ds3103_wr_reg(priv, 0x33, priv->cfg->agc); + ret = m88ds3103_wr_reg(dev, 0x33, dev->cfg->agc); if (ret) goto err; - dev_dbg(&priv->i2c->dev, "%s: carrier offset=%d\n", __func__, - (tuner_frequency - c->frequency)); + dev_dbg(&client->dev, "carrier offset=%d\n", + (tuner_frequency - c->frequency)); s32tmp = 0x10000 * (tuner_frequency - c->frequency); - s32tmp = DIV_ROUND_CLOSEST(s32tmp, priv->mclk_khz); + s32tmp = DIV_ROUND_CLOSEST(s32tmp, dev->mclk_khz); if (s32tmp < 0) s32tmp += 0x10000; buf[0] = (s32tmp >> 0) & 0xff; buf[1] = (s32tmp >> 8) & 0xff; - ret = m88ds3103_wr_regs(priv, 0x5e, buf, 2); + ret = m88ds3103_wr_regs(dev, 0x5e, buf, 2); if (ret) goto err; - ret = m88ds3103_wr_reg(priv, 0x00, 0x00); + ret = m88ds3103_wr_reg(dev, 0x00, 0x00); if (ret) goto err; - ret = m88ds3103_wr_reg(priv, 0xb2, 0x00); + ret = m88ds3103_wr_reg(dev, 0xb2, 0x00); if (ret) goto err; - priv->delivery_system = c->delivery_system; + dev->delivery_system = c->delivery_system; return 0; err: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int m88ds3103_init(struct dvb_frontend *fe) { - struct m88ds3103_priv *priv = fe->demodulator_priv; + struct m88ds3103_dev *dev = fe->demodulator_priv; + struct i2c_client *client = dev->client; struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, len, remaining; const struct firmware *fw = NULL; u8 *fw_file; u8 u8tmp; - dev_dbg(&priv->i2c->dev, "%s:\n", __func__); + dev_dbg(&client->dev, "\n"); /* set cold state by default */ - priv->warm = false; + dev->warm = false; /* wake up device from sleep */ - ret = m88ds3103_wr_reg_mask(priv, 0x08, 0x01, 0x01); + ret = m88ds3103_wr_reg_mask(dev, 0x08, 0x01, 0x01); if (ret) goto err; - ret = m88ds3103_wr_reg_mask(priv, 0x04, 0x00, 0x01); + ret = m88ds3103_wr_reg_mask(dev, 0x04, 0x00, 0x01); if (ret) goto err; - ret = m88ds3103_wr_reg_mask(priv, 0x23, 0x00, 0x10); + ret = m88ds3103_wr_reg_mask(dev, 0x23, 0x00, 0x10); if (ret) goto err; /* firmware status */ - ret = m88ds3103_rd_reg(priv, 0xb9, &u8tmp); + ret = m88ds3103_rd_reg(dev, 0xb9, &u8tmp); if (ret) goto err; - dev_dbg(&priv->i2c->dev, "%s: firmware=%02x\n", __func__, u8tmp); + dev_dbg(&client->dev, "firmware=%02x\n", u8tmp); if (u8tmp) goto skip_fw_download; /* global reset, global diseqc reset, golbal fec reset */ - ret = m88ds3103_wr_reg(priv, 0x07, 0xe0); + ret = m88ds3103_wr_reg(dev, 0x07, 0xe0); if (ret) goto err; - ret = m88ds3103_wr_reg(priv, 0x07, 0x00); + ret = m88ds3103_wr_reg(dev, 0x07, 0x00); if (ret) goto err; /* cold state - try to download firmware */ - dev_info(&priv->i2c->dev, "%s: found a '%s' in cold state\n", - KBUILD_MODNAME, m88ds3103_ops.info.name); + dev_info(&client->dev, "found a '%s' in cold state\n", + m88ds3103_ops.info.name); - if (priv->chip_id == M88RS6000_CHIP_ID) + if (dev->chip_id == M88RS6000_CHIP_ID) fw_file = M88RS6000_FIRMWARE; else fw_file = M88DS3103_FIRMWARE; /* request the firmware, this will block and timeout */ - ret = request_firmware(&fw, fw_file, priv->i2c->dev.parent); + ret = request_firmware(&fw, fw_file, &client->dev); if (ret) { - dev_err(&priv->i2c->dev, "%s: firmware file '%s' not found\n", - KBUILD_MODNAME, fw_file); + dev_err(&client->dev, "firmare file '%s' not found\n", fw_file); goto err; } - dev_info(&priv->i2c->dev, "%s: downloading firmware from file '%s'\n", - KBUILD_MODNAME, fw_file); + dev_info(&client->dev, "downloading firmware from file '%s'\n", + fw_file); - ret = m88ds3103_wr_reg(priv, 0xb2, 0x01); + ret = m88ds3103_wr_reg(dev, 0xb2, 0x01); if (ret) goto error_fw_release; for (remaining = fw->size; remaining > 0; - remaining -= (priv->cfg->i2c_wr_max - 1)) { + remaining -= (dev->cfg->i2c_wr_max - 1)) { len = remaining; - if (len > (priv->cfg->i2c_wr_max - 1)) - len = (priv->cfg->i2c_wr_max - 1); + if (len > (dev->cfg->i2c_wr_max - 1)) + len = (dev->cfg->i2c_wr_max - 1); - ret = m88ds3103_wr_regs(priv, 0xb0, + ret = m88ds3103_wr_regs(dev, 0xb0, &fw->data[fw->size - remaining], len); if (ret) { - dev_err(&priv->i2c->dev, - "%s: firmware download failed=%d\n", - KBUILD_MODNAME, ret); + dev_err(&client->dev, "firmware download failed=%d\n", + ret); goto error_fw_release; } } - ret = m88ds3103_wr_reg(priv, 0xb2, 0x00); + ret = m88ds3103_wr_reg(dev, 0xb2, 0x00); if (ret) goto error_fw_release; release_firmware(fw); fw = NULL; - ret = m88ds3103_rd_reg(priv, 0xb9, &u8tmp); + ret = m88ds3103_rd_reg(dev, 0xb9, &u8tmp); if (ret) goto err; if (!u8tmp) { - dev_info(&priv->i2c->dev, "%s: firmware did not run\n", - KBUILD_MODNAME); + dev_info(&client->dev, "firmware did not run\n"); ret = -EFAULT; goto err; } - dev_info(&priv->i2c->dev, "%s: found a '%s' in warm state\n", - KBUILD_MODNAME, m88ds3103_ops.info.name); - dev_info(&priv->i2c->dev, "%s: firmware version %X.%X\n", - KBUILD_MODNAME, (u8tmp >> 4) & 0xf, (u8tmp >> 0 & 0xf)); + dev_info(&client->dev, "found a '%s' in warm state\n", + m88ds3103_ops.info.name); + dev_info(&client->dev, "firmware version: %X.%X\n", + (u8tmp >> 4) & 0xf, (u8tmp >> 0 & 0xf)); skip_fw_download: /* warm state */ - priv->warm = true; + dev->warm = true; + /* init stats here in order signal app which stats are supported */ c->cnr.len = 1; c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; @@ -851,75 +846,77 @@ skip_fw_download: c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; c->post_bit_count.len = 1; c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; - return 0; + return 0; error_fw_release: release_firmware(fw); err: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int m88ds3103_sleep(struct dvb_frontend *fe) { - struct m88ds3103_priv *priv = fe->demodulator_priv; + struct m88ds3103_dev *dev = fe->demodulator_priv; + struct i2c_client *client = dev->client; int ret; u8 u8tmp; - dev_dbg(&priv->i2c->dev, "%s:\n", __func__); + dev_dbg(&client->dev, "\n"); - priv->fe_status = 0; - priv->delivery_system = SYS_UNDEFINED; + dev->fe_status = 0; + dev->delivery_system = SYS_UNDEFINED; /* TS Hi-Z */ - if (priv->chip_id == M88RS6000_CHIP_ID) + if (dev->chip_id == M88RS6000_CHIP_ID) u8tmp = 0x29; else u8tmp = 0x27; - ret = m88ds3103_wr_reg_mask(priv, u8tmp, 0x00, 0x01); + ret = m88ds3103_wr_reg_mask(dev, u8tmp, 0x00, 0x01); if (ret) goto err; /* sleep */ - ret = m88ds3103_wr_reg_mask(priv, 0x08, 0x00, 0x01); + ret = m88ds3103_wr_reg_mask(dev, 0x08, 0x00, 0x01); if (ret) goto err; - ret = m88ds3103_wr_reg_mask(priv, 0x04, 0x01, 0x01); + ret = m88ds3103_wr_reg_mask(dev, 0x04, 0x01, 0x01); if (ret) goto err; - ret = m88ds3103_wr_reg_mask(priv, 0x23, 0x10, 0x10); + ret = m88ds3103_wr_reg_mask(dev, 0x23, 0x10, 0x10); if (ret) goto err; return 0; err: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int m88ds3103_get_frontend(struct dvb_frontend *fe) { - struct m88ds3103_priv *priv = fe->demodulator_priv; + struct m88ds3103_dev *dev = fe->demodulator_priv; + struct i2c_client *client = dev->client; struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret; u8 buf[3]; - dev_dbg(&priv->i2c->dev, "%s:\n", __func__); + dev_dbg(&client->dev, "\n"); - if (!priv->warm || !(priv->fe_status & FE_HAS_LOCK)) { + if (!dev->warm || !(dev->fe_status & FE_HAS_LOCK)) { ret = 0; goto err; } switch (c->delivery_system) { case SYS_DVBS: - ret = m88ds3103_rd_reg(priv, 0xe0, &buf[0]); + ret = m88ds3103_rd_reg(dev, 0xe0, &buf[0]); if (ret) goto err; - ret = m88ds3103_rd_reg(priv, 0xe6, &buf[1]); + ret = m88ds3103_rd_reg(dev, 0xe6, &buf[1]); if (ret) goto err; @@ -949,23 +946,22 @@ static int m88ds3103_get_frontend(struct dvb_frontend *fe) c->fec_inner = FEC_1_2; break; default: - dev_dbg(&priv->i2c->dev, "%s: invalid fec_inner\n", - __func__); + dev_dbg(&client->dev, "invalid fec_inner\n"); } c->modulation = QPSK; break; case SYS_DVBS2: - ret = m88ds3103_rd_reg(priv, 0x7e, &buf[0]); + ret = m88ds3103_rd_reg(dev, 0x7e, &buf[0]); if (ret) goto err; - ret = m88ds3103_rd_reg(priv, 0x89, &buf[1]); + ret = m88ds3103_rd_reg(dev, 0x89, &buf[1]); if (ret) goto err; - ret = m88ds3103_rd_reg(priv, 0xf2, &buf[2]); + ret = m88ds3103_rd_reg(dev, 0xf2, &buf[2]); if (ret) goto err; @@ -998,8 +994,7 @@ static int m88ds3103_get_frontend(struct dvb_frontend *fe) c->fec_inner = FEC_9_10; break; default: - dev_dbg(&priv->i2c->dev, "%s: invalid fec_inner\n", - __func__); + dev_dbg(&client->dev, "invalid fec_inner\n"); } switch ((buf[0] >> 5) & 0x01) { @@ -1025,8 +1020,7 @@ static int m88ds3103_get_frontend(struct dvb_frontend *fe) c->modulation = APSK_32; break; default: - dev_dbg(&priv->i2c->dev, "%s: invalid modulation\n", - __func__); + dev_dbg(&client->dev, "invalid modulation\n"); } switch ((buf[1] >> 7) & 0x01) { @@ -1049,27 +1043,25 @@ static int m88ds3103_get_frontend(struct dvb_frontend *fe) c->rolloff = ROLLOFF_20; break; default: - dev_dbg(&priv->i2c->dev, "%s: invalid rolloff\n", - __func__); + dev_dbg(&client->dev, "invalid rolloff\n"); } break; default: - dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n", - __func__); + dev_dbg(&client->dev, "invalid delivery_system\n"); ret = -EINVAL; goto err; } - ret = m88ds3103_rd_regs(priv, 0x6d, buf, 2); + ret = m88ds3103_rd_regs(dev, 0x6d, buf, 2); if (ret) goto err; c->symbol_rate = 1ull * ((buf[1] << 8) | (buf[0] << 0)) * - priv->mclk_khz * 1000 / 0x10000; + dev->mclk_khz * 1000 / 0x10000; return 0; err: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } @@ -1087,9 +1079,9 @@ static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *snr) static int m88ds3103_read_ber(struct dvb_frontend *fe, u32 *ber) { - struct m88ds3103_priv *priv = fe->demodulator_priv; + struct m88ds3103_dev *dev = fe->demodulator_priv; - *ber = priv->dvbv3_ber; + *ber = dev->dvbv3_ber; return 0; } @@ -1097,14 +1089,14 @@ static int m88ds3103_read_ber(struct dvb_frontend *fe, u32 *ber) static int m88ds3103_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode fe_sec_tone_mode) { - struct m88ds3103_priv *priv = fe->demodulator_priv; + struct m88ds3103_dev *dev = fe->demodulator_priv; + struct i2c_client *client = dev->client; int ret; u8 u8tmp, tone, reg_a1_mask; - dev_dbg(&priv->i2c->dev, "%s: fe_sec_tone_mode=%d\n", __func__, - fe_sec_tone_mode); + dev_dbg(&client->dev, "fe_sec_tone_mode=%d\n", fe_sec_tone_mode); - if (!priv->warm) { + if (!dev->warm) { ret = -EAGAIN; goto err; } @@ -1119,40 +1111,39 @@ static int m88ds3103_set_tone(struct dvb_frontend *fe, reg_a1_mask = 0x00; break; default: - dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_tone_mode\n", - __func__); + dev_dbg(&client->dev, "invalid fe_sec_tone_mode\n"); ret = -EINVAL; goto err; } - u8tmp = tone << 7 | priv->cfg->envelope_mode << 5; - ret = m88ds3103_wr_reg_mask(priv, 0xa2, u8tmp, 0xe0); + u8tmp = tone << 7 | dev->cfg->envelope_mode << 5; + ret = m88ds3103_wr_reg_mask(dev, 0xa2, u8tmp, 0xe0); if (ret) goto err; u8tmp = 1 << 2; - ret = m88ds3103_wr_reg_mask(priv, 0xa1, u8tmp, reg_a1_mask); + ret = m88ds3103_wr_reg_mask(dev, 0xa1, u8tmp, reg_a1_mask); if (ret) goto err; return 0; err: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int m88ds3103_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage fe_sec_voltage) { - struct m88ds3103_priv *priv = fe->demodulator_priv; + struct m88ds3103_dev *dev = fe->demodulator_priv; + struct i2c_client *client = dev->client; int ret; u8 u8tmp; bool voltage_sel, voltage_dis; - dev_dbg(&priv->i2c->dev, "%s: fe_sec_voltage=%d\n", __func__, - fe_sec_voltage); + dev_dbg(&client->dev, "fe_sec_voltage=%d\n", fe_sec_voltage); - if (!priv->warm) { + if (!dev->warm) { ret = -EAGAIN; goto err; } @@ -1171,39 +1162,39 @@ static int m88ds3103_set_voltage(struct dvb_frontend *fe, voltage_dis = true; break; default: - dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_voltage\n", - __func__); + dev_dbg(&client->dev, "invalid fe_sec_voltage\n"); ret = -EINVAL; goto err; } /* output pin polarity */ - voltage_sel ^= priv->cfg->lnb_hv_pol; - voltage_dis ^= priv->cfg->lnb_en_pol; + voltage_sel ^= dev->cfg->lnb_hv_pol; + voltage_dis ^= dev->cfg->lnb_en_pol; u8tmp = voltage_dis << 1 | voltage_sel << 0; - ret = m88ds3103_wr_reg_mask(priv, 0xa2, u8tmp, 0x03); + ret = m88ds3103_wr_reg_mask(dev, 0xa2, u8tmp, 0x03); if (ret) goto err; return 0; err: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *diseqc_cmd) { - struct m88ds3103_priv *priv = fe->demodulator_priv; + struct m88ds3103_dev *dev = fe->demodulator_priv; + struct i2c_client *client = dev->client; int ret; unsigned long timeout; u8 u8tmp; - dev_dbg(&priv->i2c->dev, "%s: msg=%*ph\n", __func__, - diseqc_cmd->msg_len, diseqc_cmd->msg); + dev_dbg(&client->dev, "msg=%*ph\n", + diseqc_cmd->msg_len, diseqc_cmd->msg); - if (!priv->warm) { + if (!dev->warm) { ret = -EAGAIN; goto err; } @@ -1213,17 +1204,17 @@ static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe, goto err; } - u8tmp = priv->cfg->envelope_mode << 5; - ret = m88ds3103_wr_reg_mask(priv, 0xa2, u8tmp, 0xe0); + u8tmp = dev->cfg->envelope_mode << 5; + ret = m88ds3103_wr_reg_mask(dev, 0xa2, u8tmp, 0xe0); if (ret) goto err; - ret = m88ds3103_wr_regs(priv, 0xa3, diseqc_cmd->msg, + ret = m88ds3103_wr_regs(dev, 0xa3, diseqc_cmd->msg, diseqc_cmd->msg_len); if (ret) goto err; - ret = m88ds3103_wr_reg(priv, 0xa1, + ret = m88ds3103_wr_reg(dev, 0xa1, (diseqc_cmd->msg_len - 1) << 3 | 0x07); if (ret) goto err; @@ -1236,24 +1227,24 @@ static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe, usleep_range(50000, 54000); for (u8tmp = 1; !time_after(jiffies, timeout) && u8tmp;) { - ret = m88ds3103_rd_reg_mask(priv, 0xa1, &u8tmp, 0x40); + ret = m88ds3103_rd_reg_mask(dev, 0xa1, &u8tmp, 0x40); if (ret) goto err; } if (u8tmp == 0) { - dev_dbg(&priv->i2c->dev, "%s: diseqc tx took %u ms\n", __func__, + dev_dbg(&client->dev, "diseqc tx took %u ms\n", jiffies_to_msecs(jiffies) - (jiffies_to_msecs(timeout) - SEND_MASTER_CMD_TIMEOUT)); } else { - dev_dbg(&priv->i2c->dev, "%s: diseqc tx timeout\n", __func__); + dev_dbg(&client->dev, "diseqc tx timeout\n"); - ret = m88ds3103_wr_reg_mask(priv, 0xa1, 0x40, 0xc0); + ret = m88ds3103_wr_reg_mask(dev, 0xa1, 0x40, 0xc0); if (ret) goto err; } - ret = m88ds3103_wr_reg_mask(priv, 0xa2, 0x80, 0xc0); + ret = m88ds3103_wr_reg_mask(dev, 0xa2, 0x80, 0xc0); if (ret) goto err; @@ -1264,28 +1255,28 @@ static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe, return 0; err: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe, enum fe_sec_mini_cmd fe_sec_mini_cmd) { - struct m88ds3103_priv *priv = fe->demodulator_priv; + struct m88ds3103_dev *dev = fe->demodulator_priv; + struct i2c_client *client = dev->client; int ret; unsigned long timeout; u8 u8tmp, burst; - dev_dbg(&priv->i2c->dev, "%s: fe_sec_mini_cmd=%d\n", __func__, - fe_sec_mini_cmd); + dev_dbg(&client->dev, "fe_sec_mini_cmd=%d\n", fe_sec_mini_cmd); - if (!priv->warm) { + if (!dev->warm) { ret = -EAGAIN; goto err; } - u8tmp = priv->cfg->envelope_mode << 5; - ret = m88ds3103_wr_reg_mask(priv, 0xa2, u8tmp, 0xe0); + u8tmp = dev->cfg->envelope_mode << 5; + ret = m88ds3103_wr_reg_mask(dev, 0xa2, u8tmp, 0xe0); if (ret) goto err; @@ -1297,13 +1288,12 @@ static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe, burst = 0x01; break; default: - dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_mini_cmd\n", - __func__); + dev_dbg(&client->dev, "invalid fe_sec_mini_cmd\n"); ret = -EINVAL; goto err; } - ret = m88ds3103_wr_reg(priv, 0xa1, burst); + ret = m88ds3103_wr_reg(dev, 0xa1, burst); if (ret) goto err; @@ -1315,24 +1305,24 @@ static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe, usleep_range(8500, 12500); for (u8tmp = 1; !time_after(jiffies, timeout) && u8tmp;) { - ret = m88ds3103_rd_reg_mask(priv, 0xa1, &u8tmp, 0x40); + ret = m88ds3103_rd_reg_mask(dev, 0xa1, &u8tmp, 0x40); if (ret) goto err; } if (u8tmp == 0) { - dev_dbg(&priv->i2c->dev, "%s: diseqc tx took %u ms\n", __func__, + dev_dbg(&client->dev, "diseqc tx took %u ms\n", jiffies_to_msecs(jiffies) - (jiffies_to_msecs(timeout) - SEND_BURST_TIMEOUT)); } else { - dev_dbg(&priv->i2c->dev, "%s: diseqc tx timeout\n", __func__); + dev_dbg(&client->dev, "diseqc tx timeout\n"); - ret = m88ds3103_wr_reg_mask(priv, 0xa1, 0x40, 0xc0); + ret = m88ds3103_wr_reg_mask(dev, 0xa1, 0x40, 0xc0); if (ret) goto err; } - ret = m88ds3103_wr_reg_mask(priv, 0xa2, 0x80, 0xc0); + ret = m88ds3103_wr_reg_mask(dev, 0xa2, 0x80, 0xc0); if (ret) goto err; @@ -1343,7 +1333,7 @@ static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe, return 0; err: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } @@ -1357,32 +1347,32 @@ static int m88ds3103_get_tune_settings(struct dvb_frontend *fe, static void m88ds3103_release(struct dvb_frontend *fe) { - struct m88ds3103_priv *priv = fe->demodulator_priv; - struct i2c_client *client = priv->client; + struct m88ds3103_dev *dev = fe->demodulator_priv; + struct i2c_client *client = dev->client; i2c_unregister_device(client); } static int m88ds3103_select(struct i2c_adapter *adap, void *mux_priv, u32 chan) { - struct m88ds3103_priv *priv = mux_priv; + struct m88ds3103_dev *dev = mux_priv; + struct i2c_client *client = dev->client; int ret; struct i2c_msg gate_open_msg[1] = { { - .addr = priv->cfg->i2c_addr, + .addr = client->addr, .flags = 0, .len = 2, .buf = "\x03\x11", } }; - mutex_lock(&priv->i2c_mutex); + mutex_lock(&dev->i2c_mutex); /* open tuner I2C repeater for 1 xfer, closes automatically */ - ret = __i2c_transfer(priv->i2c, gate_open_msg, 1); + ret = __i2c_transfer(client->adapter, gate_open_msg, 1); if (ret != 1) { - dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d\n", - KBUILD_MODNAME, ret); + dev_warn(&client->dev, "i2c wr failed=%d\n", ret); if (ret >= 0) ret = -EREMOTEIO; @@ -1395,9 +1385,9 @@ static int m88ds3103_select(struct i2c_adapter *adap, void *mux_priv, u32 chan) static int m88ds3103_deselect(struct i2c_adapter *adap, void *mux_priv, u32 chan) { - struct m88ds3103_priv *priv = mux_priv; + struct m88ds3103_dev *dev = mux_priv; - mutex_unlock(&priv->i2c_mutex); + mutex_unlock(&dev->i2c_mutex); return 0; } @@ -1442,9 +1432,9 @@ struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg, EXPORT_SYMBOL(m88ds3103_attach); static struct dvb_frontend_ops m88ds3103_ops = { - .delsys = { SYS_DVBS, SYS_DVBS2 }, + .delsys = {SYS_DVBS, SYS_DVBS2}, .info = { - .name = "Montage M88DS3103", + .name = "Montage Technology M88DS3103", .frequency_min = 950000, .frequency_max = 2150000, .frequency_tolerance = 5000, @@ -1488,7 +1478,7 @@ static struct dvb_frontend_ops m88ds3103_ops = { static struct dvb_frontend *m88ds3103_get_dvb_frontend(struct i2c_client *client) { - struct m88ds3103_priv *dev = i2c_get_clientdata(client); + struct m88ds3103_dev *dev = i2c_get_clientdata(client); dev_dbg(&client->dev, "\n"); @@ -1497,7 +1487,7 @@ static struct dvb_frontend *m88ds3103_get_dvb_frontend(struct i2c_client *client static struct i2c_adapter *m88ds3103_get_i2c_adapter(struct i2c_client *client) { - struct m88ds3103_priv *dev = i2c_get_clientdata(client); + struct m88ds3103_dev *dev = i2c_get_clientdata(client); dev_dbg(&client->dev, "\n"); @@ -1507,7 +1497,7 @@ static struct i2c_adapter *m88ds3103_get_i2c_adapter(struct i2c_client *client) static int m88ds3103_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct m88ds3103_priv *dev; + struct m88ds3103_dev *dev; struct m88ds3103_platform_data *pdata = client->dev.platform_data; int ret; u8 chip_id, u8tmp; @@ -1519,8 +1509,6 @@ static int m88ds3103_probe(struct i2c_client *client, } dev->client = client; - dev->i2c = client->adapter; - dev->config.i2c_addr = client->addr; dev->config.clock = pdata->clk; dev->config.i2c_wr_max = pdata->i2c_wr_max; dev->config.ts_mode = pdata->ts_mode; @@ -1600,8 +1588,8 @@ static int m88ds3103_probe(struct i2c_client *client, /* create dvb_frontend */ memcpy(&dev->fe.ops, &m88ds3103_ops, sizeof(struct dvb_frontend_ops)); if (dev->chip_id == M88RS6000_CHIP_ID) - strncpy(dev->fe.ops.info.name, - "Montage M88RS6000", sizeof(dev->fe.ops.info.name)); + strncpy(dev->fe.ops.info.name, "Montage Technology M88RS6000", + sizeof(dev->fe.ops.info.name)); if (!pdata->attach_in_use) dev->fe.ops.release = NULL; dev->fe.demodulator_priv = dev; @@ -1620,7 +1608,7 @@ err: static int m88ds3103_remove(struct i2c_client *client) { - struct m88ds3103_priv *dev = i2c_get_clientdata(client); + struct m88ds3103_dev *dev = i2c_get_clientdata(client); dev_dbg(&client->dev, "\n"); @@ -1650,7 +1638,7 @@ static struct i2c_driver m88ds3103_driver = { module_i2c_driver(m88ds3103_driver); MODULE_AUTHOR("Antti Palosaari "); -MODULE_DESCRIPTION("Montage M88DS3103 DVB-S/S2 demodulator driver"); +MODULE_DESCRIPTION("Montage Technology M88DS3103 DVB-S/S2 demodulator driver"); MODULE_LICENSE("GPL"); MODULE_FIRMWARE(M88DS3103_FIRMWARE); MODULE_FIRMWARE(M88RS6000_FIRMWARE); diff --git a/drivers/media/dvb-frontends/m88ds3103.h b/drivers/media/dvb-frontends/m88ds3103.h index 381146840c51..ff0390593049 100644 --- a/drivers/media/dvb-frontends/m88ds3103.h +++ b/drivers/media/dvb-frontends/m88ds3103.h @@ -1,5 +1,5 @@ /* - * Montage M88DS3103 demodulator driver + * Montage Technology M88DS3103/M88RS6000 demodulator driver * * Copyright (C) 2013 Antti Palosaari * diff --git a/drivers/media/dvb-frontends/m88ds3103_priv.h b/drivers/media/dvb-frontends/m88ds3103_priv.h index 9d7d33430e40..35c7f3eced26 100644 --- a/drivers/media/dvb-frontends/m88ds3103_priv.h +++ b/drivers/media/dvb-frontends/m88ds3103_priv.h @@ -1,5 +1,5 @@ /* - * Montage M88DS3103 demodulator driver + * Montage Technology M88DS3103/M88RS6000 demodulator driver * * Copyright (C) 2013 Antti Palosaari * @@ -30,8 +30,7 @@ #define M88RS6000_CHIP_ID 0x74 #define M88DS3103_CHIP_ID 0x70 -struct m88ds3103_priv { - struct i2c_adapter *i2c; +struct m88ds3103_dev { struct i2c_client *client; /* mutex needed due to own tuner I2C adapter */ struct mutex i2c_mutex; -- cgit v1.2.3-59-g8ed1b From 478932b16052f5ded74685d096ae920cd17d6424 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 16 Apr 2015 22:43:52 -0300 Subject: [media] m88ds3103: use regmap for I2C register access Use regmap for I2C register access. Remove own I2C repeated mutex as it should not be needed. I2C adapter lock is already taken when I2C mux adapter is called, no need for double locking. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/Kconfig | 1 + drivers/media/dvb-frontends/m88ds3103.c | 429 +++++++++------------------ drivers/media/dvb-frontends/m88ds3103_priv.h | 5 +- 3 files changed, 145 insertions(+), 290 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index b7627caba1e7..0d35f5850ff1 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -38,6 +38,7 @@ config DVB_STV6110x config DVB_M88DS3103 tristate "Montage Technology M88DS3103" depends on DVB_CORE && I2C && I2C_MUX + select REGMAP_I2C default m if !MEDIA_SUBDRV_AUTOSELECT help Say Y when you want to support this frontend. diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index c4acf7754a74..356f23343d33 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -18,141 +18,6 @@ static struct dvb_frontend_ops m88ds3103_ops; -/* write multiple registers */ -static int m88ds3103_wr_regs(struct m88ds3103_dev *dev, - u8 reg, const u8 *val, int len) -{ -#define MAX_WR_LEN 32 -#define MAX_WR_XFER_LEN (MAX_WR_LEN + 1) - struct i2c_client *client = dev->client; - int ret; - u8 buf[MAX_WR_XFER_LEN]; - struct i2c_msg msg[1] = { - { - .addr = client->addr, - .flags = 0, - .len = 1 + len, - .buf = buf, - } - }; - - if (WARN_ON(len > MAX_WR_LEN)) - return -EINVAL; - - buf[0] = reg; - memcpy(&buf[1], val, len); - - mutex_lock(&dev->i2c_mutex); - ret = i2c_transfer(client->adapter, msg, 1); - mutex_unlock(&dev->i2c_mutex); - if (ret == 1) { - ret = 0; - } else { - dev_warn(&client->dev, "i2c wr failed=%d reg=%02x len=%d\n", - ret, reg, len); - ret = -EREMOTEIO; - } - - return ret; -} - -/* read multiple registers */ -static int m88ds3103_rd_regs(struct m88ds3103_dev *dev, - u8 reg, u8 *val, int len) -{ -#define MAX_RD_LEN 3 -#define MAX_RD_XFER_LEN (MAX_RD_LEN) - struct i2c_client *client = dev->client; - int ret; - u8 buf[MAX_RD_XFER_LEN]; - struct i2c_msg msg[2] = { - { - .addr = client->addr, - .flags = 0, - .len = 1, - .buf = ®, - }, { - .addr = client->addr, - .flags = I2C_M_RD, - .len = len, - .buf = buf, - } - }; - - if (WARN_ON(len > MAX_RD_LEN)) - return -EINVAL; - - mutex_lock(&dev->i2c_mutex); - ret = i2c_transfer(client->adapter, msg, 2); - mutex_unlock(&dev->i2c_mutex); - if (ret == 2) { - memcpy(val, buf, len); - ret = 0; - } else { - dev_warn(&client->dev, "i2c rd failed=%d reg=%02x len=%d\n", - ret, reg, len); - ret = -EREMOTEIO; - } - - return ret; -} - -/* write single register */ -static int m88ds3103_wr_reg(struct m88ds3103_dev *dev, u8 reg, u8 val) -{ - return m88ds3103_wr_regs(dev, reg, &val, 1); -} - -/* read single register */ -static int m88ds3103_rd_reg(struct m88ds3103_dev *dev, u8 reg, u8 *val) -{ - return m88ds3103_rd_regs(dev, reg, val, 1); -} - -/* write single register with mask */ -static int m88ds3103_wr_reg_mask(struct m88ds3103_dev *dev, - u8 reg, u8 val, u8 mask) -{ - int ret; - u8 u8tmp; - - /* no need for read if whole reg is written */ - if (mask != 0xff) { - ret = m88ds3103_rd_regs(dev, reg, &u8tmp, 1); - if (ret) - return ret; - - val &= mask; - u8tmp &= ~mask; - val |= u8tmp; - } - - return m88ds3103_wr_regs(dev, reg, &val, 1); -} - -/* read single register with mask */ -static int m88ds3103_rd_reg_mask(struct m88ds3103_dev *dev, - u8 reg, u8 *val, u8 mask) -{ - int ret, i; - u8 u8tmp; - - ret = m88ds3103_rd_regs(dev, reg, &u8tmp, 1); - if (ret) - return ret; - - u8tmp &= mask; - - /* find position of the first bit */ - for (i = 0; i < 8; i++) { - if ((mask >> i) & 0x01) - break; - } - *val = u8tmp >> i; - - return 0; -} - /* write reg val table using reg addr auto increment */ static int m88ds3103_wr_reg_val_tab(struct m88ds3103_dev *dev, const struct m88ds3103_reg_val *tab, int tab_len) @@ -173,7 +38,7 @@ static int m88ds3103_wr_reg_val_tab(struct m88ds3103_dev *dev, if (i == tab_len - 1 || tab[i].reg != tab[i + 1].reg - 1 || !((j + 1) % (dev->cfg->i2c_wr_max - 1))) { - ret = m88ds3103_wr_regs(dev, tab[i].reg - j, buf, j + 1); + ret = regmap_bulk_write(dev->regmap, tab[i].reg - j, buf, j + 1); if (ret) goto err; @@ -194,7 +59,7 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, struct i2c_client *client = dev->client; struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, i, itmp; - u8 u8tmp; + unsigned int utmp; u8 buf[3]; *status = 0; @@ -206,21 +71,21 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, switch (c->delivery_system) { case SYS_DVBS: - ret = m88ds3103_rd_reg_mask(dev, 0xd1, &u8tmp, 0x07); + ret = regmap_read(dev->regmap, 0xd1, &utmp); if (ret) goto err; - if (u8tmp == 0x07) + if ((utmp & 0x07) == 0x07) *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; break; case SYS_DVBS2: - ret = m88ds3103_rd_reg_mask(dev, 0x0d, &u8tmp, 0x8f); + ret = regmap_read(dev->regmap, 0x0d, &utmp); if (ret) goto err; - if (u8tmp == 0x8f) + if ((utmp & 0x8f) == 0x8f) *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; @@ -232,8 +97,7 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, } dev->fe_status = *status; - - dev_dbg(&client->dev, "lock=%02x status=%02x\n", u8tmp, *status); + dev_dbg(&client->dev, "lock=%02x status=%02x\n", utmp, *status); /* CNR */ if (dev->fe_status & FE_HAS_VITERBI) { @@ -248,11 +112,11 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, itmp = 0; for (i = 0; i < M88DS3103_SNR_ITERATIONS; i++) { - ret = m88ds3103_rd_reg(dev, 0xff, &buf[0]); + ret = regmap_read(dev->regmap, 0xff, &utmp); if (ret) goto err; - itmp += buf[0]; + itmp += utmp; } /* use of single register limits max value to 15 dB */ @@ -266,7 +130,7 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, signal_tot = 0; for (i = 0; i < M88DS3103_SNR_ITERATIONS; i++) { - ret = m88ds3103_rd_regs(dev, 0x8c, buf, 3); + ret = regmap_bulk_read(dev->regmap, 0x8c, buf, 3); if (ret) goto err; @@ -311,17 +175,17 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, switch (c->delivery_system) { case SYS_DVBS: - ret = m88ds3103_wr_reg(dev, 0xf9, 0x04); + ret = regmap_write(dev->regmap, 0xf9, 0x04); if (ret) goto err; - ret = m88ds3103_rd_reg(dev, 0xf8, &u8tmp); + ret = regmap_read(dev->regmap, 0xf8, &utmp); if (ret) goto err; /* measurement ready? */ - if (!(u8tmp & 0x10)) { - ret = m88ds3103_rd_regs(dev, 0xf6, buf, 2); + if (!(utmp & 0x10)) { + ret = regmap_bulk_read(dev->regmap, 0xf6, buf, 2); if (ret) goto err; @@ -332,14 +196,14 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, dev->dvbv3_ber = post_bit_error; /* restart measurement */ - u8tmp |= 0x10; - ret = m88ds3103_wr_reg(dev, 0xf8, u8tmp); + utmp |= 0x10; + ret = regmap_write(dev->regmap, 0xf8, utmp); if (ret) goto err; } break; case SYS_DVBS2: - ret = m88ds3103_rd_regs(dev, 0xd5, buf, 3); + ret = regmap_bulk_read(dev->regmap, 0xd5, buf, 3); if (ret) goto err; @@ -347,7 +211,7 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, /* enough data? */ if (utmp > 4000) { - ret = m88ds3103_rd_regs(dev, 0xf7, buf, 2); + ret = regmap_bulk_read(dev->regmap, 0xf7, buf, 2); if (ret) goto err; @@ -358,19 +222,19 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, dev->dvbv3_ber = post_bit_error; /* restart measurement */ - ret = m88ds3103_wr_reg(dev, 0xd1, 0x01); + ret = regmap_write(dev->regmap, 0xd1, 0x01); if (ret) goto err; - ret = m88ds3103_wr_reg(dev, 0xf9, 0x01); + ret = regmap_write(dev->regmap, 0xf9, 0x01); if (ret) goto err; - ret = m88ds3103_wr_reg(dev, 0xf9, 0x00); + ret = regmap_write(dev->regmap, 0xf9, 0x00); if (ret) goto err; - ret = m88ds3103_wr_reg(dev, 0xd1, 0x00); + ret = regmap_write(dev->regmap, 0xd1, 0x00); if (ret) goto err; } @@ -420,17 +284,17 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) } /* reset */ - ret = m88ds3103_wr_reg(dev, 0x07, 0x80); + ret = regmap_write(dev->regmap, 0x07, 0x80); if (ret) goto err; - ret = m88ds3103_wr_reg(dev, 0x07, 0x00); + ret = regmap_write(dev->regmap, 0x07, 0x00); if (ret) goto err; /* Disable demod clock path */ if (dev->chip_id == M88RS6000_CHIP_ID) { - ret = m88ds3103_wr_reg(dev, 0x06, 0xe0); + ret = regmap_write(dev->regmap, 0x06, 0xe0); if (ret) goto err; } @@ -468,7 +332,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) target_mclk = 144000; /* Enable demod clock path */ - ret = m88ds3103_wr_reg(dev, 0x06, 0x00); + ret = regmap_write(dev->regmap, 0x06, 0x00); if (ret) goto err; usleep_range(10000, 20000); @@ -514,19 +378,19 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) u8tmp2 = 0x00; /* 0b00 */ break; } - ret = m88ds3103_wr_reg_mask(dev, 0x22, u8tmp1 << 6, 0xc0); + ret = regmap_update_bits(dev->regmap, 0x22, 0xc0, u8tmp1 << 6); if (ret) goto err; - ret = m88ds3103_wr_reg_mask(dev, 0x24, u8tmp2 << 6, 0xc0); + ret = regmap_update_bits(dev->regmap, 0x24, 0xc0, u8tmp2 << 6); if (ret) goto err; } - ret = m88ds3103_wr_reg(dev, 0xb2, 0x01); + ret = regmap_write(dev->regmap, 0xb2, 0x01); if (ret) goto err; - ret = m88ds3103_wr_reg(dev, 0x00, 0x01); + ret = regmap_write(dev->regmap, 0x00, 0x01); if (ret) goto err; @@ -565,23 +429,23 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) if (dev->chip_id == M88RS6000_CHIP_ID) { if ((c->delivery_system == SYS_DVBS2) && ((c->symbol_rate / 1000) <= 5000)) { - ret = m88ds3103_wr_reg(dev, 0xc0, 0x04); + ret = regmap_write(dev->regmap, 0xc0, 0x04); if (ret) goto err; buf[0] = 0x09; buf[1] = 0x22; buf[2] = 0x88; - ret = m88ds3103_wr_regs(dev, 0x8a, buf, 3); + ret = regmap_bulk_write(dev->regmap, 0x8a, buf, 3); if (ret) goto err; } - ret = m88ds3103_wr_reg_mask(dev, 0x9d, 0x08, 0x08); + ret = regmap_update_bits(dev->regmap, 0x9d, 0x08, 0x08); if (ret) goto err; - ret = m88ds3103_wr_reg(dev, 0xf1, 0x01); + ret = regmap_write(dev->regmap, 0xf1, 0x01); if (ret) goto err; - ret = m88ds3103_wr_reg_mask(dev, 0x30, 0x80, 0x80); + ret = regmap_update_bits(dev->regmap, 0x30, 0x80, 0x80); if (ret) goto err; } @@ -611,14 +475,14 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) u8tmp |= 0x40; /* TS mode */ - ret = m88ds3103_wr_reg(dev, 0xfd, u8tmp); + ret = regmap_write(dev->regmap, 0xfd, u8tmp); if (ret) goto err; switch (dev->cfg->ts_mode) { case M88DS3103_TS_SERIAL: case M88DS3103_TS_SERIAL_D7: - ret = m88ds3103_wr_reg_mask(dev, 0x29, u8tmp1, 0x20); + ret = regmap_update_bits(dev->regmap, 0x29, 0x20, u8tmp1); if (ret) goto err; u8tmp1 = 0; @@ -643,17 +507,17 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) /* u8tmp2[5:0] => ea[5:0] */ u8tmp2 &= 0x3f; - ret = m88ds3103_rd_reg(dev, 0xfe, &u8tmp); + ret = regmap_bulk_read(dev->regmap, 0xfe, &u8tmp, 1); if (ret) goto err; u8tmp = ((u8tmp & 0xf0) << 0) | u8tmp1 >> 2; - ret = m88ds3103_wr_reg(dev, 0xfe, u8tmp); + ret = regmap_write(dev->regmap, 0xfe, u8tmp); if (ret) goto err; u8tmp = ((u8tmp1 & 0x03) << 6) | u8tmp2 >> 0; - ret = m88ds3103_wr_reg(dev, 0xea, u8tmp); + ret = regmap_write(dev->regmap, 0xea, u8tmp); if (ret) goto err; @@ -664,38 +528,38 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) else u8tmp = 0x06; - ret = m88ds3103_wr_reg(dev, 0xc3, 0x08); + ret = regmap_write(dev->regmap, 0xc3, 0x08); if (ret) goto err; - ret = m88ds3103_wr_reg(dev, 0xc8, u8tmp); + ret = regmap_write(dev->regmap, 0xc8, u8tmp); if (ret) goto err; - ret = m88ds3103_wr_reg(dev, 0xc4, 0x08); + ret = regmap_write(dev->regmap, 0xc4, 0x08); if (ret) goto err; - ret = m88ds3103_wr_reg(dev, 0xc7, 0x00); + ret = regmap_write(dev->regmap, 0xc7, 0x00); if (ret) goto err; u16tmp = DIV_ROUND_CLOSEST((c->symbol_rate / 1000) << 15, dev->mclk_khz / 2); buf[0] = (u16tmp >> 0) & 0xff; buf[1] = (u16tmp >> 8) & 0xff; - ret = m88ds3103_wr_regs(dev, 0x61, buf, 2); + ret = regmap_bulk_write(dev->regmap, 0x61, buf, 2); if (ret) goto err; - ret = m88ds3103_wr_reg_mask(dev, 0x4d, dev->cfg->spec_inv << 1, 0x02); + ret = regmap_update_bits(dev->regmap, 0x4d, 0x02, dev->cfg->spec_inv << 1); if (ret) goto err; - ret = m88ds3103_wr_reg_mask(dev, 0x30, dev->cfg->agc_inv << 4, 0x10); + ret = regmap_update_bits(dev->regmap, 0x30, 0x10, dev->cfg->agc_inv << 4); if (ret) goto err; - ret = m88ds3103_wr_reg(dev, 0x33, dev->cfg->agc); + ret = regmap_write(dev->regmap, 0x33, dev->cfg->agc); if (ret) goto err; @@ -709,15 +573,15 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) buf[0] = (s32tmp >> 0) & 0xff; buf[1] = (s32tmp >> 8) & 0xff; - ret = m88ds3103_wr_regs(dev, 0x5e, buf, 2); + ret = regmap_bulk_write(dev->regmap, 0x5e, buf, 2); if (ret) goto err; - ret = m88ds3103_wr_reg(dev, 0x00, 0x00); + ret = regmap_write(dev->regmap, 0x00, 0x00); if (ret) goto err; - ret = m88ds3103_wr_reg(dev, 0xb2, 0x00); + ret = regmap_write(dev->regmap, 0xb2, 0x00); if (ret) goto err; @@ -735,9 +599,9 @@ static int m88ds3103_init(struct dvb_frontend *fe) struct i2c_client *client = dev->client; struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, len, remaining; + unsigned int utmp; const struct firmware *fw = NULL; u8 *fw_file; - u8 u8tmp; dev_dbg(&client->dev, "\n"); @@ -745,34 +609,31 @@ static int m88ds3103_init(struct dvb_frontend *fe) dev->warm = false; /* wake up device from sleep */ - ret = m88ds3103_wr_reg_mask(dev, 0x08, 0x01, 0x01); + ret = regmap_update_bits(dev->regmap, 0x08, 0x01, 0x01); if (ret) goto err; - - ret = m88ds3103_wr_reg_mask(dev, 0x04, 0x00, 0x01); + ret = regmap_update_bits(dev->regmap, 0x04, 0x01, 0x00); if (ret) goto err; - - ret = m88ds3103_wr_reg_mask(dev, 0x23, 0x00, 0x10); + ret = regmap_update_bits(dev->regmap, 0x23, 0x10, 0x00); if (ret) goto err; /* firmware status */ - ret = m88ds3103_rd_reg(dev, 0xb9, &u8tmp); + ret = regmap_read(dev->regmap, 0xb9, &utmp); if (ret) goto err; - dev_dbg(&client->dev, "firmware=%02x\n", u8tmp); + dev_dbg(&client->dev, "firmware=%02x\n", utmp); - if (u8tmp) + if (utmp) goto skip_fw_download; /* global reset, global diseqc reset, golbal fec reset */ - ret = m88ds3103_wr_reg(dev, 0x07, 0xe0); + ret = regmap_write(dev->regmap, 0x07, 0xe0); if (ret) goto err; - - ret = m88ds3103_wr_reg(dev, 0x07, 0x00); + ret = regmap_write(dev->regmap, 0x07, 0x00); if (ret) goto err; @@ -794,7 +655,7 @@ static int m88ds3103_init(struct dvb_frontend *fe) dev_info(&client->dev, "downloading firmware from file '%s'\n", fw_file); - ret = m88ds3103_wr_reg(dev, 0xb2, 0x01); + ret = regmap_write(dev->regmap, 0xb2, 0x01); if (ret) goto error_fw_release; @@ -804,7 +665,7 @@ static int m88ds3103_init(struct dvb_frontend *fe) if (len > (dev->cfg->i2c_wr_max - 1)) len = (dev->cfg->i2c_wr_max - 1); - ret = m88ds3103_wr_regs(dev, 0xb0, + ret = regmap_bulk_write(dev->regmap, 0xb0, &fw->data[fw->size - remaining], len); if (ret) { dev_err(&client->dev, "firmware download failed=%d\n", @@ -813,18 +674,18 @@ static int m88ds3103_init(struct dvb_frontend *fe) } } - ret = m88ds3103_wr_reg(dev, 0xb2, 0x00); + ret = regmap_write(dev->regmap, 0xb2, 0x00); if (ret) goto error_fw_release; release_firmware(fw); fw = NULL; - ret = m88ds3103_rd_reg(dev, 0xb9, &u8tmp); + ret = regmap_read(dev->regmap, 0xb9, &utmp); if (ret) goto err; - if (!u8tmp) { + if (!utmp) { dev_info(&client->dev, "firmware did not run\n"); ret = -EFAULT; goto err; @@ -833,7 +694,7 @@ static int m88ds3103_init(struct dvb_frontend *fe) dev_info(&client->dev, "found a '%s' in warm state\n", m88ds3103_ops.info.name); dev_info(&client->dev, "firmware version: %X.%X\n", - (u8tmp >> 4) & 0xf, (u8tmp >> 0 & 0xf)); + (utmp >> 4) & 0xf, (utmp >> 0 & 0xf)); skip_fw_download: /* warm state */ @@ -860,7 +721,7 @@ static int m88ds3103_sleep(struct dvb_frontend *fe) struct m88ds3103_dev *dev = fe->demodulator_priv; struct i2c_client *client = dev->client; int ret; - u8 u8tmp; + unsigned int utmp; dev_dbg(&client->dev, "\n"); @@ -869,23 +730,21 @@ static int m88ds3103_sleep(struct dvb_frontend *fe) /* TS Hi-Z */ if (dev->chip_id == M88RS6000_CHIP_ID) - u8tmp = 0x29; + utmp = 0x29; else - u8tmp = 0x27; - ret = m88ds3103_wr_reg_mask(dev, u8tmp, 0x00, 0x01); + utmp = 0x27; + ret = regmap_update_bits(dev->regmap, utmp, 0x01, 0x00); if (ret) goto err; /* sleep */ - ret = m88ds3103_wr_reg_mask(dev, 0x08, 0x00, 0x01); + ret = regmap_update_bits(dev->regmap, 0x08, 0x01, 0x00); if (ret) goto err; - - ret = m88ds3103_wr_reg_mask(dev, 0x04, 0x01, 0x01); + ret = regmap_update_bits(dev->regmap, 0x04, 0x01, 0x01); if (ret) goto err; - - ret = m88ds3103_wr_reg_mask(dev, 0x23, 0x10, 0x10); + ret = regmap_update_bits(dev->regmap, 0x23, 0x10, 0x10); if (ret) goto err; @@ -912,11 +771,11 @@ static int m88ds3103_get_frontend(struct dvb_frontend *fe) switch (c->delivery_system) { case SYS_DVBS: - ret = m88ds3103_rd_reg(dev, 0xe0, &buf[0]); + ret = regmap_bulk_read(dev->regmap, 0xe0, &buf[0], 1); if (ret) goto err; - ret = m88ds3103_rd_reg(dev, 0xe6, &buf[1]); + ret = regmap_bulk_read(dev->regmap, 0xe6, &buf[1], 1); if (ret) goto err; @@ -953,15 +812,15 @@ static int m88ds3103_get_frontend(struct dvb_frontend *fe) break; case SYS_DVBS2: - ret = m88ds3103_rd_reg(dev, 0x7e, &buf[0]); + ret = regmap_bulk_read(dev->regmap, 0x7e, &buf[0], 1); if (ret) goto err; - ret = m88ds3103_rd_reg(dev, 0x89, &buf[1]); + ret = regmap_bulk_read(dev->regmap, 0x89, &buf[1], 1); if (ret) goto err; - ret = m88ds3103_rd_reg(dev, 0xf2, &buf[2]); + ret = regmap_bulk_read(dev->regmap, 0xf2, &buf[2], 1); if (ret) goto err; @@ -1052,7 +911,7 @@ static int m88ds3103_get_frontend(struct dvb_frontend *fe) goto err; } - ret = m88ds3103_rd_regs(dev, 0x6d, buf, 2); + ret = regmap_bulk_read(dev->regmap, 0x6d, buf, 2); if (ret) goto err; @@ -1092,7 +951,7 @@ static int m88ds3103_set_tone(struct dvb_frontend *fe, struct m88ds3103_dev *dev = fe->demodulator_priv; struct i2c_client *client = dev->client; int ret; - u8 u8tmp, tone, reg_a1_mask; + unsigned int utmp, tone, reg_a1_mask; dev_dbg(&client->dev, "fe_sec_tone_mode=%d\n", fe_sec_tone_mode); @@ -1116,13 +975,13 @@ static int m88ds3103_set_tone(struct dvb_frontend *fe, goto err; } - u8tmp = tone << 7 | dev->cfg->envelope_mode << 5; - ret = m88ds3103_wr_reg_mask(dev, 0xa2, u8tmp, 0xe0); + utmp = tone << 7 | dev->cfg->envelope_mode << 5; + ret = regmap_update_bits(dev->regmap, 0xa2, 0xe0, utmp); if (ret) goto err; - u8tmp = 1 << 2; - ret = m88ds3103_wr_reg_mask(dev, 0xa1, u8tmp, reg_a1_mask); + utmp = 1 << 2; + ret = regmap_update_bits(dev->regmap, 0xa1, reg_a1_mask, utmp); if (ret) goto err; @@ -1138,7 +997,7 @@ static int m88ds3103_set_voltage(struct dvb_frontend *fe, struct m88ds3103_dev *dev = fe->demodulator_priv; struct i2c_client *client = dev->client; int ret; - u8 u8tmp; + unsigned int utmp; bool voltage_sel, voltage_dis; dev_dbg(&client->dev, "fe_sec_voltage=%d\n", fe_sec_voltage); @@ -1171,8 +1030,8 @@ static int m88ds3103_set_voltage(struct dvb_frontend *fe, voltage_sel ^= dev->cfg->lnb_hv_pol; voltage_dis ^= dev->cfg->lnb_en_pol; - u8tmp = voltage_dis << 1 | voltage_sel << 0; - ret = m88ds3103_wr_reg_mask(dev, 0xa2, u8tmp, 0x03); + utmp = voltage_dis << 1 | voltage_sel << 0; + ret = regmap_update_bits(dev->regmap, 0xa2, 0x03, utmp); if (ret) goto err; @@ -1188,8 +1047,8 @@ static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe, struct m88ds3103_dev *dev = fe->demodulator_priv; struct i2c_client *client = dev->client; int ret; + unsigned int utmp; unsigned long timeout; - u8 u8tmp; dev_dbg(&client->dev, "msg=%*ph\n", diseqc_cmd->msg_len, diseqc_cmd->msg); @@ -1204,17 +1063,17 @@ static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe, goto err; } - u8tmp = dev->cfg->envelope_mode << 5; - ret = m88ds3103_wr_reg_mask(dev, 0xa2, u8tmp, 0xe0); + utmp = dev->cfg->envelope_mode << 5; + ret = regmap_update_bits(dev->regmap, 0xa2, 0xe0, utmp); if (ret) goto err; - ret = m88ds3103_wr_regs(dev, 0xa3, diseqc_cmd->msg, + ret = regmap_bulk_write(dev->regmap, 0xa3, diseqc_cmd->msg, diseqc_cmd->msg_len); if (ret) goto err; - ret = m88ds3103_wr_reg(dev, 0xa1, + ret = regmap_write(dev->regmap, 0xa1, (diseqc_cmd->msg_len - 1) << 3 | 0x07); if (ret) goto err; @@ -1226,29 +1085,30 @@ static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe, /* DiSEqC message typical period is 54 ms */ usleep_range(50000, 54000); - for (u8tmp = 1; !time_after(jiffies, timeout) && u8tmp;) { - ret = m88ds3103_rd_reg_mask(dev, 0xa1, &u8tmp, 0x40); + for (utmp = 1; !time_after(jiffies, timeout) && utmp;) { + ret = regmap_read(dev->regmap, 0xa1, &utmp); if (ret) goto err; + utmp = (utmp >> 6) & 0x1; } - if (u8tmp == 0) { + if (utmp == 0) { dev_dbg(&client->dev, "diseqc tx took %u ms\n", jiffies_to_msecs(jiffies) - (jiffies_to_msecs(timeout) - SEND_MASTER_CMD_TIMEOUT)); } else { dev_dbg(&client->dev, "diseqc tx timeout\n"); - ret = m88ds3103_wr_reg_mask(dev, 0xa1, 0x40, 0xc0); + ret = regmap_update_bits(dev->regmap, 0xa1, 0xc0, 0x40); if (ret) goto err; } - ret = m88ds3103_wr_reg_mask(dev, 0xa2, 0x80, 0xc0); + ret = regmap_update_bits(dev->regmap, 0xa2, 0xc0, 0x80); if (ret) goto err; - if (u8tmp == 1) { + if (utmp == 1) { ret = -ETIMEDOUT; goto err; } @@ -1265,8 +1125,8 @@ static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe, struct m88ds3103_dev *dev = fe->demodulator_priv; struct i2c_client *client = dev->client; int ret; + unsigned int utmp, burst; unsigned long timeout; - u8 u8tmp, burst; dev_dbg(&client->dev, "fe_sec_mini_cmd=%d\n", fe_sec_mini_cmd); @@ -1275,8 +1135,8 @@ static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe, goto err; } - u8tmp = dev->cfg->envelope_mode << 5; - ret = m88ds3103_wr_reg_mask(dev, 0xa2, u8tmp, 0xe0); + utmp = dev->cfg->envelope_mode << 5; + ret = regmap_update_bits(dev->regmap, 0xa2, 0xe0, utmp); if (ret) goto err; @@ -1293,7 +1153,7 @@ static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe, goto err; } - ret = m88ds3103_wr_reg(dev, 0xa1, burst); + ret = regmap_write(dev->regmap, 0xa1, burst); if (ret) goto err; @@ -1304,29 +1164,30 @@ static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe, /* DiSEqC ToneBurst period is 12.5 ms */ usleep_range(8500, 12500); - for (u8tmp = 1; !time_after(jiffies, timeout) && u8tmp;) { - ret = m88ds3103_rd_reg_mask(dev, 0xa1, &u8tmp, 0x40); + for (utmp = 1; !time_after(jiffies, timeout) && utmp;) { + ret = regmap_read(dev->regmap, 0xa1, &utmp); if (ret) goto err; + utmp = (utmp >> 6) & 0x1; } - if (u8tmp == 0) { + if (utmp == 0) { dev_dbg(&client->dev, "diseqc tx took %u ms\n", jiffies_to_msecs(jiffies) - (jiffies_to_msecs(timeout) - SEND_BURST_TIMEOUT)); } else { dev_dbg(&client->dev, "diseqc tx timeout\n"); - ret = m88ds3103_wr_reg_mask(dev, 0xa1, 0x40, 0xc0); + ret = regmap_update_bits(dev->regmap, 0xa1, 0xc0, 0x40); if (ret) goto err; } - ret = m88ds3103_wr_reg_mask(dev, 0xa2, 0x80, 0xc0); + ret = regmap_update_bits(dev->regmap, 0xa2, 0xc0, 0x80); if (ret) goto err; - if (u8tmp == 1) { + if (utmp == 1) { ret = -ETIMEDOUT; goto err; } @@ -1358,40 +1219,25 @@ static int m88ds3103_select(struct i2c_adapter *adap, void *mux_priv, u32 chan) struct m88ds3103_dev *dev = mux_priv; struct i2c_client *client = dev->client; int ret; - struct i2c_msg gate_open_msg[1] = { - { - .addr = client->addr, - .flags = 0, - .len = 2, - .buf = "\x03\x11", - } + struct i2c_msg msg = { + .addr = client->addr, + .flags = 0, + .len = 2, + .buf = "\x03\x11", }; - mutex_lock(&dev->i2c_mutex); - - /* open tuner I2C repeater for 1 xfer, closes automatically */ - ret = __i2c_transfer(client->adapter, gate_open_msg, 1); + /* Open tuner I2C repeater for 1 xfer, closes automatically */ + ret = __i2c_transfer(client->adapter, &msg, 1); if (ret != 1) { dev_warn(&client->dev, "i2c wr failed=%d\n", ret); if (ret >= 0) ret = -EREMOTEIO; - return ret; } return 0; } -static int m88ds3103_deselect(struct i2c_adapter *adap, void *mux_priv, - u32 chan) -{ - struct m88ds3103_dev *dev = mux_priv; - - mutex_unlock(&dev->i2c_mutex); - - return 0; -} - /* * XXX: That is wrapper to m88ds3103_probe() via driver core in order to provide * proper I2C client for legacy media attach binding. @@ -1500,7 +1346,7 @@ static int m88ds3103_probe(struct i2c_client *client, struct m88ds3103_dev *dev; struct m88ds3103_platform_data *pdata = client->dev.platform_data; int ret; - u8 chip_id, u8tmp; + unsigned int utmp; dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { @@ -1522,34 +1368,41 @@ static int m88ds3103_probe(struct i2c_client *client, dev->config.lnb_hv_pol = pdata->lnb_hv_pol; dev->config.lnb_en_pol = pdata->lnb_en_pol; dev->cfg = &dev->config; - mutex_init(&dev->i2c_mutex); + /* create regmap */ + dev->regmap_config.reg_bits = 8, + dev->regmap_config.val_bits = 8, + dev->regmap_config.lock_arg = dev, + dev->regmap = devm_regmap_init_i2c(client, &dev->regmap_config); + if (IS_ERR(dev->regmap)) { + ret = PTR_ERR(dev->regmap); + goto err_kfree; + } /* 0x00: chip id[6:0], 0x01: chip ver[7:0], 0x02: chip ver[15:8] */ - ret = m88ds3103_rd_reg(dev, 0x00, &chip_id); + ret = regmap_read(dev->regmap, 0x00, &utmp); if (ret) goto err_kfree; - chip_id >>= 1; - dev_dbg(&client->dev, "chip_id=%02x\n", chip_id); + dev->chip_id = utmp >> 1; + dev_dbg(&client->dev, "chip_id=%02x\n", dev->chip_id); - switch (chip_id) { + switch (dev->chip_id) { case M88RS6000_CHIP_ID: case M88DS3103_CHIP_ID: break; default: goto err_kfree; } - dev->chip_id = chip_id; switch (dev->cfg->clock_out) { case M88DS3103_CLOCK_OUT_DISABLED: - u8tmp = 0x80; + utmp = 0x80; break; case M88DS3103_CLOCK_OUT_ENABLED: - u8tmp = 0x00; + utmp = 0x00; break; case M88DS3103_CLOCK_OUT_ENABLED_DIV2: - u8tmp = 0x10; + utmp = 0x10; break; default: ret = -EINVAL; @@ -1558,28 +1411,28 @@ static int m88ds3103_probe(struct i2c_client *client, /* 0x29 register is defined differently for m88rs6000. */ /* set internal tuner address to 0x21 */ - if (chip_id == M88RS6000_CHIP_ID) - u8tmp = 0x00; + if (dev->chip_id == M88RS6000_CHIP_ID) + utmp = 0x00; - ret = m88ds3103_wr_reg(dev, 0x29, u8tmp); + ret = regmap_write(dev->regmap, 0x29, utmp); if (ret) goto err_kfree; /* sleep */ - ret = m88ds3103_wr_reg_mask(dev, 0x08, 0x00, 0x01); + ret = regmap_update_bits(dev->regmap, 0x08, 0x01, 0x00); if (ret) goto err_kfree; - ret = m88ds3103_wr_reg_mask(dev, 0x04, 0x01, 0x01); + ret = regmap_update_bits(dev->regmap, 0x04, 0x01, 0x01); if (ret) goto err_kfree; - ret = m88ds3103_wr_reg_mask(dev, 0x23, 0x10, 0x10); + ret = regmap_update_bits(dev->regmap, 0x23, 0x10, 0x10); if (ret) goto err_kfree; /* create mux i2c adapter for tuner */ dev->i2c_adapter = i2c_add_mux_adapter(client->adapter, &client->dev, dev, 0, 0, 0, m88ds3103_select, - m88ds3103_deselect); + NULL); if (dev->i2c_adapter == NULL) { ret = -ENOMEM; goto err_kfree; diff --git a/drivers/media/dvb-frontends/m88ds3103_priv.h b/drivers/media/dvb-frontends/m88ds3103_priv.h index 35c7f3eced26..eee8c22c51ec 100644 --- a/drivers/media/dvb-frontends/m88ds3103_priv.h +++ b/drivers/media/dvb-frontends/m88ds3103_priv.h @@ -22,6 +22,7 @@ #include "dvb_math.h" #include #include +#include #include #define M88DS3103_FIRMWARE "dvb-demod-m88ds3103.fw" @@ -32,8 +33,8 @@ struct m88ds3103_dev { struct i2c_client *client; - /* mutex needed due to own tuner I2C adapter */ - struct mutex i2c_mutex; + struct regmap_config regmap_config; + struct regmap *regmap; struct m88ds3103_config config; const struct m88ds3103_config *cfg; struct dvb_frontend fe; -- cgit v1.2.3-59-g8ed1b From 76b91be3d360af85f4ad2a27a54268726bee7679 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 16 Apr 2015 22:55:31 -0300 Subject: [media] em28xx: PCTV 461e use I2C client for demod and SEC Use I2C client binding for demod and SEC. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-dvb.c | 136 +++++++++++++++++++++------------- 1 file changed, 83 insertions(+), 53 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index be0abca04fb4..a38248360833 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -1521,64 +1521,94 @@ static int em28xx_dvb_init(struct em28xx *dev) } } break; - case EM28178_BOARD_PCTV_461E: - { - /* demod I2C adapter */ - struct i2c_adapter *i2c_adapter; - struct i2c_client *client; - struct i2c_board_info info; - struct ts2020_config ts2020_config = { - }; - memset(&info, 0, sizeof(struct i2c_board_info)); - - /* attach demod */ - dvb->fe[0] = dvb_attach(m88ds3103_attach, - &pctv_461e_m88ds3103_config, - &dev->i2c_adap[dev->def_i2c_bus], - &i2c_adapter); - if (dvb->fe[0] == NULL) { - result = -ENODEV; - goto out_free; - } - - /* attach tuner */ - ts2020_config.fe = dvb->fe[0]; - strlcpy(info.type, "ts2022", I2C_NAME_SIZE); - info.addr = 0x60; - info.platform_data = &ts2020_config; - request_module("ts2020"); - client = i2c_new_device(i2c_adapter, &info); - if (client == NULL || client->dev.driver == NULL) { - dvb_frontend_detach(dvb->fe[0]); - result = -ENODEV; - goto out_free; - } - - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); - dvb_frontend_detach(dvb->fe[0]); - result = -ENODEV; - goto out_free; - } + case EM28178_BOARD_PCTV_461E: { + struct i2c_client *client; + struct i2c_adapter *i2c_adapter; + struct i2c_board_info board_info; + struct m88ds3103_platform_data m88ds3103_pdata = {}; + struct ts2020_config ts2020_config = {}; + struct a8293_platform_data a8293_pdata = {}; - /* delegate signal strength measurement to tuner */ - dvb->fe[0]->ops.read_signal_strength = - dvb->fe[0]->ops.tuner_ops.get_rf_strength; + /* attach demod */ + m88ds3103_pdata.clk = 27000000; + m88ds3103_pdata.i2c_wr_max = 33; + m88ds3103_pdata.ts_mode = M88DS3103_TS_PARALLEL; + m88ds3103_pdata.ts_clk = 16000; + m88ds3103_pdata.ts_clk_pol = 1; + m88ds3103_pdata.agc = 0x99; + memset(&board_info, 0, sizeof(board_info)); + strlcpy(board_info.type, "m88ds3103", I2C_NAME_SIZE); + board_info.addr = 0x68; + board_info.platform_data = &m88ds3103_pdata; + request_module("m88ds3103"); + client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info); + if (client == NULL || client->dev.driver == NULL) { + result = -ENODEV; + goto out_free; + } + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + result = -ENODEV; + goto out_free; + } + dvb->fe[0] = m88ds3103_pdata.get_dvb_frontend(client); + i2c_adapter = m88ds3103_pdata.get_i2c_adapter(client); + dvb->i2c_client_demod = client; - /* attach SEC */ - if (!dvb_attach(a8293_attach, dvb->fe[0], - &dev->i2c_adap[dev->def_i2c_bus], - &em28xx_a8293_config)) { - module_put(client->dev.driver->owner); - i2c_unregister_device(client); - dvb_frontend_detach(dvb->fe[0]); - result = -ENODEV; - goto out_free; - } + /* attach tuner */ + ts2020_config.fe = dvb->fe[0]; + memset(&board_info, 0, sizeof(board_info)); + strlcpy(board_info.type, "ts2022", I2C_NAME_SIZE); + board_info.addr = 0x60; + board_info.platform_data = &ts2020_config; + request_module("ts2020"); + client = i2c_new_device(i2c_adapter, &board_info); + if (client == NULL || client->dev.driver == NULL) { + module_put(dvb->i2c_client_demod->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_demod); + result = -ENODEV; + goto out_free; + } + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + module_put(dvb->i2c_client_demod->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_demod); + result = -ENODEV; + goto out_free; + } + dvb->i2c_client_tuner = client; + /* delegate signal strength measurement to tuner */ + dvb->fe[0]->ops.read_signal_strength = + dvb->fe[0]->ops.tuner_ops.get_rf_strength; - dvb->i2c_client_tuner = client; + /* attach SEC */ + a8293_pdata.dvb_frontend = dvb->fe[0]; + memset(&board_info, 0, sizeof(board_info)); + strlcpy(board_info.type, "a8293", I2C_NAME_SIZE); + board_info.addr = 0x08; + board_info.platform_data = &a8293_pdata; + request_module("a8293"); + client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info); + if (client == NULL || client->dev.driver == NULL) { + module_put(dvb->i2c_client_tuner->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_tuner); + module_put(dvb->i2c_client_demod->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_demod); + result = -ENODEV; + goto out_free; + } + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + module_put(dvb->i2c_client_tuner->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_tuner); + module_put(dvb->i2c_client_demod->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_demod); + result = -ENODEV; + goto out_free; } + dvb->i2c_client_sec = client; break; + } case EM28178_BOARD_PCTV_292E: { struct i2c_adapter *adapter; -- cgit v1.2.3-59-g8ed1b From 0f91c9d6bab956fe55c32f143b21cbcc3538f699 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 26 May 2015 12:04:00 -0300 Subject: [media] TS2020: Calculate tuner gain correctly The TS2020 and TS2022 tuners take an input from the demodulator indicating the AGC setting on that component that is then used to influence the tuner's own gain. This should be taken into account when calculating the gain and signal strength. Further, the existing TS2020 driver miscalculates the signal strength as the result of its calculations can exceed the storage capacity of the 16-bit word used to return it to userspace. To this end: (1) Add a callback function (->get_agc_pwm()) in the ts2020_config struct that the tuner can call to get the AGC PWM value from the demodulator. (2) Modify the TS2020 driver to calculate the gain according to Montage's specification with the adjustment that we produce a negative value and scale it to 0.001dB units (which is what the DVBv5 API will require): (a) Callback to the demodulator to retrieve the AGC PWM value and then turn that into Vagc for incorporation in the calculations. If the callback is unset, assume a Vagc of 0. (b) Calculate the tuner gain from a combination of Vagc and the tuner's RF gain and baseband gain settings. (3) Turn this into a percentage signal strength as per Montage's specification for return to userspace with the DVBv3 API. (4) Provide a function in the M88DS3103 demodulator driver that can be used to get the AGC PWM value on behalf of the tuner. (5) The ts2020_config.get_agc_pwm function should be set by the code that stitches together the drivers for each card. For the DVBSky cards that use the M88DS3103 with the TS2020 or the TS2022, set the get_agc_pwm function to point to m88ds3103_get_agc_pwm. I have tested this with a DVBSky S952 card which has an M88DS3103 and a TS2022. Thanks to Montage for providing access to information about the workings of these parts. Signed-off-by: David Howells Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/m88ds3103.c | 16 ++++ drivers/media/dvb-frontends/m88ds3103.h | 2 + drivers/media/dvb-frontends/ts2020.c | 138 +++++++++++++++++++++++++++----- drivers/media/dvb-frontends/ts2020.h | 5 ++ drivers/media/pci/cx23885/cx23885-dvb.c | 3 + drivers/media/usb/dvb-usb-v2/dvbsky.c | 2 + 6 files changed, 148 insertions(+), 18 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index 356f23343d33..e9b2d2b69b1d 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -52,6 +52,22 @@ err: return ret; } +/* + * Get the demodulator AGC PWM voltage setting supplied to the tuner. + */ +int m88ds3103_get_agc_pwm(struct dvb_frontend *fe, u8 *_agc_pwm) +{ + struct m88ds3103_dev *dev = fe->demodulator_priv; + unsigned tmp; + int ret; + + ret = regmap_read(dev->regmap, 0x3f, &tmp); + if (ret == 0) + *_agc_pwm = tmp; + return ret; +} +EXPORT_SYMBOL(m88ds3103_get_agc_pwm); + static int m88ds3103_read_status(struct dvb_frontend *fe, enum fe_status *status) { diff --git a/drivers/media/dvb-frontends/m88ds3103.h b/drivers/media/dvb-frontends/m88ds3103.h index ff0390593049..04b355a005fb 100644 --- a/drivers/media/dvb-frontends/m88ds3103.h +++ b/drivers/media/dvb-frontends/m88ds3103.h @@ -176,6 +176,7 @@ extern struct dvb_frontend *m88ds3103_attach( const struct m88ds3103_config *config, struct i2c_adapter *i2c, struct i2c_adapter **tuner_i2c); +extern int m88ds3103_get_agc_pwm(struct dvb_frontend *fe, u8 *_agc_pwm); #else static inline struct dvb_frontend *m88ds3103_attach( const struct m88ds3103_config *config, @@ -185,6 +186,7 @@ static inline struct dvb_frontend *m88ds3103_attach( pr_warn("%s: driver disabled by Kconfig\n", __func__); return NULL; } +#define m88ds3103_get_agc_pwm NULL #endif #endif diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c index f674717fa921..277e1cff627b 100644 --- a/drivers/media/dvb-frontends/ts2020.c +++ b/drivers/media/dvb-frontends/ts2020.c @@ -32,6 +32,7 @@ struct ts2020_priv { struct regmap_config regmap_config; struct regmap *regmap; struct dvb_frontend *fe; + int (*get_agc_pwm)(struct dvb_frontend *fe, u8 *_agc_pwm); /* i2c details */ int i2c_address; struct i2c_adapter *i2c; @@ -313,32 +314,132 @@ static int ts2020_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) return 0; } -/* read TS2020 signal strength */ -static int ts2020_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) +/* + * Get the tuner gain. + * @fe: The front end for which we're determining the gain + * @v_agc: The voltage of the AGC from the demodulator (0-2600mV) + * @_gain: Where to store the gain (in 0.001dB units) + * + * Returns 0 or a negative error code. + */ +static int ts2020_read_tuner_gain(struct dvb_frontend *fe, unsigned v_agc, + __s64 *_gain) { struct ts2020_priv *priv = fe->tuner_priv; - unsigned int utmp; - u16 sig_reading, sig_strength; - u8 rfgain, bbgain; + unsigned long gain1, gain2, gain3; + unsigned utmp; + int ret; + + /* Read the RF gain */ + ret = regmap_read(priv->regmap, 0x3d, &utmp); + if (ret < 0) + return ret; + gain1 = utmp & 0x1f; + + /* Read the baseband gain */ + ret = regmap_read(priv->regmap, 0x21, &utmp); + if (ret < 0) + return ret; + gain2 = utmp & 0x1f; + + switch (priv->tuner) { + case TS2020_M88TS2020: + gain1 = clamp_t(long, gain1, 0, 15); + gain2 = clamp_t(long, gain2, 0, 13); + v_agc = clamp_t(long, v_agc, 400, 1100); + + *_gain = -(gain1 * 2330 + + gain2 * 3500 + + v_agc * 24 / 10 * 10 + + 10000); + /* gain in range -19600 to -116850 in units of 0.001dB */ + break; + + case TS2020_M88TS2022: + ret = regmap_read(priv->regmap, 0x66, &utmp); + if (ret < 0) + return ret; + gain3 = (utmp >> 3) & 0x07; + + gain1 = clamp_t(long, gain1, 0, 15); + gain2 = clamp_t(long, gain2, 2, 16); + gain3 = clamp_t(long, gain3, 0, 6); + v_agc = clamp_t(long, v_agc, 600, 1600); + + *_gain = -(gain1 * 2650 + + gain2 * 3380 + + gain3 * 2850 + + v_agc * 176 / 100 * 10 - + 30000); + /* gain in range -47320 to -158950 in units of 0.001dB */ + break; + } + + return 0; +} + +/* + * Get the AGC information from the demodulator and use that to calculate the + * tuner gain. + */ +static int ts2020_get_tuner_gain(struct dvb_frontend *fe, __s64 *_gain) +{ + struct ts2020_priv *priv = fe->tuner_priv; + int v_agc = 0, ret; + u8 agc_pwm; - regmap_read(priv->regmap, 0x3d, &utmp); - rfgain = utmp & 0x1f; - regmap_read(priv->regmap, 0x21, &utmp); - bbgain = utmp & 0x1f; + /* Read the AGC PWM rate from the demodulator */ + if (priv->get_agc_pwm) { + ret = priv->get_agc_pwm(fe, &agc_pwm); + if (ret < 0) + return ret; - if (rfgain > 15) - rfgain = 15; - if (bbgain > 13) - bbgain = 13; + switch (priv->tuner) { + case TS2020_M88TS2020: + v_agc = (int)agc_pwm * 20 - 1166; + break; + case TS2020_M88TS2022: + v_agc = (int)agc_pwm * 16 - 670; + break; + } - sig_reading = rfgain * 2 + bbgain * 3; + if (v_agc < 0) + v_agc = 0; + } - sig_strength = 40 + (64 - sig_reading) * 50 / 64 ; + return ts2020_read_tuner_gain(fe, v_agc, _gain); +} - /* cook the value to be suitable for szap-s2 human readable output */ - *signal_strength = sig_strength * 1000; +/* + * Read TS2020 signal strength in v3 format. + */ +static int ts2020_read_signal_strength(struct dvb_frontend *fe, + u16 *signal_strength) +{ + unsigned strength; + __s64 gain; + int ret; + + /* Determine the total gain of the tuner */ + ret = ts2020_get_tuner_gain(fe, &gain); + if (ret < 0) + return ret; + + /* Calculate the signal strength based on the total gain of the tuner */ + if (gain < -85000) + /* 0%: no signal or weak signal */ + strength = 0; + else if (gain < -65000) + /* 0% - 60%: weak signal */ + strength = 0 + (85000 + gain) * 3 / 1000; + else if (gain < -45000) + /* 60% - 90%: normal signal */ + strength = 60 + (65000 + gain) * 3 / 2000; + else + /* 90% - 99%: strong signal */ + strength = 90 + (45000 + gain) / 5000; + *signal_strength = strength * 65535 / 100; return 0; } @@ -442,6 +543,7 @@ static int ts2020_probe(struct i2c_client *client, dev->clk_out_div = pdata->clk_out_div; dev->frequency_div = pdata->frequency_div; dev->fe = fe; + dev->get_agc_pwm = pdata->get_agc_pwm; fe->tuner_priv = dev; dev->client = client; diff --git a/drivers/media/dvb-frontends/ts2020.h b/drivers/media/dvb-frontends/ts2020.h index f40bbcf9f6eb..37797244774d 100644 --- a/drivers/media/dvb-frontends/ts2020.h +++ b/drivers/media/dvb-frontends/ts2020.h @@ -57,6 +57,11 @@ struct ts2020_config { * driver private, do not set value */ u8 attach_in_use:1; + + /* Operation to be called by the ts2020 driver to get the value of the + * AGC PWM tuner input as theoretically output by the demodulator. + */ + int (*get_agc_pwm)(struct dvb_frontend *fe, u8 *_agc_pwm); }; /* Do not add new ts2020_attach() users! Use I2C bindings instead. */ diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index a77c2d3b50fb..6e8c24cdb2cd 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -1908,6 +1908,7 @@ static int dvb_register(struct cx23885_tsport *port) /* attach tuner */ memset(&ts2020_config, 0, sizeof(ts2020_config)); ts2020_config.fe = fe0->dvb.frontend; + ts2020_config.get_agc_pwm = m88ds3103_get_agc_pwm; memset(&info, 0, sizeof(struct i2c_board_info)); strlcpy(info.type, "ts2020", I2C_NAME_SIZE); info.addr = 0x60; @@ -2039,6 +2040,7 @@ static int dvb_register(struct cx23885_tsport *port) /* attach tuner */ memset(&ts2020_config, 0, sizeof(ts2020_config)); ts2020_config.fe = fe0->dvb.frontend; + ts2020_config.get_agc_pwm = m88ds3103_get_agc_pwm; memset(&info, 0, sizeof(struct i2c_board_info)); strlcpy(info.type, "ts2020", I2C_NAME_SIZE); info.addr = 0x60; @@ -2084,6 +2086,7 @@ static int dvb_register(struct cx23885_tsport *port) /* attach tuner */ memset(&ts2020_config, 0, sizeof(ts2020_config)); ts2020_config.fe = fe0->dvb.frontend; + ts2020_config.get_agc_pwm = m88ds3103_get_agc_pwm; memset(&info, 0, sizeof(struct i2c_board_info)); strlcpy(info.type, "ts2020", I2C_NAME_SIZE); info.addr = 0x60; diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c index 5cc01bbdede9..0376c092bab8 100644 --- a/drivers/media/usb/dvb-usb-v2/dvbsky.c +++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c @@ -332,6 +332,7 @@ static int dvbsky_s960_attach(struct dvb_usb_adapter *adap) /* attach tuner */ ts2020_config.fe = adap->fe[0]; + ts2020_config.get_agc_pwm = m88ds3103_get_agc_pwm; strlcpy(info.type, "ts2020", I2C_NAME_SIZE); info.addr = 0x60; info.platform_data = &ts2020_config; @@ -454,6 +455,7 @@ static int dvbsky_s960c_attach(struct dvb_usb_adapter *adap) /* attach tuner */ ts2020_config.fe = adap->fe[0]; + ts2020_config.get_agc_pwm = m88ds3103_get_agc_pwm; strlcpy(info.type, "ts2020", I2C_NAME_SIZE); info.addr = 0x60; info.platform_data = &ts2020_config; -- cgit v1.2.3-59-g8ed1b From 3366cd5d72c664aa5e447f41ed2f7dac69f6a94e Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 26 May 2015 12:04:07 -0300 Subject: [media] ts2020: Provide DVBv5 API signal strength Provide a DVBv5 API signal strength. This is in units of 0.001 dBm rather than a percentage. >From Antti Palosaari's testing with a signal generator, it appears that the gain calculated according to Montage's specification if negated is a reasonable representation of the signal strength of the generator. To this end: (1) Polled statistic gathering needed to be implemented in the TS2020 driver. This is done in the ts2020_stat_work() function. (2) The calculated gain is placed as the signal strength in the dtv_property_cache associated with the front end with the scale set to FE_SCALE_DECIBEL. (3) The DVBv3 format signal strength then needed to be calculated from the signal strength stored in the dtv_property_cache rather than accessing the value when ts2020_read_signal_strength() is called. Signed-off-by: David Howells Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/ts2020.c | 62 ++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 9 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c index 277e1cff627b..80ae0397b05c 100644 --- a/drivers/media/dvb-frontends/ts2020.c +++ b/drivers/media/dvb-frontends/ts2020.c @@ -32,10 +32,11 @@ struct ts2020_priv { struct regmap_config regmap_config; struct regmap *regmap; struct dvb_frontend *fe; + struct delayed_work stat_work; int (*get_agc_pwm)(struct dvb_frontend *fe, u8 *_agc_pwm); /* i2c details */ - int i2c_address; struct i2c_adapter *i2c; + int i2c_address; u8 clk_out:2; u8 clk_out_div:5; u32 frequency_div; /* LO output divider switch frequency */ @@ -65,6 +66,7 @@ static int ts2020_release(struct dvb_frontend *fe) static int ts2020_sleep(struct dvb_frontend *fe) { struct ts2020_priv *priv = fe->tuner_priv; + int ret; u8 u8tmp; if (priv->tuner == TS2020_M88TS2020) @@ -72,11 +74,18 @@ static int ts2020_sleep(struct dvb_frontend *fe) else u8tmp = 0x00; - return regmap_write(priv->regmap, u8tmp, 0x00); + ret = regmap_write(priv->regmap, u8tmp, 0x00); + if (ret < 0) + return ret; + + /* stop statistics polling */ + cancel_delayed_work_sync(&priv->stat_work); + return 0; } static int ts2020_init(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct ts2020_priv *priv = fe->tuner_priv; int i; u8 u8tmp; @@ -138,6 +147,13 @@ static int ts2020_init(struct dvb_frontend *fe) reg_vals[i].val); } + /* Initialise v5 stats here */ + c->strength.len = 1; + c->strength.stat[0].scale = FE_SCALE_DECIBEL; + c->strength.stat[0].uvalue = 0; + + /* Start statistics polling */ + schedule_delayed_work(&priv->stat_work, 0); return 0; } @@ -410,20 +426,47 @@ static int ts2020_get_tuner_gain(struct dvb_frontend *fe, __s64 *_gain) return ts2020_read_tuner_gain(fe, v_agc, _gain); } +/* + * Gather statistics on a regular basis + */ +static void ts2020_stat_work(struct work_struct *work) +{ + struct ts2020_priv *priv = container_of(work, struct ts2020_priv, + stat_work.work); + struct i2c_client *client = priv->client; + struct dtv_frontend_properties *c = &priv->fe->dtv_property_cache; + int ret; + + dev_dbg(&client->dev, "\n"); + + ret = ts2020_get_tuner_gain(priv->fe, &c->strength.stat[0].svalue); + if (ret < 0) + goto err; + + c->strength.stat[0].scale = FE_SCALE_DECIBEL; + + schedule_delayed_work(&priv->stat_work, msecs_to_jiffies(2000)); + return; +err: + dev_dbg(&client->dev, "failed=%d\n", ret); +} + /* * Read TS2020 signal strength in v3 format. */ static int ts2020_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) + u16 *_signal_strength) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; unsigned strength; __s64 gain; - int ret; - /* Determine the total gain of the tuner */ - ret = ts2020_get_tuner_gain(fe, &gain); - if (ret < 0) - return ret; + if (c->strength.stat[0].scale == FE_SCALE_NOT_AVAILABLE) { + *_signal_strength = 0; + return 0; + } + + gain = c->strength.stat[0].svalue; /* Calculate the signal strength based on the total gain of the tuner */ if (gain < -85000) @@ -439,7 +482,7 @@ static int ts2020_read_signal_strength(struct dvb_frontend *fe, /* 90% - 99%: strong signal */ strength = 90 + (45000 + gain) / 5000; - *signal_strength = strength * 65535 / 100; + *_signal_strength = strength * 65535 / 100; return 0; } @@ -546,6 +589,7 @@ static int ts2020_probe(struct i2c_client *client, dev->get_agc_pwm = pdata->get_agc_pwm; fe->tuner_priv = dev; dev->client = client; + INIT_DELAYED_WORK(&dev->stat_work, ts2020_stat_work); /* check if the tuner is there */ ret = regmap_read(dev->regmap, 0x00, &utmp); -- cgit v1.2.3-59-g8ed1b From 0f20baad24f97c3390ae869661408bb3ee12764e Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 3 Jun 2015 08:34:13 -0300 Subject: [media] ts2020: Copy loop_through from the config to the internal data Copy the loop_through setting from the ts2020_config struct to the internal ts2020_priv struct so that it can actually be used. Whilst we're at it, group the bitfields together in the same order in both structs so that the compiler has a good chance to copy them in one go. Signed-off-by: David Howells Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/ts2020.c | 3 ++- drivers/media/dvb-frontends/ts2020.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c index 80ae0397b05c..8c997d064beb 100644 --- a/drivers/media/dvb-frontends/ts2020.c +++ b/drivers/media/dvb-frontends/ts2020.c @@ -37,6 +37,7 @@ struct ts2020_priv { /* i2c details */ struct i2c_adapter *i2c; int i2c_address; + bool loop_through:1; u8 clk_out:2; u8 clk_out_div:5; u32 frequency_div; /* LO output divider switch frequency */ @@ -44,7 +45,6 @@ struct ts2020_priv { #define TS2020_M88TS2020 0 #define TS2020_M88TS2022 1 u8 tuner; - u8 loop_through:1; }; struct ts2020_reg_val { @@ -582,6 +582,7 @@ static int ts2020_probe(struct i2c_client *client, dev->i2c = client->adapter; dev->i2c_address = client->addr; + dev->loop_through = pdata->loop_through; dev->clk_out = pdata->clk_out; dev->clk_out_div = pdata->clk_out_div; dev->frequency_div = pdata->frequency_div; diff --git a/drivers/media/dvb-frontends/ts2020.h b/drivers/media/dvb-frontends/ts2020.h index 37797244774d..002bc0ac1603 100644 --- a/drivers/media/dvb-frontends/ts2020.h +++ b/drivers/media/dvb-frontends/ts2020.h @@ -32,7 +32,7 @@ struct ts2020_config { /* * RF loop-through */ - u8 loop_through:1; + bool loop_through:1; /* * clock output -- cgit v1.2.3-59-g8ed1b From c7275ae16114bd6be4cb83ee02bf801c303a2225 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 3 Jun 2015 08:35:08 -0300 Subject: [media] ts2020: Allow stats polling to be suppressed Statistics polling can not be done by lmedm04 driver's implementation of M88RS2000/TS2020 because I2C messages stop the device's demuxer, so allow polling for statistics to be suppressed in the ts2020 driver by setting dont_poll in the ts2020_config struct. Reported-by: Malcolm Priestley Signed-off-by: David Howells cc: Malcolm Priestley Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/ts2020.c | 18 ++++++++++++++---- drivers/media/dvb-frontends/ts2020.h | 3 +++ 2 files changed, 17 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c index 8c997d064beb..946d8e9502fd 100644 --- a/drivers/media/dvb-frontends/ts2020.c +++ b/drivers/media/dvb-frontends/ts2020.c @@ -40,6 +40,7 @@ struct ts2020_priv { bool loop_through:1; u8 clk_out:2; u8 clk_out_div:5; + bool dont_poll:1; u32 frequency_div; /* LO output divider switch frequency */ u32 frequency_khz; /* actual used LO frequency */ #define TS2020_M88TS2020 0 @@ -52,6 +53,8 @@ struct ts2020_reg_val { u8 val; }; +static void ts2020_stat_work(struct work_struct *work); + static int ts2020_release(struct dvb_frontend *fe) { struct ts2020_priv *priv = fe->tuner_priv; @@ -79,7 +82,8 @@ static int ts2020_sleep(struct dvb_frontend *fe) return ret; /* stop statistics polling */ - cancel_delayed_work_sync(&priv->stat_work); + if (!priv->dont_poll) + cancel_delayed_work_sync(&priv->stat_work); return 0; } @@ -152,8 +156,8 @@ static int ts2020_init(struct dvb_frontend *fe) c->strength.stat[0].scale = FE_SCALE_DECIBEL; c->strength.stat[0].uvalue = 0; - /* Start statistics polling */ - schedule_delayed_work(&priv->stat_work, 0); + /* Start statistics polling by invoking the work function */ + ts2020_stat_work(&priv->stat_work.work); return 0; } @@ -445,7 +449,8 @@ static void ts2020_stat_work(struct work_struct *work) c->strength.stat[0].scale = FE_SCALE_DECIBEL; - schedule_delayed_work(&priv->stat_work, msecs_to_jiffies(2000)); + if (!priv->dont_poll) + schedule_delayed_work(&priv->stat_work, msecs_to_jiffies(2000)); return; err: dev_dbg(&client->dev, "failed=%d\n", ret); @@ -458,9 +463,13 @@ static int ts2020_read_signal_strength(struct dvb_frontend *fe, u16 *_signal_strength) { struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct ts2020_priv *priv = fe->tuner_priv; unsigned strength; __s64 gain; + if (priv->dont_poll) + ts2020_stat_work(&priv->stat_work.work); + if (c->strength.stat[0].scale == FE_SCALE_NOT_AVAILABLE) { *_signal_strength = 0; return 0; @@ -585,6 +594,7 @@ static int ts2020_probe(struct i2c_client *client, dev->loop_through = pdata->loop_through; dev->clk_out = pdata->clk_out; dev->clk_out_div = pdata->clk_out_div; + dev->dont_poll = pdata->dont_poll; dev->frequency_div = pdata->frequency_div; dev->fe = fe; dev->get_agc_pwm = pdata->get_agc_pwm; diff --git a/drivers/media/dvb-frontends/ts2020.h b/drivers/media/dvb-frontends/ts2020.h index 002bc0ac1603..9220e5cf0d21 100644 --- a/drivers/media/dvb-frontends/ts2020.h +++ b/drivers/media/dvb-frontends/ts2020.h @@ -48,6 +48,9 @@ struct ts2020_config { */ u8 clk_out_div:5; + /* Set to true to suppress stat polling */ + bool dont_poll:1; + /* * pointer to DVB frontend */ -- cgit v1.2.3-59-g8ed1b From 9e8715c91da5567518fcfc16721e01f974536e4a Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Fri, 5 Jun 2015 07:55:07 -0300 Subject: [media] lmedm04: Enable dont_poll for TS2020 tuner Following a change made to TS2020 tuner in patches ts2020: Provide DVBv5 API signal strength ts2020: Allow stats polling to be suppressed Polling on the driver must be suppressed because the demuxer is stopped by I2C messages. Signed-off-by: Malcolm Priestley Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/lmedm04.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c index 1b6ca42ad116..d37940774503 100644 --- a/drivers/media/usb/dvb-usb-v2/lmedm04.c +++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c @@ -799,6 +799,7 @@ static struct m88rs2000_config m88rs2000_config = { static struct ts2020_config ts2020_config = { .tuner_address = 0x60, .clk_out_div = 7, + .dont_poll = true }; static int dm04_lme2510_set_voltage(struct dvb_frontend *fe, -- cgit v1.2.3-59-g8ed1b From 555416f9878d2d1547765c1587b05e585c69096b Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Fri, 5 Jun 2015 22:53:27 -0300 Subject: [media] s5k5baf: Convert use of __constant_cpu_to_be16 to cpu_to_be16 In little endian cases, macro cpu_to_be16 unfolds to __swab16 which provides special case for constants. In big endian cases, __constant_cpu_to_be16 and cpu_to_be16 expand directly to the same expression. So, replace __constant_cpu_to_be16 with cpu_to_be16 with the goal of getting rid of the definition of __constant_cpu_to_be16 completely. The semantic patch that performs this transformation is as follows: @@expression x;@@ - __constant_cpu_to_be16(x) + cpu_to_be16(x) Signed-off-by: Vaishali Thakkar Reviewed-by: Andrzej Hajda Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/s5k5baf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index bee73de347dc..774e0d0c94cb 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -491,7 +491,7 @@ static void s5k5baf_write_arr_seq(struct s5k5baf *state, u16 addr, v4l2_dbg(3, debug, c, "i2c_write_seq(count=%d): %*ph\n", count, min(2 * count, 64), seq); - buf[0] = __constant_cpu_to_be16(REG_CMD_BUF); + buf[0] = cpu_to_be16(REG_CMD_BUF); while (count > 0) { int n = min_t(int, count, ARRAY_SIZE(buf) - 1); -- cgit v1.2.3-59-g8ed1b From d976872891f139f59cfcb4e47ca05fc2e90f3e43 Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Sat, 6 Jun 2015 04:44:57 -0300 Subject: [media] saa7164: change Si2168 reglen to 0 bit The i2c_reg_len for Si2168 should be 0 for correct I2C communication. Signed-off-by: Olli Salonen Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7164/saa7164-cards.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7164/saa7164-cards.c b/drivers/media/pci/saa7164/saa7164-cards.c index 8a6455d282c3..c2b738227f58 100644 --- a/drivers/media/pci/saa7164/saa7164-cards.c +++ b/drivers/media/pci/saa7164/saa7164-cards.c @@ -621,7 +621,7 @@ struct saa7164_board saa7164_boards[] = { .name = "SI2168-1", .i2c_bus_nr = SAA7164_I2C_BUS_2, .i2c_bus_addr = 0xc8 >> 1, - .i2c_reg_len = REGLEN_8bit, + .i2c_reg_len = REGLEN_0bit, }, { .id = 0x25, .type = SAA7164_UNIT_TUNER, @@ -635,7 +635,7 @@ struct saa7164_board saa7164_boards[] = { .name = "SI2168-2", .i2c_bus_nr = SAA7164_I2C_BUS_2, .i2c_bus_addr = 0xcc >> 1, - .i2c_reg_len = REGLEN_8bit, + .i2c_reg_len = REGLEN_0bit, } }, }, }; -- cgit v1.2.3-59-g8ed1b From 5dce1ee611e4acd0893c77611d25fe5b1594764a Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Sat, 6 Jun 2015 04:44:58 -0300 Subject: [media] saa7164: Improvements for I2C handling" This reverts commit ad90b6b0f10566d4a5546e27fe455ce3b5e6b6c7. This patch breaks I2C communication towards Si2168. After reverting and applying the other patch in this series the I2C communication is correct. Signed-off-by: Olli Salonen Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7164/saa7164-api.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7164/saa7164-api.c b/drivers/media/pci/saa7164/saa7164-api.c index e8077037fb5c..e7e586c1ba53 100644 --- a/drivers/media/pci/saa7164/saa7164-api.c +++ b/drivers/media/pci/saa7164/saa7164-api.c @@ -1385,8 +1385,7 @@ int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg, * 08... register address */ memset(buf, 0, sizeof(buf)); - if (reg) - memcpy((buf + 2 * sizeof(u32) + 0), reg, reglen); + memcpy((buf + 2 * sizeof(u32) + 0), reg, reglen); *((u32 *)(buf + 0 * sizeof(u32))) = reglen; *((u32 *)(buf + 1 * sizeof(u32))) = datalen; @@ -1475,14 +1474,6 @@ int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen, * 04-07 dest bytes to write * 08... register address */ - if (datalen == 1) { - /* Workaround for issues with i2c components - * that issue writes with no data. IE: SI2168/2157 - * Increase reglen by 1, strobe out an additional byte, - * ignored by SI2168/2157. - */ - datalen++; - } *((u32 *)(buf + 0 * sizeof(u32))) = reglen; *((u32 *)(buf + 1 * sizeof(u32))) = datalen - reglen; memcpy((buf + 2 * sizeof(u32)), data, datalen); -- cgit v1.2.3-59-g8ed1b From 8d7e506350a3ff1b0659f7f5d65115a9be5ae37e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 6 Jun 2015 13:55:22 -0300 Subject: [media] dvb-core: prevent some corruption the legacy ioctl Quite a few of the ->diseqc_send_master_cmd() implementations don't check cmd->msg_len so it can lead to memory corruption. Signed-off-by: Dan Carpenter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_frontend.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index b30ca59de04f..842b9c8f80c6 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -2384,7 +2384,13 @@ static int dvb_frontend_ioctl_legacy(struct file *file, case FE_DISEQC_SEND_MASTER_CMD: if (fe->ops.diseqc_send_master_cmd) { - err = fe->ops.diseqc_send_master_cmd(fe, (struct dvb_diseqc_master_cmd*) parg); + struct dvb_diseqc_master_cmd *cmd = parg; + + if (cmd->msg_len > sizeof(cmd->msg)) { + err = -EINVAL; + break; + } + err = fe->ops.diseqc_send_master_cmd(fe, cmd); fepriv->state = FESTATE_DISEQC; fepriv->status = 0; } -- cgit v1.2.3-59-g8ed1b From 9b6a065e797e525e94d949bba1abc257527b3f87 Mon Sep 17 00:00:00 2001 From: Jan Klötzke Date: Sat, 6 Jun 2015 16:58:09 -0300 Subject: [media] rc/keymaps: add RC keytable for TechniSat TS35 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The TS35 remote is distributed with TechniSat CableStar HD2 cards (mantis chipset). The exact protocol type is unknown, making this rc map probably only usable by mantis cards. Signed-off-by: Jan Klötzke Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/keymaps/Makefile | 1 + drivers/media/rc/keymaps/rc-technisat-ts35.c | 76 ++++++++++++++++++++++++++++ include/media/rc-map.h | 1 + 3 files changed, 78 insertions(+) create mode 100644 drivers/media/rc/keymaps/rc-technisat-ts35.c (limited to 'drivers/media') diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile index abf60794223d..07c4b9878366 100644 --- a/drivers/media/rc/keymaps/Makefile +++ b/drivers/media/rc/keymaps/Makefile @@ -84,6 +84,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ rc-snapstream-firefly.o \ rc-streamzap.o \ rc-tbs-nec.o \ + rc-technisat-ts35.o \ rc-technisat-usb2.o \ rc-terratec-cinergy-xs.o \ rc-terratec-slim.o \ diff --git a/drivers/media/rc/keymaps/rc-technisat-ts35.c b/drivers/media/rc/keymaps/rc-technisat-ts35.c new file mode 100644 index 000000000000..3328cbefabad --- /dev/null +++ b/drivers/media/rc/keymaps/rc-technisat-ts35.c @@ -0,0 +1,76 @@ +/* rc-technisat-ts35.c - Keytable for TechniSat TS35 remote + * + * Copyright (c) 2013 by Jan Klötzke + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + */ + +#include +#include + +static struct rc_map_table technisat_ts35[] = { + {0x32, KEY_MUTE}, + {0x07, KEY_MEDIA}, + {0x1c, KEY_AB}, + {0x33, KEY_POWER}, + + {0x3e, KEY_1}, + {0x3d, KEY_2}, + {0x3c, KEY_3}, + {0x3b, KEY_4}, + {0x3a, KEY_5}, + {0x39, KEY_6}, + {0x38, KEY_7}, + {0x37, KEY_8}, + {0x36, KEY_9}, + {0x3f, KEY_0}, + {0x35, KEY_DIGITS}, + {0x2c, KEY_TV}, + + {0x20, KEY_INFO}, + {0x2d, KEY_MENU}, + {0x1f, KEY_UP}, + {0x1e, KEY_DOWN}, + {0x2e, KEY_LEFT}, + {0x2f, KEY_RIGHT}, + {0x28, KEY_OK}, + {0x10, KEY_EPG}, + {0x1d, KEY_BACK}, + + {0x14, KEY_RED}, + {0x13, KEY_GREEN}, + {0x12, KEY_YELLOW}, + {0x11, KEY_BLUE}, + + {0x09, KEY_SELECT}, + {0x03, KEY_TEXT}, + {0x16, KEY_STOP}, + {0x30, KEY_HELP}, +}; + +static struct rc_map_list technisat_ts35_map = { + .map = { + .scan = technisat_ts35, + .size = ARRAY_SIZE(technisat_ts35), + .rc_type = RC_TYPE_UNKNOWN, + .name = RC_MAP_TECHNISAT_TS35, + } +}; + +static int __init init_rc_map(void) +{ + return rc_map_register(&technisat_ts35_map); +} + +static void __exit exit_rc_map(void) +{ + rc_map_unregister(&technisat_ts35_map); +} + +module_init(init_rc_map) +module_exit(exit_rc_map) + +MODULE_LICENSE("GPL"); diff --git a/include/media/rc-map.h b/include/media/rc-map.h index e7a1514075ec..aa56264d3050 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h @@ -194,6 +194,7 @@ void rc_map_init(void); #define RC_MAP_SNAPSTREAM_FIREFLY "rc-snapstream-firefly" #define RC_MAP_STREAMZAP "rc-streamzap" #define RC_MAP_TBS_NEC "rc-tbs-nec" +#define RC_MAP_TECHNISAT_TS35 "rc-technisat-ts35" #define RC_MAP_TECHNISAT_USB2 "rc-technisat-usb2" #define RC_MAP_TERRATEC_CINERGY_XS "rc-terratec-cinergy-xs" #define RC_MAP_TERRATEC_SLIM "rc-terratec-slim" -- cgit v1.2.3-59-g8ed1b From 4862690d82eec2d530bf78803009a1e3bb82be9a Mon Sep 17 00:00:00 2001 From: Jan Klötzke Date: Sat, 6 Jun 2015 16:58:10 -0300 Subject: [media] rc/keymaps: add keytable for Terratec Cinergy C PCI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This RC map was taken from Christoph Pinkl's patch (http://patchwork.linuxtv.org/patch/7217/). It is used solely by the respective mantis based card because the encoding is not known. Signed-off-by: Jan Klötzke Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/keymaps/Makefile | 1 + .../media/rc/keymaps/rc-terratec-cinergy-c-pci.c | 88 ++++++++++++++++++++++ include/media/rc-map.h | 1 + 3 files changed, 90 insertions(+) create mode 100644 drivers/media/rc/keymaps/rc-terratec-cinergy-c-pci.c (limited to 'drivers/media') diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile index 07c4b9878366..775f66301afa 100644 --- a/drivers/media/rc/keymaps/Makefile +++ b/drivers/media/rc/keymaps/Makefile @@ -86,6 +86,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ rc-tbs-nec.o \ rc-technisat-ts35.o \ rc-technisat-usb2.o \ + rc-terratec-cinergy-c-pci.o \ rc-terratec-cinergy-xs.o \ rc-terratec-slim.o \ rc-terratec-slim-2.o \ diff --git a/drivers/media/rc/keymaps/rc-terratec-cinergy-c-pci.c b/drivers/media/rc/keymaps/rc-terratec-cinergy-c-pci.c new file mode 100644 index 000000000000..7958f458527a --- /dev/null +++ b/drivers/media/rc/keymaps/rc-terratec-cinergy-c-pci.c @@ -0,0 +1,88 @@ +/* keytable for Terratec Cinergy C PCI Remote Controller + * + * Copyright (c) 2010 by Igor M. Liplianin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include + +static struct rc_map_table terratec_cinergy_c_pci[] = { + { 0x3e, KEY_POWER}, + { 0x3d, KEY_1}, + { 0x3c, KEY_2}, + { 0x3b, KEY_3}, + { 0x3a, KEY_4}, + { 0x39, KEY_5}, + { 0x38, KEY_6}, + { 0x37, KEY_7}, + { 0x36, KEY_8}, + { 0x35, KEY_9}, + { 0x34, KEY_VIDEO_NEXT}, /* AV */ + { 0x33, KEY_0}, + { 0x32, KEY_REFRESH}, + { 0x30, KEY_EPG}, + { 0x2f, KEY_UP}, + { 0x2e, KEY_LEFT}, + { 0x2d, KEY_OK}, + { 0x2c, KEY_RIGHT}, + { 0x2b, KEY_DOWN}, + { 0x29, KEY_INFO}, + { 0x28, KEY_RED}, + { 0x27, KEY_GREEN}, + { 0x26, KEY_YELLOW}, + { 0x25, KEY_BLUE}, + { 0x24, KEY_CHANNELUP}, + { 0x23, KEY_VOLUMEUP}, + { 0x22, KEY_MUTE}, + { 0x21, KEY_VOLUMEDOWN}, + { 0x20, KEY_CHANNELDOWN}, + { 0x1f, KEY_PAUSE}, + { 0x1e, KEY_HOME}, + { 0x1d, KEY_MENU}, /* DVD Menu */ + { 0x1c, KEY_SUBTITLE}, + { 0x1b, KEY_TEXT}, /* Teletext */ + { 0x1a, KEY_DELETE}, + { 0x19, KEY_TV}, + { 0x18, KEY_DVD}, + { 0x17, KEY_STOP}, + { 0x16, KEY_VIDEO}, + { 0x15, KEY_AUDIO}, /* Music */ + { 0x14, KEY_SCREEN}, /* Pic */ + { 0x13, KEY_PLAY}, + { 0x12, KEY_BACK}, + { 0x11, KEY_REWIND}, + { 0x10, KEY_FASTFORWARD}, + { 0x0b, KEY_PREVIOUS}, + { 0x07, KEY_RECORD}, + { 0x03, KEY_NEXT}, + +}; + +static struct rc_map_list terratec_cinergy_c_pci_map = { + .map = { + .scan = terratec_cinergy_c_pci, + .size = ARRAY_SIZE(terratec_cinergy_c_pci), + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_TERRATEC_CINERGY_C_PCI, + } +}; + +static int __init init_rc_map_terratec_cinergy_c_pci(void) +{ + return rc_map_register(&terratec_cinergy_c_pci_map); +} + +static void __exit exit_rc_map_terratec_cinergy_c_pci(void) +{ + rc_map_unregister(&terratec_cinergy_c_pci_map); +} + +module_init(init_rc_map_terratec_cinergy_c_pci); +module_exit(exit_rc_map_terratec_cinergy_c_pci); + +MODULE_LICENSE("GPL"); diff --git a/include/media/rc-map.h b/include/media/rc-map.h index aa56264d3050..9873a179df2e 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h @@ -196,6 +196,7 @@ void rc_map_init(void); #define RC_MAP_TBS_NEC "rc-tbs-nec" #define RC_MAP_TECHNISAT_TS35 "rc-technisat-ts35" #define RC_MAP_TECHNISAT_USB2 "rc-technisat-usb2" +#define RC_MAP_TERRATEC_CINERGY_C_PCI "rc-terratec-cinergy-c-pci" #define RC_MAP_TERRATEC_CINERGY_XS "rc-terratec-cinergy-xs" #define RC_MAP_TERRATEC_SLIM "rc-terratec-slim" #define RC_MAP_TERRATEC_SLIM_2 "rc-terratec-slim-2" -- cgit v1.2.3-59-g8ed1b From 578e95dd38b5b23be99b9899ddab480be4be9b2a Mon Sep 17 00:00:00 2001 From: Jan Klötzke Date: Sat, 6 Jun 2015 16:58:11 -0300 Subject: [media] rc/keymaps: add keytable for Terratec Cinergy S2 HD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This RC map was taken from Christoph Pinkl's patch (http://patchwork.linuxtv.org/patch/7217/). It is used solely by the respective mantis based card because the encoding is not known. Signed-off-by: Jan Klötzke Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/keymaps/Makefile | 1 + .../media/rc/keymaps/rc-terratec-cinergy-s2-hd.c | 86 ++++++++++++++++++++++ include/media/rc-map.h | 1 + 3 files changed, 88 insertions(+) create mode 100644 drivers/media/rc/keymaps/rc-terratec-cinergy-s2-hd.c (limited to 'drivers/media') diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile index 775f66301afa..f0c02c814b47 100644 --- a/drivers/media/rc/keymaps/Makefile +++ b/drivers/media/rc/keymaps/Makefile @@ -87,6 +87,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ rc-technisat-ts35.o \ rc-technisat-usb2.o \ rc-terratec-cinergy-c-pci.o \ + rc-terratec-cinergy-s2-hd.o \ rc-terratec-cinergy-xs.o \ rc-terratec-slim.o \ rc-terratec-slim-2.o \ diff --git a/drivers/media/rc/keymaps/rc-terratec-cinergy-s2-hd.c b/drivers/media/rc/keymaps/rc-terratec-cinergy-s2-hd.c new file mode 100644 index 000000000000..1e096bbda4a0 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-terratec-cinergy-s2-hd.c @@ -0,0 +1,86 @@ +/* keytable for Terratec Cinergy S2 HD Remote Controller + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include + +static struct rc_map_table terratec_cinergy_s2_hd[] = { + { 0x03, KEY_NEXT}, /* >| */ + { 0x07, KEY_RECORD}, + { 0x0b, KEY_PREVIOUS}, /* |< */ + { 0x10, KEY_FASTFORWARD}, /* >> */ + { 0x11, KEY_REWIND}, /* << */ + { 0x12, KEY_ESC}, /* Back */ + { 0x13, KEY_PLAY}, + { 0x14, KEY_IMAGES}, + { 0x15, KEY_AUDIO}, + { 0x16, KEY_MEDIA}, /* Video-Menu */ + { 0x17, KEY_STOP}, + { 0x18, KEY_DVD}, + { 0x19, KEY_TV}, + { 0x1a, KEY_DELETE}, + { 0x1b, KEY_TEXT}, + { 0x1c, KEY_SUBTITLE}, + { 0x1d, KEY_MENU}, /* DVD-Menu */ + { 0x1e, KEY_HOME}, + { 0x1f, KEY_PAUSE}, + { 0x20, KEY_CHANNELDOWN}, + { 0x21, KEY_VOLUMEDOWN}, + { 0x22, KEY_MUTE}, + { 0x23, KEY_VOLUMEUP}, + { 0x24, KEY_CHANNELUP}, + { 0x25, KEY_BLUE}, + { 0x26, KEY_YELLOW}, + { 0x27, KEY_GREEN}, + { 0x28, KEY_RED}, + { 0x29, KEY_INFO}, + { 0x2b, KEY_DOWN}, + { 0x2c, KEY_RIGHT}, + { 0x2d, KEY_OK}, + { 0x2e, KEY_LEFT}, + { 0x2f, KEY_UP}, + { 0x30, KEY_EPG}, + { 0x32, KEY_VIDEO}, /* A<=>B */ + { 0x33, KEY_0}, + { 0x34, KEY_VCR}, /* AV */ + { 0x35, KEY_9}, + { 0x36, KEY_8}, + { 0x37, KEY_7}, + { 0x38, KEY_6}, + { 0x39, KEY_5}, + { 0x3a, KEY_4}, + { 0x3b, KEY_3}, + { 0x3c, KEY_2}, + { 0x3d, KEY_1}, + { 0x3e, KEY_POWER}, + +}; + +static struct rc_map_list terratec_cinergy_s2_hd_map = { + .map = { + .scan = terratec_cinergy_s2_hd, + .size = ARRAY_SIZE(terratec_cinergy_s2_hd), + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_TERRATEC_CINERGY_S2_HD, + } +}; + +static int __init init_rc_map_terratec_cinergy_s2_hd(void) +{ + return rc_map_register(&terratec_cinergy_s2_hd_map); +} + +static void __exit exit_rc_map_terratec_cinergy_s2_hd(void) +{ + rc_map_unregister(&terratec_cinergy_s2_hd_map); +} + +module_init(init_rc_map_terratec_cinergy_s2_hd); +module_exit(exit_rc_map_terratec_cinergy_s2_hd); + +MODULE_LICENSE("GPL"); diff --git a/include/media/rc-map.h b/include/media/rc-map.h index 9873a179df2e..50ed644df118 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h @@ -197,6 +197,7 @@ void rc_map_init(void); #define RC_MAP_TECHNISAT_TS35 "rc-technisat-ts35" #define RC_MAP_TECHNISAT_USB2 "rc-technisat-usb2" #define RC_MAP_TERRATEC_CINERGY_C_PCI "rc-terratec-cinergy-c-pci" +#define RC_MAP_TERRATEC_CINERGY_S2_HD "rc-terratec-cinergy-s2-hd" #define RC_MAP_TERRATEC_CINERGY_XS "rc-terratec-cinergy-xs" #define RC_MAP_TERRATEC_SLIM "rc-terratec-slim" #define RC_MAP_TERRATEC_SLIM_2 "rc-terratec-slim-2" -- cgit v1.2.3-59-g8ed1b From 1c35cf9ccac5cf32cd865e6a62dfd16dd50ad5dd Mon Sep 17 00:00:00 2001 From: Jan Klötzke Date: Sat, 6 Jun 2015 16:58:12 -0300 Subject: [media] rc/keymaps: add keytable for Twinhan DTV CAB CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This RC map was taken from Christoph Pinkl's patch (http://patchwork.linuxtv.org/patch/7217/). It is used solely by the respective mantis based card because the encoding is not known. Signed-off-by: Jan Klötzke Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/keymaps/Makefile | 1 + drivers/media/rc/keymaps/rc-twinhan-dtv-cab-ci.c | 98 ++++++++++++++++++++++++ include/media/rc-map.h | 1 + 3 files changed, 100 insertions(+) create mode 100644 drivers/media/rc/keymaps/rc-twinhan-dtv-cab-ci.c (limited to 'drivers/media') diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile index f0c02c814b47..fbbd3bbcd252 100644 --- a/drivers/media/rc/keymaps/Makefile +++ b/drivers/media/rc/keymaps/Makefile @@ -97,6 +97,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ rc-total-media-in-hand-02.o \ rc-trekstor.o \ rc-tt-1500.o \ + rc-twinhan-dtv-cab-ci.o \ rc-twinhan1027.o \ rc-videomate-m1f.o \ rc-videomate-s350.o \ diff --git a/drivers/media/rc/keymaps/rc-twinhan-dtv-cab-ci.c b/drivers/media/rc/keymaps/rc-twinhan-dtv-cab-ci.c new file mode 100644 index 000000000000..202500cb3061 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-twinhan-dtv-cab-ci.c @@ -0,0 +1,98 @@ +/* keytable for Twinhan DTV CAB CI Remote Controller + * + * Copyright (c) 2010 by Igor M. Liplianin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include + +static struct rc_map_table twinhan_dtv_cab_ci[] = { + { 0x29, KEY_POWER}, + { 0x28, KEY_FAVORITES}, + { 0x30, KEY_TEXT}, + { 0x17, KEY_INFO}, /* Preview */ + { 0x23, KEY_EPG}, + { 0x3b, KEY_F22}, /* Record List */ + + { 0x3c, KEY_1}, + { 0x3e, KEY_2}, + { 0x39, KEY_3}, + { 0x36, KEY_4}, + { 0x22, KEY_5}, + { 0x20, KEY_6}, + { 0x32, KEY_7}, + { 0x26, KEY_8}, + { 0x24, KEY_9}, + { 0x2a, KEY_0}, + + { 0x33, KEY_CANCEL}, + { 0x2c, KEY_BACK}, + { 0x15, KEY_CLEAR}, + { 0x3f, KEY_TAB}, + { 0x10, KEY_ENTER}, + { 0x14, KEY_UP}, + { 0x0d, KEY_RIGHT}, + { 0x0e, KEY_DOWN}, + { 0x11, KEY_LEFT}, + + { 0x21, KEY_VOLUMEUP}, + { 0x35, KEY_VOLUMEDOWN}, + { 0x3d, KEY_CHANNELDOWN}, + { 0x3a, KEY_CHANNELUP}, + { 0x2e, KEY_RECORD}, + { 0x2b, KEY_PLAY}, + { 0x13, KEY_PAUSE}, + { 0x25, KEY_STOP}, + + { 0x1f, KEY_REWIND}, + { 0x2d, KEY_FASTFORWARD}, + { 0x1e, KEY_PREVIOUS}, /* Replay |< */ + { 0x1d, KEY_NEXT}, /* Skip >| */ + + { 0x0b, KEY_CAMERA}, /* Capture */ + { 0x0f, KEY_LANGUAGE}, /* SAP */ + { 0x18, KEY_MODE}, /* PIP */ + { 0x12, KEY_ZOOM}, /* Full screen */ + { 0x1c, KEY_SUBTITLE}, + { 0x2f, KEY_MUTE}, + { 0x16, KEY_F20}, /* L/R */ + { 0x38, KEY_F21}, /* Hibernate */ + + { 0x37, KEY_SWITCHVIDEOMODE}, /* A/V */ + { 0x31, KEY_AGAIN}, /* Recall */ + { 0x1a, KEY_KPPLUS}, /* Zoom+ */ + { 0x19, KEY_KPMINUS}, /* Zoom- */ + { 0x27, KEY_RED}, + { 0x0C, KEY_GREEN}, + { 0x01, KEY_YELLOW}, + { 0x00, KEY_BLUE}, +}; + +static struct rc_map_list twinhan_dtv_cab_ci_map = { + .map = { + .scan = twinhan_dtv_cab_ci, + .size = ARRAY_SIZE(twinhan_dtv_cab_ci), + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_TWINHAN_DTV_CAB_CI, + } +}; + +static int __init init_rc_map_twinhan_dtv_cab_ci(void) +{ + return rc_map_register(&twinhan_dtv_cab_ci_map); +} + +static void __exit exit_rc_map_twinhan_dtv_cab_ci(void) +{ + rc_map_unregister(&twinhan_dtv_cab_ci_map); +} + +module_init(init_rc_map_twinhan_dtv_cab_ci); +module_exit(exit_rc_map_twinhan_dtv_cab_ci); + +MODULE_LICENSE("GPL"); diff --git a/include/media/rc-map.h b/include/media/rc-map.h index 50ed644df118..27763d5bd261 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h @@ -207,6 +207,7 @@ void rc_map_init(void); #define RC_MAP_TOTAL_MEDIA_IN_HAND_02 "rc-total-media-in-hand-02" #define RC_MAP_TREKSTOR "rc-trekstor" #define RC_MAP_TT_1500 "rc-tt-1500" +#define RC_MAP_TWINHAN_DTV_CAB_CI "rc-twinhan-dtv-cab-ci" #define RC_MAP_TWINHAN_VP1027_DVBS "rc-twinhan1027" #define RC_MAP_VIDEOMATE_K100 "rc-videomate-k100" #define RC_MAP_VIDEOMATE_S350 "rc-videomate-s350" -- cgit v1.2.3-59-g8ed1b From a96762da0cfcbe27f18febb84797269cd9faf791 Mon Sep 17 00:00:00 2001 From: Jan Klötzke Date: Sat, 6 Jun 2015 16:58:13 -0300 Subject: [media] mantis: add remote control support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The embedded UART is apparently used to receive decoded IR (RC5?) codes. Forward these scan codes to the RC framework and (where known) add corresponding mapping tables to translate them into regular keys. This patch has been tested on a TechniSat CableStar HD2. The mappings of other rc-maps were taken from Christoph Pinkl's patch (http://patchwork.linuxtv.org/patch/7217/) and the s2-liplianin repository. The major difference to Christoph's patch is a reworked interrupt handling of the UART because the RX interrupt is apparently level triggered and requires masking until the FIFO is read by the UART worker. Signed-off-by: Jan Klötzke Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/mantis/hopper_cards.c | 13 +++- drivers/media/pci/mantis/mantis_cards.c | 57 +++++++++++++---- drivers/media/pci/mantis/mantis_common.h | 33 ++++++++-- drivers/media/pci/mantis/mantis_dma.c | 5 +- drivers/media/pci/mantis/mantis_i2c.c | 8 +-- drivers/media/pci/mantis/mantis_input.c | 106 +++++-------------------------- drivers/media/pci/mantis/mantis_input.h | 28 ++++++++ drivers/media/pci/mantis/mantis_pcmcia.c | 4 +- drivers/media/pci/mantis/mantis_uart.c | 62 +++++++++--------- 9 files changed, 166 insertions(+), 150 deletions(-) create mode 100644 drivers/media/pci/mantis/mantis_input.h (limited to 'drivers/media') diff --git a/drivers/media/pci/mantis/hopper_cards.c b/drivers/media/pci/mantis/hopper_cards.c index 104914a5bf06..97b7a3220dbd 100644 --- a/drivers/media/pci/mantis/hopper_cards.c +++ b/drivers/media/pci/mantis/hopper_cards.c @@ -106,6 +106,9 @@ static irqreturn_t hopper_irq_handler(int irq, void *dev_id) } if (stat & MANTIS_INT_IRQ1) { dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]); + spin_lock(&mantis->intmask_lock); + mmwrite(mmread(MANTIS_INT_MASK) & ~MANTIS_INT_IRQ1, MANTIS_INT_MASK); + spin_unlock(&mantis->intmask_lock); schedule_work(&mantis->uart_work); } if (stat & MANTIS_INT_OCERR) { @@ -154,6 +157,7 @@ static irqreturn_t hopper_irq_handler(int irq, void *dev_id) static int hopper_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) { + struct mantis_pci_drvdata *drvdata; struct mantis_pci *mantis; struct mantis_hwconfig *config; int err = 0; @@ -165,12 +169,16 @@ static int hopper_pci_probe(struct pci_dev *pdev, goto fail0; } + drvdata = (struct mantis_pci_drvdata *) pci_id->driver_data; mantis->num = devs; mantis->verbose = verbose; mantis->pdev = pdev; - config = (struct mantis_hwconfig *) pci_id->driver_data; + config = drvdata->hwconfig; config->irq_handler = &hopper_irq_handler; mantis->hwconfig = config; + mantis->rc_map_name = drvdata->rc_map_name; + + spin_lock_init(&mantis->intmask_lock); err = mantis_pci_init(mantis); if (err) { @@ -247,7 +255,8 @@ static void hopper_pci_remove(struct pci_dev *pdev) } static struct pci_device_id hopper_pci_table[] = { - MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3028_DVB_T, &vp3028_config), + MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3028_DVB_T, &vp3028_config, + NULL), { } }; diff --git a/drivers/media/pci/mantis/mantis_cards.c b/drivers/media/pci/mantis/mantis_cards.c index 9861a8cf1dce..6b64bfd938b6 100644 --- a/drivers/media/pci/mantis/mantis_cards.c +++ b/drivers/media/pci/mantis/mantis_cards.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "dmxdev.h" #include "dvbdev.h" @@ -49,6 +50,7 @@ #include "mantis_pci.h" #include "mantis_i2c.h" #include "mantis_reg.h" +#include "mantis_input.h" static unsigned int verbose; module_param(verbose, int, 0644); @@ -114,6 +116,9 @@ static irqreturn_t mantis_irq_handler(int irq, void *dev_id) } if (stat & MANTIS_INT_IRQ1) { dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]); + spin_lock(&mantis->intmask_lock); + mmwrite(mmread(MANTIS_INT_MASK) & ~MANTIS_INT_IRQ1, MANTIS_INT_MASK); + spin_unlock(&mantis->intmask_lock); schedule_work(&mantis->uart_work); } if (stat & MANTIS_INT_OCERR) { @@ -162,6 +167,7 @@ static irqreturn_t mantis_irq_handler(int irq, void *dev_id) static int mantis_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) { + struct mantis_pci_drvdata *drvdata; struct mantis_pci *mantis; struct mantis_hwconfig *config; int err = 0; @@ -172,12 +178,16 @@ static int mantis_pci_probe(struct pci_dev *pdev, return -ENOMEM; } + drvdata = (struct mantis_pci_drvdata *) pci_id->driver_data; mantis->num = devs; mantis->verbose = verbose; mantis->pdev = pdev; - config = (struct mantis_hwconfig *) pci_id->driver_data; + config = drvdata->hwconfig; config->irq_handler = &mantis_irq_handler; mantis->hwconfig = config; + mantis->rc_map_name = drvdata->rc_map_name; + + spin_lock_init(&mantis->intmask_lock); err = mantis_pci_init(mantis); if (err) { @@ -215,16 +225,25 @@ static int mantis_pci_probe(struct pci_dev *pdev, goto err_dma_exit; } + err = mantis_input_init(mantis); + if (err < 0) { + dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err); + goto err_dvb_exit; + } + err = mantis_uart_init(mantis); if (err < 0) { dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART initialization failed <%d>", err); - goto err_dvb_exit; + goto err_input_exit; } devs++; return 0; +err_input_exit: + mantis_input_exit(mantis); + err_dvb_exit: mantis_dvb_exit(mantis); @@ -250,6 +269,7 @@ static void mantis_pci_remove(struct pci_dev *pdev) if (mantis) { mantis_uart_exit(mantis); + mantis_input_exit(mantis); mantis_dvb_exit(mantis); mantis_dma_exit(mantis); mantis_i2c_exit(mantis); @@ -260,17 +280,28 @@ static void mantis_pci_remove(struct pci_dev *pdev) } static struct pci_device_id mantis_pci_table[] = { - MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1033_DVB_S, &vp1033_config), - MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1034_DVB_S, &vp1034_config), - MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1041_DVB_S2, &vp1041_config), - MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_10, &vp1041_config), - MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_20, &vp1041_config), - MAKE_ENTRY(TERRATEC, CINERGY_S2_PCI_HD, &vp1041_config), - MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2033_DVB_C, &vp2033_config), - MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2040_DVB_C, &vp2040_config), - MAKE_ENTRY(TECHNISAT, CABLESTAR_HD2, &vp2040_config), - MAKE_ENTRY(TERRATEC, CINERGY_C, &vp2040_config), - MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3030_DVB_T, &vp3030_config), + MAKE_ENTRY(TECHNISAT, CABLESTAR_HD2, &vp2040_config, + RC_MAP_TECHNISAT_TS35), + MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_10, &vp1041_config, + NULL), + MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_20, &vp1041_config, + NULL), + MAKE_ENTRY(TERRATEC, CINERGY_C, &vp2040_config, + RC_MAP_TERRATEC_CINERGY_C_PCI), + MAKE_ENTRY(TERRATEC, CINERGY_S2_PCI_HD, &vp1041_config, + RC_MAP_TERRATEC_CINERGY_S2_HD), + MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1033_DVB_S, &vp1033_config, + NULL), + MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1034_DVB_S, &vp1034_config, + NULL), + MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1041_DVB_S2, &vp1041_config, + RC_MAP_TWINHAN_DTV_CAB_CI), + MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2033_DVB_C, &vp2033_config, + RC_MAP_TWINHAN_DTV_CAB_CI), + MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2040_DVB_C, &vp2040_config, + NULL), + MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3030_DVB_T, &vp3030_config, + NULL), { } }; diff --git a/drivers/media/pci/mantis/mantis_common.h b/drivers/media/pci/mantis/mantis_common.h index 8ff448bb792d..d48778a366a9 100644 --- a/drivers/media/pci/mantis/mantis_common.h +++ b/drivers/media/pci/mantis/mantis_common.h @@ -25,6 +25,7 @@ #include #include +#include "mantis_reg.h" #include "mantis_uart.h" #include "mantis_link.h" @@ -68,12 +69,13 @@ #define TECHNISAT 0x1ae4 #define TERRATEC 0x153b -#define MAKE_ENTRY(__subven, __subdev, __configptr) { \ +#define MAKE_ENTRY(__subven, __subdev, __configptr, __rc) { \ .vendor = TWINHAN_TECHNOLOGIES, \ .device = MANTIS, \ .subvendor = (__subven), \ .subdevice = (__subdev), \ - .driver_data = (unsigned long) (__configptr) \ + .driver_data = (unsigned long) \ + &(struct mantis_pci_drvdata){__configptr, __rc} \ } enum mantis_i2c_mode { @@ -101,6 +103,11 @@ struct mantis_hwconfig { enum mantis_i2c_mode i2c_mode; }; +struct mantis_pci_drvdata { + struct mantis_hwconfig *hwconfig; + char *rc_map_name; +}; + struct mantis_pci { unsigned int verbose; @@ -131,6 +138,7 @@ struct mantis_pci { dma_addr_t risc_dma; struct tasklet_struct tasklet; + spinlock_t intmask_lock; struct i2c_adapter adapter; int i2c_rc; @@ -165,15 +173,32 @@ struct mantis_pci { struct mantis_ca *mantis_ca; - wait_queue_head_t uart_wq; struct work_struct uart_work; - spinlock_t uart_lock; struct rc_dev *rc; char input_name[80]; char input_phys[80]; + char *rc_map_name; }; #define MANTIS_HIF_STATUS (mantis->gpio_status) +static inline void mantis_mask_ints(struct mantis_pci *mantis, u32 mask) +{ + unsigned long flags; + + spin_lock_irqsave(&mantis->intmask_lock, flags); + mmwrite(mmread(MANTIS_INT_MASK) & ~mask, MANTIS_INT_MASK); + spin_unlock_irqrestore(&mantis->intmask_lock, flags); +} + +static inline void mantis_unmask_ints(struct mantis_pci *mantis, u32 mask) +{ + unsigned long flags; + + spin_lock_irqsave(&mantis->intmask_lock, flags); + mmwrite(mmread(MANTIS_INT_MASK) | mask, MANTIS_INT_MASK); + spin_unlock_irqrestore(&mantis->intmask_lock, flags); +} + #endif /* __MANTIS_COMMON_H */ diff --git a/drivers/media/pci/mantis/mantis_dma.c b/drivers/media/pci/mantis/mantis_dma.c index 566c407175a4..1d59c7e039f7 100644 --- a/drivers/media/pci/mantis/mantis_dma.c +++ b/drivers/media/pci/mantis/mantis_dma.c @@ -190,7 +190,7 @@ void mantis_dma_start(struct mantis_pci *mantis) mmwrite(0, MANTIS_DMA_CTL); mantis->last_block = mantis->busy_block = 0; - mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_RISCI, MANTIS_INT_MASK); + mantis_unmask_ints(mantis, MANTIS_INT_RISCI); mmwrite(MANTIS_FIFO_EN | MANTIS_DCAP_EN | MANTIS_RISC_EN, MANTIS_DMA_CTL); @@ -209,8 +209,7 @@ void mantis_dma_stop(struct mantis_pci *mantis) mmwrite(mmread(MANTIS_INT_STAT), MANTIS_INT_STAT); - mmwrite(mmread(MANTIS_INT_MASK) & ~(MANTIS_INT_RISCI | - MANTIS_INT_RISCEN), MANTIS_INT_MASK); + mantis_mask_ints(mantis, MANTIS_INT_RISCI | MANTIS_INT_RISCEN); } diff --git a/drivers/media/pci/mantis/mantis_i2c.c b/drivers/media/pci/mantis/mantis_i2c.c index 895ddba3c0fb..a93823490a43 100644 --- a/drivers/media/pci/mantis/mantis_i2c.c +++ b/drivers/media/pci/mantis/mantis_i2c.c @@ -245,8 +245,7 @@ int mantis_i2c_init(struct mantis_pci *mantis) intmask = mmread(MANTIS_INT_MASK); mmwrite(intstat, MANTIS_INT_STAT); dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt"); - intmask = mmread(MANTIS_INT_MASK); - mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK); + mantis_mask_ints(mantis, MANTIS_INT_I2CDONE); return 0; } @@ -254,11 +253,8 @@ EXPORT_SYMBOL_GPL(mantis_i2c_init); int mantis_i2c_exit(struct mantis_pci *mantis) { - u32 intmask; - dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt"); - intmask = mmread(MANTIS_INT_MASK); - mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK); + mantis_mask_ints(mantis, MANTIS_INT_I2CDONE); dprintk(MANTIS_DEBUG, 1, "Removing I2C adapter"); i2c_del_adapter(&mantis->adapter); diff --git a/drivers/media/pci/mantis/mantis_input.c b/drivers/media/pci/mantis/mantis_input.c index 0e5252e5c0ef..abf0ddfef0cb 100644 --- a/drivers/media/pci/mantis/mantis_input.c +++ b/drivers/media/pci/mantis/mantis_input.c @@ -18,8 +18,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#if 0 /* Currently unused */ - #include #include @@ -30,100 +28,32 @@ #include "dvb_net.h" #include "mantis_common.h" -#include "mantis_reg.h" -#include "mantis_uart.h" +#include "mantis_input.h" #define MODULE_NAME "mantis_core" -#define RC_MAP_MANTIS "rc-mantis" - -static struct rc_map_table mantis_ir_table[] = { - { 0x29, KEY_POWER }, - { 0x28, KEY_FAVORITES }, - { 0x30, KEY_TEXT }, - { 0x17, KEY_INFO }, /* Preview */ - { 0x23, KEY_EPG }, - { 0x3b, KEY_F22 }, /* Record List */ - { 0x3c, KEY_1 }, - { 0x3e, KEY_2 }, - { 0x39, KEY_3 }, - { 0x36, KEY_4 }, - { 0x22, KEY_5 }, - { 0x20, KEY_6 }, - { 0x32, KEY_7 }, - { 0x26, KEY_8 }, - { 0x24, KEY_9 }, - { 0x2a, KEY_0 }, - - { 0x33, KEY_CANCEL }, - { 0x2c, KEY_BACK }, - { 0x15, KEY_CLEAR }, - { 0x3f, KEY_TAB }, - { 0x10, KEY_ENTER }, - { 0x14, KEY_UP }, - { 0x0d, KEY_RIGHT }, - { 0x0e, KEY_DOWN }, - { 0x11, KEY_LEFT }, - - { 0x21, KEY_VOLUMEUP }, - { 0x35, KEY_VOLUMEDOWN }, - { 0x3d, KEY_CHANNELDOWN }, - { 0x3a, KEY_CHANNELUP }, - { 0x2e, KEY_RECORD }, - { 0x2b, KEY_PLAY }, - { 0x13, KEY_PAUSE }, - { 0x25, KEY_STOP }, - - { 0x1f, KEY_REWIND }, - { 0x2d, KEY_FASTFORWARD }, - { 0x1e, KEY_PREVIOUS }, /* Replay |< */ - { 0x1d, KEY_NEXT }, /* Skip >| */ - - { 0x0b, KEY_CAMERA }, /* Capture */ - { 0x0f, KEY_LANGUAGE }, /* SAP */ - { 0x18, KEY_MODE }, /* PIP */ - { 0x12, KEY_ZOOM }, /* Full screen */ - { 0x1c, KEY_SUBTITLE }, - { 0x2f, KEY_MUTE }, - { 0x16, KEY_F20 }, /* L/R */ - { 0x38, KEY_F21 }, /* Hibernate */ - - { 0x37, KEY_SWITCHVIDEOMODE }, /* A/V */ - { 0x31, KEY_AGAIN }, /* Recall */ - { 0x1a, KEY_KPPLUS }, /* Zoom+ */ - { 0x19, KEY_KPMINUS }, /* Zoom- */ - { 0x27, KEY_RED }, - { 0x0C, KEY_GREEN }, - { 0x01, KEY_YELLOW }, - { 0x00, KEY_BLUE }, -}; - -static struct rc_map_list ir_mantis_map = { - .map = { - .scan = mantis_ir_table, - .size = ARRAY_SIZE(mantis_ir_table), - .rc_type = RC_TYPE_UNKNOWN, - .name = RC_MAP_MANTIS, - } -}; + +void mantis_input_process(struct mantis_pci *mantis, int scancode) +{ + if (mantis->rc) + rc_keydown(mantis->rc, RC_TYPE_UNKNOWN, scancode, 0); +} int mantis_input_init(struct mantis_pci *mantis) { struct rc_dev *dev; int err; - err = rc_map_register(&ir_mantis_map); - if (err) - goto out; - dev = rc_allocate_device(); if (!dev) { dprintk(MANTIS_ERROR, 1, "Remote device allocation failed"); err = -ENOMEM; - goto out_map; + goto out; } - sprintf(mantis->input_name, "Mantis %s IR receiver", mantis->hwconfig->model_name); - sprintf(mantis->input_phys, "pci-%s/ir0", pci_name(mantis->pdev)); + snprintf(mantis->input_name, sizeof(mantis->input_name), + "Mantis %s IR receiver", mantis->hwconfig->model_name); + snprintf(mantis->input_phys, sizeof(mantis->input_phys), + "pci-%s/ir0", pci_name(mantis->pdev)); dev->input_name = mantis->input_name; dev->input_phys = mantis->input_phys; @@ -132,7 +62,7 @@ int mantis_input_init(struct mantis_pci *mantis) dev->input_id.product = mantis->device_id; dev->input_id.version = 1; dev->driver_name = MODULE_NAME; - dev->map_name = RC_MAP_MANTIS; + dev->map_name = mantis->rc_map_name ? : RC_MAP_EMPTY; dev->dev.parent = &mantis->pdev->dev; err = rc_register_device(dev); @@ -146,17 +76,13 @@ int mantis_input_init(struct mantis_pci *mantis) out_dev: rc_free_device(dev); -out_map: - rc_map_unregister(&ir_mantis_map); out: return err; } +EXPORT_SYMBOL_GPL(mantis_input_init); -int mantis_init_exit(struct mantis_pci *mantis) +void mantis_input_exit(struct mantis_pci *mantis) { rc_unregister_device(mantis->rc); - rc_map_unregister(&ir_mantis_map); - return 0; } - -#endif +EXPORT_SYMBOL_GPL(mantis_input_exit); diff --git a/drivers/media/pci/mantis/mantis_input.h b/drivers/media/pci/mantis/mantis_input.h new file mode 100644 index 000000000000..3bbde8b11ce1 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_input.h @@ -0,0 +1,28 @@ +/* + Mantis PCI bridge driver + + Copyright (C) Manu Abraham (abraham.manu@gmail.com) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __MANTIS_INPUT_H +#define __MANTIS_INPUT_H + +extern int mantis_input_init(struct mantis_pci *mantis); +extern void mantis_input_exit(struct mantis_pci *mantis); +extern void mantis_input_process(struct mantis_pci *mantis, int scancode); + +#endif /* __MANTIS_UART_H */ diff --git a/drivers/media/pci/mantis/mantis_pcmcia.c b/drivers/media/pci/mantis/mantis_pcmcia.c index 2f188c089666..b2dbc7b2e0f6 100644 --- a/drivers/media/pci/mantis/mantis_pcmcia.c +++ b/drivers/media/pci/mantis/mantis_pcmcia.c @@ -89,7 +89,7 @@ int mantis_pcmcia_init(struct mantis_ca *ca) u32 gpif_stat, card_stat; - mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_IRQ0, MANTIS_INT_MASK); + mantis_unmask_ints(mantis, MANTIS_INT_IRQ0); gpif_stat = mmread(MANTIS_GPIF_STATUS); card_stat = mmread(MANTIS_GPIF_IRQCFG); @@ -117,5 +117,5 @@ void mantis_pcmcia_exit(struct mantis_ca *ca) struct mantis_pci *mantis = ca->ca_priv; mmwrite(mmread(MANTIS_GPIF_STATUS) & (~MANTIS_CARD_PLUGOUT | ~MANTIS_CARD_PLUGIN), MANTIS_GPIF_STATUS); - mmwrite(mmread(MANTIS_INT_MASK) & ~MANTIS_INT_IRQ0, MANTIS_INT_MASK); + mantis_mask_ints(mantis, MANTIS_INT_IRQ0); } diff --git a/drivers/media/pci/mantis/mantis_uart.c b/drivers/media/pci/mantis/mantis_uart.c index a70719218631..483410948995 100644 --- a/drivers/media/pci/mantis/mantis_uart.c +++ b/drivers/media/pci/mantis/mantis_uart.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "dmxdev.h" #include "dvbdev.h" @@ -35,6 +36,7 @@ #include "mantis_common.h" #include "mantis_reg.h" #include "mantis_uart.h" +#include "mantis_input.h" struct mantis_uart_params { enum mantis_baud baud_rate; @@ -59,51 +61,53 @@ static struct { { "EVEN" } }; -#define UART_MAX_BUF 16 - -static int mantis_uart_read(struct mantis_pci *mantis, u8 *data) +static void mantis_uart_read(struct mantis_pci *mantis) { struct mantis_hwconfig *config = mantis->hwconfig; - u32 stat = 0, i; + int i, scancode = 0, err = 0; /* get data */ + dprintk(MANTIS_DEBUG, 1, "UART Reading ..."); for (i = 0; i < (config->bytes + 1); i++) { + int data = mmread(MANTIS_UART_RXD); + dprintk(MANTIS_DEBUG, 0, " <%02x>", data); - stat = mmread(MANTIS_UART_STAT); - - if (stat & MANTIS_UART_RXFIFO_FULL) { - dprintk(MANTIS_ERROR, 1, "RX Fifo FULL"); - } - data[i] = mmread(MANTIS_UART_RXD) & 0x3f; - - dprintk(MANTIS_DEBUG, 1, "Reading ... <%02x>", data[i] & 0x3f); + scancode = (scancode << 8) | (data & 0x3f); + err |= data; - if (data[i] & (1 << 7)) { + if (data & (1 << 7)) dprintk(MANTIS_ERROR, 1, "UART framing error"); - return -EINVAL; - } - if (data[i] & (1 << 6)) { + + if (data & (1 << 6)) dprintk(MANTIS_ERROR, 1, "UART parity error"); - return -EINVAL; - } } + dprintk(MANTIS_DEBUG, 0, "\n"); - return 0; + if ((err & 0xC0) == 0) + mantis_input_process(mantis, scancode); } static void mantis_uart_work(struct work_struct *work) { struct mantis_pci *mantis = container_of(work, struct mantis_pci, uart_work); - struct mantis_hwconfig *config = mantis->hwconfig; - u8 buf[16]; - int i; + u32 stat; - mantis_uart_read(mantis, buf); + stat = mmread(MANTIS_UART_STAT); - for (i = 0; i < (config->bytes + 1); i++) - dprintk(MANTIS_INFO, 1, "UART BUF:%d <%02x> ", i, buf[i]); + if (stat & MANTIS_UART_RXFIFO_FULL) + dprintk(MANTIS_ERROR, 1, "RX Fifo FULL"); - dprintk(MANTIS_DEBUG, 0, "\n"); + /* + * MANTIS_UART_RXFIFO_DATA is only set if at least config->bytes + 1 bytes + * are in the FIFO. + */ + while (stat & MANTIS_UART_RXFIFO_DATA) { + mantis_uart_read(mantis); + stat = mmread(MANTIS_UART_STAT); + } + + /* re-enable UART (RX) interrupt */ + mantis_unmask_ints(mantis, MANTIS_INT_IRQ1); } static int mantis_uart_setup(struct mantis_pci *mantis, @@ -152,9 +156,6 @@ int mantis_uart_init(struct mantis_pci *mantis) rates[params.baud_rate].string, parity[params.parity].string); - init_waitqueue_head(&mantis->uart_wq); - spin_lock_init(&mantis->uart_lock); - INIT_WORK(&mantis->uart_work, mantis_uart_work); /* disable interrupt */ @@ -169,8 +170,8 @@ int mantis_uart_init(struct mantis_pci *mantis) mmwrite((mmread(MANTIS_UART_CTL) | MANTIS_UART_RXFLUSH), MANTIS_UART_CTL); /* enable interrupt */ - mmwrite(mmread(MANTIS_INT_MASK) | 0x800, MANTIS_INT_MASK); mmwrite(mmread(MANTIS_UART_CTL) | MANTIS_UART_RXINT, MANTIS_UART_CTL); + mantis_unmask_ints(mantis, MANTIS_INT_IRQ1); schedule_work(&mantis->uart_work); dprintk(MANTIS_DEBUG, 1, "UART successfully initialized"); @@ -182,6 +183,7 @@ EXPORT_SYMBOL_GPL(mantis_uart_init); void mantis_uart_exit(struct mantis_pci *mantis) { /* disable interrupt */ + mantis_mask_ints(mantis, MANTIS_INT_IRQ1); mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL); flush_work(&mantis->uart_work); } -- cgit v1.2.3-59-g8ed1b From 9d605e6359f0808581b89350c643208586f41a06 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 10 Jun 2015 12:06:34 -0300 Subject: [media] mantis: cleanup CodingStyle issues due to last commit Commit a96762da0cfc('[media] mantis: add remote control support') introduced some new CodingStyle issues. Fix them. No functional changes. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/mantis/hopper_cards.c | 7 ++++--- drivers/media/pci/mantis/mantis_cards.c | 30 ++++++++++++++++-------------- drivers/media/pci/mantis/mantis_input.c | 8 ++------ drivers/media/pci/mantis/mantis_input.h | 10 +++------- drivers/media/pci/mantis/mantis_uart.c | 5 +++-- 5 files changed, 28 insertions(+), 32 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/mantis/hopper_cards.c b/drivers/media/pci/mantis/hopper_cards.c index 97b7a3220dbd..68b5800030b7 100644 --- a/drivers/media/pci/mantis/hopper_cards.c +++ b/drivers/media/pci/mantis/hopper_cards.c @@ -107,7 +107,8 @@ static irqreturn_t hopper_irq_handler(int irq, void *dev_id) if (stat & MANTIS_INT_IRQ1) { dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]); spin_lock(&mantis->intmask_lock); - mmwrite(mmread(MANTIS_INT_MASK) & ~MANTIS_INT_IRQ1, MANTIS_INT_MASK); + mmwrite(mmread(MANTIS_INT_MASK) & ~MANTIS_INT_IRQ1, + MANTIS_INT_MASK); spin_unlock(&mantis->intmask_lock); schedule_work(&mantis->uart_work); } @@ -169,7 +170,7 @@ static int hopper_pci_probe(struct pci_dev *pdev, goto fail0; } - drvdata = (struct mantis_pci_drvdata *) pci_id->driver_data; + drvdata = (void *)pci_id->driver_data; mantis->num = devs; mantis->verbose = verbose; mantis->pdev = pdev; @@ -256,7 +257,7 @@ static void hopper_pci_remove(struct pci_dev *pdev) static struct pci_device_id hopper_pci_table[] = { MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3028_DVB_T, &vp3028_config, - NULL), + NULL), { } }; diff --git a/drivers/media/pci/mantis/mantis_cards.c b/drivers/media/pci/mantis/mantis_cards.c index 6b64bfd938b6..cdefffc16d9e 100644 --- a/drivers/media/pci/mantis/mantis_cards.c +++ b/drivers/media/pci/mantis/mantis_cards.c @@ -117,7 +117,8 @@ static irqreturn_t mantis_irq_handler(int irq, void *dev_id) if (stat & MANTIS_INT_IRQ1) { dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]); spin_lock(&mantis->intmask_lock); - mmwrite(mmread(MANTIS_INT_MASK) & ~MANTIS_INT_IRQ1, MANTIS_INT_MASK); + mmwrite(mmread(MANTIS_INT_MASK) & ~MANTIS_INT_IRQ1, + MANTIS_INT_MASK); spin_unlock(&mantis->intmask_lock); schedule_work(&mantis->uart_work); } @@ -178,7 +179,7 @@ static int mantis_pci_probe(struct pci_dev *pdev, return -ENOMEM; } - drvdata = (struct mantis_pci_drvdata *) pci_id->driver_data; + drvdata = (void *)pci_id->driver_data; mantis->num = devs; mantis->verbose = verbose; mantis->pdev = pdev; @@ -227,7 +228,8 @@ static int mantis_pci_probe(struct pci_dev *pdev, err = mantis_input_init(mantis); if (err < 0) { - dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err); + dprintk(MANTIS_ERROR, 1, + "ERROR: Mantis DVB initialization failed <%d>", err); goto err_dvb_exit; } @@ -281,27 +283,27 @@ static void mantis_pci_remove(struct pci_dev *pdev) static struct pci_device_id mantis_pci_table[] = { MAKE_ENTRY(TECHNISAT, CABLESTAR_HD2, &vp2040_config, - RC_MAP_TECHNISAT_TS35), + RC_MAP_TECHNISAT_TS35), MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_10, &vp1041_config, - NULL), + NULL), MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_20, &vp1041_config, - NULL), + NULL), MAKE_ENTRY(TERRATEC, CINERGY_C, &vp2040_config, - RC_MAP_TERRATEC_CINERGY_C_PCI), + RC_MAP_TERRATEC_CINERGY_C_PCI), MAKE_ENTRY(TERRATEC, CINERGY_S2_PCI_HD, &vp1041_config, - RC_MAP_TERRATEC_CINERGY_S2_HD), + RC_MAP_TERRATEC_CINERGY_S2_HD), MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1033_DVB_S, &vp1033_config, - NULL), + NULL), MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1034_DVB_S, &vp1034_config, - NULL), + NULL), MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1041_DVB_S2, &vp1041_config, - RC_MAP_TWINHAN_DTV_CAB_CI), + RC_MAP_TWINHAN_DTV_CAB_CI), MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2033_DVB_C, &vp2033_config, - RC_MAP_TWINHAN_DTV_CAB_CI), + RC_MAP_TWINHAN_DTV_CAB_CI), MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2040_DVB_C, &vp2040_config, - NULL), + NULL), MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3030_DVB_T, &vp3030_config, - NULL), + NULL), { } }; diff --git a/drivers/media/pci/mantis/mantis_input.c b/drivers/media/pci/mantis/mantis_input.c index abf0ddfef0cb..7f7f1d4d7bb1 100644 --- a/drivers/media/pci/mantis/mantis_input.c +++ b/drivers/media/pci/mantis/mantis_input.c @@ -12,10 +12,6 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include @@ -51,9 +47,9 @@ int mantis_input_init(struct mantis_pci *mantis) } snprintf(mantis->input_name, sizeof(mantis->input_name), - "Mantis %s IR receiver", mantis->hwconfig->model_name); + "Mantis %s IR receiver", mantis->hwconfig->model_name); snprintf(mantis->input_phys, sizeof(mantis->input_phys), - "pci-%s/ir0", pci_name(mantis->pdev)); + "pci-%s/ir0", pci_name(mantis->pdev)); dev->input_name = mantis->input_name; dev->input_phys = mantis->input_phys; diff --git a/drivers/media/pci/mantis/mantis_input.h b/drivers/media/pci/mantis/mantis_input.h index 3bbde8b11ce1..0fbd92987c02 100644 --- a/drivers/media/pci/mantis/mantis_input.h +++ b/drivers/media/pci/mantis/mantis_input.h @@ -12,17 +12,13 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __MANTIS_INPUT_H #define __MANTIS_INPUT_H -extern int mantis_input_init(struct mantis_pci *mantis); -extern void mantis_input_exit(struct mantis_pci *mantis); -extern void mantis_input_process(struct mantis_pci *mantis, int scancode); +int mantis_input_init(struct mantis_pci *mantis); +void mantis_input_exit(struct mantis_pci *mantis); +void mantis_input_process(struct mantis_pci *mantis, int scancode); #endif /* __MANTIS_UART_H */ diff --git a/drivers/media/pci/mantis/mantis_uart.c b/drivers/media/pci/mantis/mantis_uart.c index 483410948995..f1c96aec8c7b 100644 --- a/drivers/media/pci/mantis/mantis_uart.c +++ b/drivers/media/pci/mantis/mantis_uart.c @@ -70,6 +70,7 @@ static void mantis_uart_read(struct mantis_pci *mantis) dprintk(MANTIS_DEBUG, 1, "UART Reading ..."); for (i = 0; i < (config->bytes + 1); i++) { int data = mmread(MANTIS_UART_RXD); + dprintk(MANTIS_DEBUG, 0, " <%02x>", data); scancode = (scancode << 8) | (data & 0x3f); @@ -98,8 +99,8 @@ static void mantis_uart_work(struct work_struct *work) dprintk(MANTIS_ERROR, 1, "RX Fifo FULL"); /* - * MANTIS_UART_RXFIFO_DATA is only set if at least config->bytes + 1 bytes - * are in the FIFO. + * MANTIS_UART_RXFIFO_DATA is only set if at least + * config->bytes + 1 bytes are in the FIFO. */ while (stat & MANTIS_UART_RXFIFO_DATA) { mantis_uart_read(mantis); -- cgit v1.2.3-59-g8ed1b From 87b09bd048924f5b830d57f719b0c62ec25bac32 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 10 Jun 2015 12:26:18 -0300 Subject: ts2020: fix compilation on i386 drivers/built-in.o: In function `ts2020_read_signal_strength': ts2020.c:(.text+0x298ff94): undefined reference to `__divdi3' ts2020.c:(.text+0x298ffd4): undefined reference to `__divdi3' ts2020.c:(.text+0x298fffd): undefined reference to `__divdi3' Makefile:921: recipe for target 'vmlinux' failed Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/ts2020.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c index 946d8e9502fd..f61b143a0052 100644 --- a/drivers/media/dvb-frontends/ts2020.c +++ b/drivers/media/dvb-frontends/ts2020.c @@ -22,6 +22,7 @@ #include "dvb_frontend.h" #include "ts2020.h" #include +#include #define TS2020_XTAL_FREQ 27000 /* in kHz */ #define FREQ_OFFSET_LOW_SYM_RATE 3000 @@ -483,13 +484,13 @@ static int ts2020_read_signal_strength(struct dvb_frontend *fe, strength = 0; else if (gain < -65000) /* 0% - 60%: weak signal */ - strength = 0 + (85000 + gain) * 3 / 1000; + strength = 0 + div64_s64((85000 + gain) * 3, 1000); else if (gain < -45000) /* 60% - 90%: normal signal */ - strength = 60 + (65000 + gain) * 3 / 2000; + strength = 60 + div64_s64((65000 + gain) * 3, 2000); else /* 90% - 99%: strong signal */ - strength = 90 + (45000 + gain) / 5000; + strength = 90 + div64_s64((45000 + gain), 5000); *_signal_strength = strength * 65535 / 100; return 0; -- cgit v1.2.3-59-g8ed1b From 1a8b18afa13f2772b1ae79de3831f0b81b4a0903 Mon Sep 17 00:00:00 2001 From: Fabien Dessenne Date: Wed, 10 Jun 2015 07:19:37 -0300 Subject: [media] bdisp: remove needless check As reported by smatch: drivers/media/platform/sti/bdisp/bdisp-v4l2.c:947 bdisp_s_selection() warn: unsigned 'out.width' is never less than zero. drivers/media/platform/sti/bdisp/bdisp-v4l2.c:947 bdisp_s_selection() warn: unsigned 'out.height' is never less than zero. Indeed, width and height are unsigned. Signed-off-by: Fabien Dessenne Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sti/bdisp/bdisp-v4l2.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c index 89d7a2279bc6..9a8405cd5216 100644 --- a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c +++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c @@ -944,8 +944,7 @@ static int bdisp_s_selection(struct file *file, void *fh, out.width = ALIGN(in->width, frame->fmt->w_align); out.height = ALIGN(in->height, frame->fmt->w_align); - if ((out.width < 0) || (out.height < 0) || - ((out.left + out.width) > frame->width) || + if (((out.left + out.width) > frame->width) || ((out.top + out.height) > frame->height)) { dev_err(ctx->bdisp_dev->dev, "Invalid crop: %dx%d@(%d,%d) vs frame: %dx%d\n", -- cgit v1.2.3-59-g8ed1b From baa1fb504c5b89d1b04e5b4d1b8658f41bb29477 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 10 Jun 2015 12:30:52 -0300 Subject: [media] bdisp: remove unused var Fix the following warning: drivers/media/platform/sti/bdisp/bdisp-v4l2.c: In function 'bdisp_register_device': drivers/media/platform/sti/bdisp/bdisp-v4l2.c:1024:26: warning: variable 'pdev' set but not used [-Wunused-but-set-variable] struct platform_device *pdev; Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sti/bdisp/bdisp-v4l2.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c index 9a8405cd5216..9e782ebe18da 100644 --- a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c +++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c @@ -1021,14 +1021,11 @@ static const struct v4l2_ioctl_ops bdisp_ioctl_ops = { static int bdisp_register_device(struct bdisp_dev *bdisp) { - struct platform_device *pdev; int ret; if (!bdisp) return -ENODEV; - pdev = bdisp->pdev; - bdisp->vdev.fops = &bdisp_fops; bdisp->vdev.ioctl_ops = &bdisp_ioctl_ops; bdisp->vdev.release = video_device_release_empty; -- cgit v1.2.3-59-g8ed1b From 48c91aadc5372f2c3a9b7da11403f86ef2118b26 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Mon, 8 Jun 2015 19:05:20 -0300 Subject: [media] lmedm04: implement dvb v5 statistics Indroduce function lme2510_update_stats to update statistics directly from usb interrupt. Provide signal and snr wrap rounds for dvb v3 functions. Block and post bit are not available. When i2c_talk_onoff is on no statistics are available, with possible future hand over to the relevant frontend/tuner. Signed-off-by: Malcolm Priestley Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/lmedm04.c | 104 ++++++++++++++++++++++++--------- 1 file changed, 77 insertions(+), 27 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c index d37940774503..57fb184184bf 100644 --- a/drivers/media/usb/dvb-usb-v2/lmedm04.c +++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c @@ -257,6 +257,65 @@ static int lme2510_enable_pid(struct dvb_usb_device *d, u8 index, u16 pid_out) return ret; } +static void lme2510_update_stats(struct dvb_usb_adapter *adap) +{ + struct lme2510_state *st = adap_to_priv(adap); + struct dvb_frontend *fe = adap->fe[0]; + struct dtv_frontend_properties *c; + u64 s_tmp = 0, c_tmp = 0; + + if (!fe) + return; + + c = &fe->dtv_property_cache; + + c->block_count.len = 1; + c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->block_error.len = 1; + c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->post_bit_count.len = 1; + c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->post_bit_error.len = 1; + c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + + if (st->i2c_talk_onoff) { + c->strength.len = 1; + c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->cnr.len = 1; + c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + return; + } + + switch (st->tuner_config) { + case TUNER_LG: + s_tmp = 0xff - st->signal_level; + s_tmp |= s_tmp << 8; + + c_tmp = 0xff - st->signal_sn; + c_tmp |= c_tmp << 8; + break; + /* fall through */ + case TUNER_S7395: + case TUNER_S0194: + s_tmp = 0xffff - (((st->signal_level * 2) << 8) * 5 / 4); + + c_tmp = ((0xff - st->signal_sn - 0xa1) * 3) << 8; + break; + case TUNER_RS2000: + s_tmp = st->signal_level * 0xffff / 0xff; + + c_tmp = st->signal_sn * 0xffff / 0x7f; + } + + c->strength.len = 1; + c->strength.stat[0].scale = FE_SCALE_RELATIVE; + c->strength.stat[0].uvalue = s_tmp; + + c->cnr.len = 1; + c->cnr.stat[0].scale = FE_SCALE_RELATIVE; + c->cnr.stat[0].uvalue = c_tmp; +} + static void lme2510_int_response(struct urb *lme_urb) { struct dvb_usb_adapter *adap = lme_urb->context; @@ -337,6 +396,8 @@ static void lme2510_int_response(struct urb *lme_urb) if (!signal_lock) st->lock_status &= ~FE_HAS_LOCK; + lme2510_update_stats(adap); + debug_data_snipet(5, "INT Remote data snipet in", ibuf); break; case 0xcc: @@ -872,56 +933,45 @@ static int dm04_read_status(struct dvb_frontend *fe, enum fe_status *status) *status = st->lock_status; - if (!(*status & FE_HAS_LOCK)) + if (!(*status & FE_HAS_LOCK)) { + struct dvb_usb_adapter *adap = fe_to_adap(fe); + st->i2c_talk_onoff = 1; + lme2510_update_stats(adap); + } + return ret; } static int dm04_read_signal_strength(struct dvb_frontend *fe, u16 *strength) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct lme2510_state *st = fe_to_priv(fe); if (st->fe_read_signal_strength && !st->stream_on) return st->fe_read_signal_strength(fe, strength); - switch (st->tuner_config) { - case TUNER_LG: - *strength = 0xff - st->signal_level; - *strength |= *strength << 8; - break; - /* fall through */ - case TUNER_S7395: - case TUNER_S0194: - *strength = 0xffff - (((st->signal_level * 2) << 8) * 5 / 4); - break; - case TUNER_RS2000: - *strength = (u16)((u32)st->signal_level * 0xffff / 0xff); - } + if (c->strength.stat[0].scale == FE_SCALE_RELATIVE) + *strength = (u16)c->strength.stat[0].uvalue; + else + *strength = 0; return 0; } static int dm04_read_snr(struct dvb_frontend *fe, u16 *snr) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct lme2510_state *st = fe_to_priv(fe); if (st->fe_read_snr && !st->stream_on) return st->fe_read_snr(fe, snr); - switch (st->tuner_config) { - case TUNER_LG: - *snr = 0xff - st->signal_sn; - *snr |= *snr << 8; - break; - /* fall through */ - case TUNER_S7395: - case TUNER_S0194: - *snr = (u16)((0xff - st->signal_sn - 0xa1) * 3) << 8; - break; - case TUNER_RS2000: - *snr = (u16)((u32)st->signal_sn * 0xffff / 0x7f); - } + if (c->cnr.stat[0].scale == FE_SCALE_RELATIVE) + *snr = (u16)c->cnr.stat[0].uvalue; + else + *snr = 0; return 0; } -- cgit v1.2.3-59-g8ed1b From e42c8c6eb456f8978de417ea349eef676ef4385c Mon Sep 17 00:00:00 2001 From: Rafael Lourenço de Lima Chehab Date: Mon, 8 Jun 2015 22:20:45 -0300 Subject: [media] au0828: move dev->boards atribuition to happen earlier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The attribution of dev->boards occured too late, which would couse an OOPS in media controller registration. Signed-off-by: Rafael Lourenço de Lima Chehab Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/au0828/au0828-cards.c | 2 -- drivers/media/usb/au0828/au0828-core.c | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/au0828/au0828-cards.c b/drivers/media/usb/au0828/au0828-cards.c index edc27355f271..6b469e8c4c6e 100644 --- a/drivers/media/usb/au0828/au0828-cards.c +++ b/drivers/media/usb/au0828/au0828-cards.c @@ -195,8 +195,6 @@ void au0828_card_setup(struct au0828_dev *dev) dprintk(1, "%s()\n", __func__); - dev->board = au0828_boards[dev->boardnr]; - if (dev->i2c_rc == 0) { dev->i2c_client.addr = 0xa0 >> 1; tveeprom_read(&dev->i2c_client, eeprom, sizeof(eeprom)); diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 082ae6ba492f..0934024fb89d 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -222,6 +222,8 @@ static int au0828_usb_probe(struct usb_interface *interface, mutex_init(&dev->dvb.lock); dev->usbdev = usbdev; dev->boardnr = id->driver_info; + dev->board = au0828_boards[dev->boardnr]; + #ifdef CONFIG_VIDEO_AU0828_V4L2 dev->v4l2_dev.release = au0828_usb_v4l2_release; -- cgit v1.2.3-59-g8ed1b From bc5e66bd2591424f0e08d5478a36a8074fe739f5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 10 Jun 2015 13:55:35 -0300 Subject: [media] cx88: don't declare restart_video_queue if not used While compiled on alpha, got this error: drivers/media/pci/cx88/cx88-video.c:415:12: warning: 'restart_video_queue' defined but not used [-Wunused-function] Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index cebb07d87617..400e5caefd58 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -410,7 +410,6 @@ static int stop_video_dma(struct cx8800_dev *dev) cx_clear(MO_VID_INTMSK, 0x0f0011); return 0; } -#endif static int restart_video_queue(struct cx8800_dev *dev, struct cx88_dmaqueue *q) @@ -426,6 +425,7 @@ static int restart_video_queue(struct cx8800_dev *dev, } return 0; } +#endif /* ------------------------------------------------------------------ */ -- cgit v1.2.3-59-g8ed1b From 82d229cde00f7476b223c3ac5ded0248014cdeb7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 10 Jun 2015 14:37:16 -0300 Subject: [media] bdisp-debug: don't try to divide by s64 There are several warnings there, on some architectures, related to dividing a s32 by a s64 value: drivers/media/platform/sti/bdisp/bdisp-debug.c:594: warning: comparison of distinct pointer types lacks a cast drivers/media/platform/sti/bdisp/bdisp-debug.c:594: warning: right shift count >= width of type drivers/media/platform/sti/bdisp/bdisp-debug.c:594: warning: passing argument 1 of '__div64_32' from incompatible pointer type drivers/media/platform/sti/bdisp/bdisp-debug.c:595: warning: comparison of distinct pointer types lacks a cast drivers/media/platform/sti/bdisp/bdisp-debug.c:595: warning: right shift count >= width of type drivers/media/platform/sti/bdisp/bdisp-debug.c:595: warning: passing argument 1 of '__div64_32' from incompatible pointer type CC [M] drivers/media/tuners/mt2060.o drivers/media/platform/sti/bdisp/bdisp-debug.c:596: warning: comparison of distinct pointer types lacks a cast drivers/media/platform/sti/bdisp/bdisp-debug.c:596: warning: right shift count >= width of type drivers/media/platform/sti/bdisp/bdisp-debug.c:596: warning: passing argument 1 of '__div64_32' from incompatible pointer type drivers/media/platform/sti/bdisp/bdisp-debug.c:597: warning: comparison of distinct pointer types lacks a cast drivers/media/platform/sti/bdisp/bdisp-debug.c:597: warning: right shift count >= width of type drivers/media/platform/sti/bdisp/bdisp-debug.c:597: warning: passing argument 1 of '__div64_32' from incompatible pointer type That doesn't make much sense. What the driver is actually trying to do is to divide one second by a value. So, check the range before dividing. That warrants the right result and will remove the warnings on non-64 bits archs. Also fixes this warning: drivers/media/platform/sti/bdisp/bdisp-debug.c:588: warning: comparison of distinct pointer types lacks a cast by using div64_s64() instead of calling do_div() directly. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sti/bdisp/bdisp-debug.c | 33 +++++++++++++++++--------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/sti/bdisp/bdisp-debug.c b/drivers/media/platform/sti/bdisp/bdisp-debug.c index 7c3a632746ba..18282a0f80c9 100644 --- a/drivers/media/platform/sti/bdisp/bdisp-debug.c +++ b/drivers/media/platform/sti/bdisp/bdisp-debug.c @@ -572,6 +572,8 @@ static int bdisp_dbg_regs(struct seq_file *s, void *data) return 0; } +#define SECOND 1000000 + static int bdisp_dbg_perf(struct seq_file *s, void *data) { struct bdisp_dev *bdisp = s->private; @@ -584,17 +586,26 @@ static int bdisp_dbg_perf(struct seq_file *s, void *data) return 0; } - avg_time_us = bdisp->dbg.tot_duration; - do_div(avg_time_us, request->nb_req); - - avg_fps = 1000000; - min_fps = 1000000; - max_fps = 1000000; - last_fps = 1000000; - do_div(avg_fps, avg_time_us); - do_div(min_fps, bdisp->dbg.min_duration); - do_div(max_fps, bdisp->dbg.max_duration); - do_div(last_fps, bdisp->dbg.last_duration); + avg_time_us = div64_s64(bdisp->dbg.tot_duration, request->nb_req); + if (avg_time_us > SECOND) + avg_fps = 0; + else + avg_fps = SECOND / (s32)avg_time_us; + + if (bdisp->dbg.min_duration > SECOND) + min_fps = 0; + else + min_fps = SECOND / (s32)bdisp->dbg.min_duration; + + if (bdisp->dbg.max_duration > SECOND) + max_fps = 0; + else + max_fps = SECOND / (s32)bdisp->dbg.max_duration; + + if (bdisp->dbg.last_duration > SECOND) + last_fps = 0; + else + last_fps = SECOND / (s32)bdisp->dbg.last_duration; seq_printf(s, "HW processing (%d requests):\n", request->nb_req); seq_printf(s, " Average: %5lld us (%3d fps)\n", -- cgit v1.2.3-59-g8ed1b From 6fe2d69c07864eecf33373b0e4be401737e37fa4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 18 Jun 2015 14:31:38 -0300 Subject: [media] mantis: cleanup a warning Signed-off-by: Mauro Carvalho Chehab drivers/media/pci/mantis/mantis_i2c.c: In function 'mantis_i2c_init': drivers/media/pci/mantis/mantis_i2c.c:222:15: warning: variable 'intmask' set but not used [-Wunused-but-set-variable] u32 intstat, intmask; --- drivers/media/pci/mantis/mantis_i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/mantis/mantis_i2c.c b/drivers/media/pci/mantis/mantis_i2c.c index a93823490a43..d72ee47dc6e4 100644 --- a/drivers/media/pci/mantis/mantis_i2c.c +++ b/drivers/media/pci/mantis/mantis_i2c.c @@ -219,7 +219,7 @@ static struct i2c_algorithm mantis_algo = { int mantis_i2c_init(struct mantis_pci *mantis) { - u32 intstat, intmask; + u32 intstat; struct i2c_adapter *i2c_adapter = &mantis->adapter; struct pci_dev *pdev = mantis->pdev; @@ -242,7 +242,7 @@ int mantis_i2c_init(struct mantis_pci *mantis) dprintk(MANTIS_DEBUG, 1, "Initializing I2C .."); intstat = mmread(MANTIS_INT_STAT); - intmask = mmread(MANTIS_INT_MASK); + mmread(MANTIS_INT_MASK); mmwrite(intstat, MANTIS_INT_STAT); dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt"); mantis_mask_ints(mantis, MANTIS_INT_I2CDONE); -- cgit v1.2.3-59-g8ed1b From 511a1b8a4c816a4e46a0d0aea9221ff3c708282e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 15 Jun 2015 04:16:32 -0300 Subject: [media] Revert "[media] vb2: Push mmap_sem down to memops" This reverts commit 48b25a3a713b90988b6882d318f7c0a6bed9aabc. That commit caused two regressions. The first is a BUG: Jun 14 18:42:15 test-media kernel: [ 115.972299] BUG: unable to handle kernel NULL pointer dereference at 0000000000000100 Jun 14 18:42:15 test-media kernel: [ 115.972307] IP: [] __lock_acquire+0x2f0/0x2070 Jun 14 18:42:15 test-media kernel: [ 115.972316] PGD 0 Jun 14 18:42:15 test-media kernel: [ 115.972318] Oops: 0000 [#1] PREEMPT SMP Jun 14 18:42:15 test-media kernel: [ 115.972321] Modules linked in: vivid v4l2_dv_timings videobuf2_vmalloc videobuf2_memops videobuf2_core v4l2_common videodev media vmw_balloon vmw_vmci acpi_cpufreq processor button Jun 14 18:42:15 test-media kernel: [ 115.972333] CPU: 0 PID: 1542 Comm: v4l2-ctl Not tainted 4.1.0-rc3-test-media #1190 Jun 14 18:42:15 test-media kernel: [ 115.972336] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 05/20/2014 Jun 14 18:42:15 test-media kernel: [ 115.972337] task: ffff880220ce4200 ti: ffff88021d16c000 task.ti: ffff88021d16c000 Jun 14 18:42:15 test-media kernel: [ 115.972339] RIP: 0010:[] [] __lock_acquire+0x2f0/0x2070 Jun 14 18:42:15 test-media kernel: [ 115.972342] RSP: 0018:ffff88021d16f9b8 EFLAGS: 00010002 Jun 14 18:42:15 test-media kernel: [ 115.972343] RAX: 0000000000000046 RBX: 0000000000000292 RCX: 0000000000000001 Jun 14 18:42:15 test-media kernel: [ 115.972345] RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000100 Jun 14 18:42:15 test-media kernel: [ 115.972346] RBP: ffff88021d16fa88 R08: 0000000000000001 R09: 0000000000000000 Jun 14 18:42:15 test-media kernel: [ 115.972347] R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000001 Jun 14 18:42:15 test-media kernel: [ 115.972348] R13: ffff880220ce4200 R14: 0000000000000100 R15: 0000000000000000 Jun 14 18:42:15 test-media kernel: [ 115.972350] FS: 00007f2441e7f740(0000) GS:ffff880236e00000(0000) knlGS:0000000000000000 Jun 14 18:42:15 test-media kernel: [ 115.972351] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b Jun 14 18:42:15 test-media kernel: [ 115.972353] CR2: 0000000000000100 CR3: 0000000001e0b000 CR4: 00000000001406f0 Jun 14 18:42:15 test-media kernel: [ 115.972424] Stack: Jun 14 18:42:15 test-media kernel: [ 115.972427] ffff88021d16fa98 ffffffff810d6543 0000000000000006 0000000000000246 Jun 14 18:42:15 test-media kernel: [ 115.972431] ffff88021d16fa08 ffffffff810d532d ffff880220ce4a78 ffff880200000000 Jun 14 18:42:15 test-media kernel: [ 115.972433] ffff880200000001 0000000000000000 0000000000000001 000000000093a4a0 Jun 14 18:42:15 test-media kernel: [ 115.972436] Call Trace: Jun 14 18:42:15 test-media kernel: [ 115.972440] [] ? __lock_acquire+0xb63/0x2070 Jun 14 18:42:15 test-media kernel: [ 115.972443] [] ? mark_held_locks+0x6d/0xa0 Jun 14 18:42:15 test-media kernel: [ 115.972445] [] ? __lock_is_held+0x58/0x80 Jun 14 18:42:15 test-media kernel: [ 115.972447] [] lock_acquire+0x6c/0xa0 Jun 14 18:42:15 test-media kernel: [ 115.972452] [] ? vb2_vmalloc_put_userptr+0x36/0x110 [videobuf2_vmalloc] Jun 14 18:42:15 test-media kernel: [ 115.972458] [] down_read+0x42/0x60 Jun 14 18:42:15 test-media kernel: [ 115.972460] [] ? vb2_vmalloc_put_userptr+0x36/0x110 [videobuf2_vmalloc] Jun 14 18:42:15 test-media kernel: [ 115.972463] [] ? mutex_lock_nested+0x2b1/0x560 Jun 14 18:42:15 test-media kernel: [ 115.972467] [] ? vb2_queue_release+0x25/0x40 [videobuf2_core] Jun 14 18:42:15 test-media kernel: [ 115.972469] [] vb2_vmalloc_put_userptr+0x36/0x110 [videobuf2_vmalloc] Jun 14 18:42:15 test-media kernel: [ 115.972472] [] __vb2_queue_free+0x146/0x5e0 [videobuf2_core] Jun 14 18:42:15 test-media kernel: [ 115.972475] [] vb2_queue_release+0x33/0x40 [videobuf2_core] Jun 14 18:42:15 test-media kernel: [ 115.972478] [] _vb2_fop_release+0x95/0xb0 [videobuf2_core] Jun 14 18:42:15 test-media kernel: [ 115.972481] [] vb2_fop_release+0x29/0x50 [videobuf2_core] Jun 14 18:42:15 test-media kernel: [ 115.972485] [] vivid_fop_release+0x92/0x230 [vivid] Jun 14 18:42:15 test-media kernel: [ 115.972491] [] v4l2_release+0x30/0x80 [videodev] Jun 14 18:42:15 test-media kernel: [ 115.972496] [] __fput+0xe5/0x200 Jun 14 18:42:15 test-media kernel: [ 115.972498] [] ____fput+0x9/0x10 Jun 14 18:42:15 test-media kernel: [ 115.972501] [] task_work_run+0xc4/0xf0 Jun 14 18:42:15 test-media kernel: [ 115.972504] [] do_exit+0x3a0/0xaf0 Jun 14 18:42:15 test-media kernel: [ 115.972507] [] ? _raw_spin_unlock_irq+0x2b/0x60 Jun 14 18:42:15 test-media kernel: [ 115.972509] [] do_group_exit+0x4f/0xe0 Jun 14 18:42:15 test-media kernel: [ 115.972511] [] get_signal+0x200/0x8c0 Jun 14 18:42:15 test-media kernel: [ 115.972514] [] ? __mutex_unlock_slowpath+0xf5/0x240 Jun 14 18:42:15 test-media kernel: [ 115.972518] [] do_signal+0x23/0x820 Jun 14 18:42:15 test-media kernel: [ 115.972521] [] ? mutex_unlock+0x9/0x10 Jun 14 18:42:15 test-media kernel: [ 115.972524] [] ? v4l2_ioctl+0x78/0xf0 [videodev] Jun 14 18:42:15 test-media kernel: [ 115.972526] [] ? int_very_careful+0x5/0x46 Jun 14 18:42:15 test-media kernel: [ 115.972529] [] ? trace_hardirqs_on_caller+0x15d/0x200 Jun 14 18:42:15 test-media kernel: [ 115.972531] [] do_notify_resume+0x50/0x60 Jun 14 18:42:15 test-media kernel: [ 115.972533] [] int_signal+0x12/0x17 Jun 14 18:42:15 test-media kernel: [ 115.972534] Code: ca 81 31 c0 e8 7a e2 8c 00 e8 aa 1d 8d 00 0f 1f 44 00 00 31 db 48 81 c4 a8 00 00 00 89 d8 5b 41 5c 41 5d 41 5e 41 5f 5d c3 66 90 <49> 81 3e 40 4e 02 82 b8 00 00 00 00 44 0f 44 e0 41 83 ff 01 0f Jun 14 18:42:15 test-media kernel: [ 115.972567] RIP [] __lock_acquire+0x2f0/0x2070 Jun 14 18:42:15 test-media kernel: [ 115.972569] RSP Jun 14 18:42:15 test-media kernel: [ 115.972570] CR2: 0000000000000100 Jun 14 18:42:15 test-media kernel: [ 115.972573] ---[ end trace 25595c2b8560cb57 ]--- Jun 14 18:42:15 test-media kernel: [ 115.972575] Fixing recursive fault but reboot is needed! This can be reproduced by loading the vivid driver and running: v4l2-ctl --stream-user and pressing Ctrl-C. You may have to try a few times, but in my experience this BUG is triggered quite quickly. The second is a possible deadlock: Jun 14 18:44:07 test-media kernel: [ 49.376650] ====================================================== Jun 14 18:44:07 test-media kernel: [ 49.376651] [ INFO: possible circular locking dependency detected ] Jun 14 18:44:07 test-media kernel: [ 49.376653] 4.1.0-rc3-test-media #1190 Not tainted Jun 14 18:44:07 test-media kernel: [ 49.376654] ------------------------------------------------------- Jun 14 18:44:07 test-media kernel: [ 49.376655] v4l2-compliance/1468 is trying to acquire lock: Jun 14 18:44:07 test-media kernel: [ 49.376657] (&mm->mmap_sem){++++++}, at: [] vb2_vmalloc_put_userptr+0x36/0x110 [videobuf2_vmalloc] Jun 14 18:44:07 test-media kernel: [ 49.376665] Jun 14 18:44:07 test-media kernel: [ 49.376665] but task is already holding lock: Jun 14 18:44:07 test-media kernel: [ 49.376666] (&q->mmap_lock){+.+...}, at: [] vb2_queue_release+0x25/0x40 [videobuf2_core] Jun 14 18:44:07 test-media kernel: [ 49.376670] Jun 14 18:44:07 test-media kernel: [ 49.376670] which lock already depends on the new lock. Jun 14 18:44:07 test-media kernel: [ 49.376670] Jun 14 18:44:07 test-media kernel: [ 49.376671] Jun 14 18:44:07 test-media kernel: [ 49.376671] the existing dependency chain (in reverse order) is: Jun 14 18:44:07 test-media kernel: [ 49.376672] Jun 14 18:44:07 test-media kernel: [ 49.376672] -> #1 (&q->mmap_lock){+.+...}: Jun 14 18:44:07 test-media kernel: [ 49.376675] [] lock_acquire+0x6c/0xa0 Jun 14 18:44:07 test-media kernel: [ 49.376682] [] mutex_lock_nested+0x5e/0x560 Jun 14 18:44:07 test-media kernel: [ 49.376689] [] vb2_mmap+0x232/0x350 [videobuf2_core] Jun 14 18:44:07 test-media kernel: [ 49.376691] [] vb2_fop_mmap+0x20/0x30 [videobuf2_core] Jun 14 18:44:07 test-media kernel: [ 49.376694] [] v4l2_mmap+0x52/0x90 [videodev] Jun 14 18:44:07 test-media kernel: [ 49.376698] [] mmap_region+0x3b3/0x5e0 Jun 14 18:44:07 test-media kernel: [ 49.376701] [] do_mmap_pgoff+0x317/0x400 Jun 14 18:44:07 test-media kernel: [ 49.376703] [] vm_mmap_pgoff+0x90/0xc0 Jun 14 18:44:07 test-media kernel: [ 49.376708] [] SyS_mmap_pgoff+0x1d7/0x280 Jun 14 18:44:07 test-media kernel: [ 49.376709] [] SyS_mmap+0x1d/0x20 Jun 14 18:44:07 test-media kernel: [ 49.376714] [] system_call_fastpath+0x12/0x76 Jun 14 18:44:07 test-media kernel: [ 49.376716] Jun 14 18:44:07 test-media kernel: [ 49.376716] -> #0 (&mm->mmap_sem){++++++}: Jun 14 18:44:07 test-media kernel: [ 49.376718] [] __lock_acquire+0x1fd3/0x2070 Jun 14 18:44:07 test-media kernel: [ 49.376720] [] lock_acquire+0x6c/0xa0 Jun 14 18:44:07 test-media kernel: [ 49.376721] [] down_read+0x42/0x60 Jun 14 18:44:07 test-media kernel: [ 49.376723] [] vb2_vmalloc_put_userptr+0x36/0x110 [videobuf2_vmalloc] Jun 14 18:44:07 test-media kernel: [ 49.376725] [] __vb2_queue_free+0x146/0x5e0 [videobuf2_core] Jun 14 18:44:07 test-media kernel: [ 49.376727] [] vb2_queue_release+0x33/0x40 [videobuf2_core] Jun 14 18:44:07 test-media kernel: [ 49.376729] [] _vb2_fop_release+0x95/0xb0 [videobuf2_core] Jun 14 18:44:07 test-media kernel: [ 49.376731] [] vb2_fop_release+0x29/0x50 [videobuf2_core] Jun 14 18:44:07 test-media kernel: [ 49.376733] [] vivid_fop_release+0x92/0x230 [vivid] Jun 14 18:44:07 test-media kernel: [ 49.376737] [] v4l2_release+0x30/0x80 [videodev] Jun 14 18:44:07 test-media kernel: [ 49.376739] [] __fput+0xe5/0x200 Jun 14 18:44:07 test-media kernel: [ 49.376744] [] ____fput+0x9/0x10 Jun 14 18:44:07 test-media kernel: [ 49.376746] [] task_work_run+0xc4/0xf0 Jun 14 18:44:07 test-media kernel: [ 49.376749] [] do_notify_resume+0x41/0x60 Jun 14 18:44:07 test-media kernel: [ 49.376752] [] int_signal+0x12/0x17 Jun 14 18:44:07 test-media kernel: [ 49.376754] Jun 14 18:44:07 test-media kernel: [ 49.376754] other info that might help us debug this: Jun 14 18:44:07 test-media kernel: [ 49.376754] Jun 14 18:44:07 test-media kernel: [ 49.376755] Possible unsafe locking scenario: Jun 14 18:44:07 test-media kernel: [ 49.376755] Jun 14 18:44:07 test-media kernel: [ 49.376756] CPU0 CPU1 Jun 14 18:44:07 test-media kernel: [ 49.376757] ---- ---- Jun 14 18:44:07 test-media kernel: [ 49.376758] lock(&q->mmap_lock); Jun 14 18:44:07 test-media kernel: [ 49.376759] lock(&mm->mmap_sem); Jun 14 18:44:07 test-media kernel: [ 49.376760] lock(&q->mmap_lock); Jun 14 18:44:07 test-media kernel: [ 49.376761] lock(&mm->mmap_sem); Jun 14 18:44:07 test-media kernel: [ 49.376763] Jun 14 18:44:07 test-media kernel: [ 49.376763] *** DEADLOCK *** Jun 14 18:44:07 test-media kernel: [ 49.376763] Jun 14 18:44:07 test-media kernel: [ 49.376764] 2 locks held by v4l2-compliance/1468: Jun 14 18:44:07 test-media kernel: [ 49.376765] #0: (&dev->mutex#3){+.+.+.}, at: [] _vb2_fop_release+0x2a/0xb0 [videobuf2_core] Jun 14 18:44:07 test-media kernel: [ 49.376770] #1: (&q->mmap_lock){+.+...}, at: [] vb2_queue_release+0x25/0x40 [videobuf2_core] Jun 14 18:44:07 test-media kernel: [ 49.376773] Jun 14 18:44:07 test-media kernel: [ 49.376773] stack backtrace: Jun 14 18:44:07 test-media kernel: [ 49.376776] CPU: 2 PID: 1468 Comm: v4l2-compliance Not tainted 4.1.0-rc3-test-media #1190 Jun 14 18:44:07 test-media kernel: [ 49.376777] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 05/20/2014 Jun 14 18:44:07 test-media kernel: [ 49.376779] ffffffff8279e0b0 ffff88021d6f7ba8 ffffffff819a7aac 0000000000000011 Jun 14 18:44:07 test-media kernel: [ 49.376781] ffffffff8279e0b0 ffff88021d6f7bf8 ffffffff819a3964 ffff88021d6f7bd8 Jun 14 18:44:07 test-media kernel: [ 49.376783] ffff8800ac8aa100 0000000000000002 ffff8800ac8aa9a0 0000000000000002 Jun 14 18:44:07 test-media kernel: [ 49.376785] Call Trace: Jun 14 18:44:07 test-media kernel: [ 49.376788] [] dump_stack+0x4f/0x7b Jun 14 18:44:07 test-media kernel: [ 49.376792] [] print_circular_bug+0x20f/0x251 Jun 14 18:44:07 test-media kernel: [ 49.376793] [] __lock_acquire+0x1fd3/0x2070 Jun 14 18:44:07 test-media kernel: [ 49.376795] [] ? __lock_acquire+0xb63/0x2070 Jun 14 18:44:07 test-media kernel: [ 49.376797] [] ? __lock_is_held+0x58/0x80 Jun 14 18:44:07 test-media kernel: [ 49.376798] [] lock_acquire+0x6c/0xa0 Jun 14 18:44:07 test-media kernel: [ 49.376800] [] ? vb2_vmalloc_put_userptr+0x36/0x110 [videobuf2_vmalloc] Jun 14 18:44:07 test-media kernel: [ 49.376802] [] down_read+0x42/0x60 Jun 14 18:44:07 test-media kernel: [ 49.376803] [] ? vb2_vmalloc_put_userptr+0x36/0x110 [videobuf2_vmalloc] Jun 14 18:44:07 test-media kernel: [ 49.376805] [] ? mutex_lock_nested+0x2b1/0x560 Jun 14 18:44:07 test-media kernel: [ 49.376807] [] ? vb2_queue_release+0x25/0x40 [videobuf2_core] Jun 14 18:44:07 test-media kernel: [ 49.376808] [] vb2_vmalloc_put_userptr+0x36/0x110 [videobuf2_vmalloc] Jun 14 18:44:07 test-media kernel: [ 49.376810] [] ? _vb2_fop_release+0x2a/0xb0 [videobuf2_core] Jun 14 18:44:07 test-media kernel: [ 49.376812] [] __vb2_queue_free+0x146/0x5e0 [videobuf2_core] Jun 14 18:44:07 test-media kernel: [ 49.376814] [] vb2_queue_release+0x33/0x40 [videobuf2_core] Jun 14 18:44:07 test-media kernel: [ 49.376816] [] _vb2_fop_release+0x95/0xb0 [videobuf2_core] Jun 14 18:44:07 test-media kernel: [ 49.376818] [] vb2_fop_release+0x29/0x50 [videobuf2_core] Jun 14 18:44:07 test-media kernel: [ 49.376820] [] vivid_fop_release+0x92/0x230 [vivid] Jun 14 18:44:07 test-media kernel: [ 49.376822] [] v4l2_release+0x30/0x80 [videodev] Jun 14 18:44:07 test-media kernel: [ 49.376824] [] __fput+0xe5/0x200 Jun 14 18:44:07 test-media kernel: [ 49.376825] [] ? int_very_careful+0x5/0x46 Jun 14 18:44:07 test-media kernel: [ 49.376827] [] ____fput+0x9/0x10 Jun 14 18:44:07 test-media kernel: [ 49.376828] [] task_work_run+0xc4/0xf0 Jun 14 18:44:07 test-media kernel: [ 49.376830] [] do_notify_resume+0x41/0x60 Jun 14 18:44:07 test-media kernel: [ 49.376832] [] int_signal+0x12/0x17 This can be triggered by loading the vivid module with the module option 'no_error_inj=1' and running 'v4l2-compliance -s5'. Again, it may take a few attempts to trigger this but for me it happens quite quickly. Without this patch I cannot reproduce these two issues. So reverting is the best solution for now. Signed-off-by: Hans Verkuil Cc: Jan Kara Cc: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-core.c | 2 ++ drivers/media/v4l2-core/videobuf2-dma-contig.c | 7 ------- drivers/media/v4l2-core/videobuf2-dma-sg.c | 6 ------ drivers/media/v4l2-core/videobuf2-vmalloc.c | 6 +----- 4 files changed, 3 insertions(+), 18 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 1a096a62ef30..d835814a24d4 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -1662,7 +1662,9 @@ static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b) ret = __qbuf_mmap(vb, b); break; case V4L2_MEMORY_USERPTR: + down_read(¤t->mm->mmap_sem); ret = __qbuf_userptr(vb, b); + up_read(¤t->mm->mmap_sem); break; case V4L2_MEMORY_DMABUF: ret = __qbuf_dmabuf(vb, b); diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 369df95af5c7..94c1e6455d36 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -532,9 +532,7 @@ static void vb2_dc_put_userptr(void *buf_priv) sg_free_table(sgt); kfree(sgt); } - down_read(¤t->mm->mmap_sem); vb2_put_vma(buf->vma); - up_read(¤t->mm->mmap_sem); kfree(buf); } @@ -618,7 +616,6 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, goto fail_buf; } - down_read(¤t->mm->mmap_sem); /* current->mm->mmap_sem is taken by videobuf2 core */ vma = find_vma(current->mm, vaddr); if (!vma) { @@ -645,7 +642,6 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, if (ret) { unsigned long pfn; if (vb2_dc_get_user_pfn(start, n_pages, vma, &pfn) == 0) { - up_read(¤t->mm->mmap_sem); buf->dma_addr = vb2_dc_pfn_to_dma(buf->dev, pfn); buf->size = size; kfree(pages); @@ -655,7 +651,6 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, pr_err("failed to get user pages\n"); goto fail_vma; } - up_read(¤t->mm->mmap_sem); sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); if (!sgt) { @@ -718,12 +713,10 @@ fail_get_user_pages: while (n_pages) put_page(pages[--n_pages]); - down_read(¤t->mm->mmap_sem); fail_vma: vb2_put_vma(buf->vma); fail_pages: - up_read(¤t->mm->mmap_sem); kfree(pages); /* kfree is NULL-proof */ fail_buf: diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c index d7bcb05c7058..7289b81bd7b7 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c @@ -264,7 +264,6 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr, if (!buf->pages) goto userptr_fail_alloc_pages; - down_read(¤t->mm->mmap_sem); vma = find_vma(current->mm, vaddr); if (!vma) { dprintk(1, "no vma for address %lu\n", vaddr); @@ -303,7 +302,6 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr, 1, /* force */ buf->pages, NULL); - up_read(¤t->mm->mmap_sem); if (num_pages_from_user != buf->num_pages) goto userptr_fail_get_user_pages; @@ -333,10 +331,8 @@ userptr_fail_get_user_pages: if (!vma_is_io(buf->vma)) while (--num_pages_from_user >= 0) put_page(buf->pages[num_pages_from_user]); - down_read(¤t->mm->mmap_sem); vb2_put_vma(buf->vma); userptr_fail_find_vma: - up_read(¤t->mm->mmap_sem); kfree(buf->pages); userptr_fail_alloc_pages: kfree(buf); @@ -370,9 +366,7 @@ static void vb2_dma_sg_put_userptr(void *buf_priv) put_page(buf->pages[i]); } kfree(buf->pages); - down_read(¤t->mm->mmap_sem); vb2_put_vma(buf->vma); - up_read(¤t->mm->mmap_sem); kfree(buf); } diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c b/drivers/media/v4l2-core/videobuf2-vmalloc.c index f6656fefc035..2fe4c27f524a 100644 --- a/drivers/media/v4l2-core/videobuf2-vmalloc.c +++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c @@ -89,7 +89,7 @@ static void *vb2_vmalloc_get_userptr(void *alloc_ctx, unsigned long vaddr, offset = vaddr & ~PAGE_MASK; buf->size = size; - down_read(¤t->mm->mmap_sem); + vma = find_vma(current->mm, vaddr); if (vma && (vma->vm_flags & VM_PFNMAP) && (vma->vm_pgoff)) { if (vb2_get_contig_userptr(vaddr, size, &vma, &physp)) @@ -121,7 +121,6 @@ static void *vb2_vmalloc_get_userptr(void *alloc_ctx, unsigned long vaddr, if (!buf->vaddr) goto fail_get_user_pages; } - up_read(¤t->mm->mmap_sem); buf->vaddr += offset; return buf; @@ -134,7 +133,6 @@ fail_get_user_pages: kfree(buf->pages); fail_pages_array_alloc: - up_read(¤t->mm->mmap_sem); kfree(buf); return NULL; @@ -146,7 +144,6 @@ static void vb2_vmalloc_put_userptr(void *buf_priv) unsigned long vaddr = (unsigned long)buf->vaddr & PAGE_MASK; unsigned int i; - down_read(¤t->mm->mmap_sem); if (buf->pages) { if (vaddr) vm_unmap_ram((void *)vaddr, buf->n_pages); @@ -160,7 +157,6 @@ static void vb2_vmalloc_put_userptr(void *buf_priv) vb2_put_vma(buf->vma); iounmap((__force void __iomem *)buf->vaddr); } - up_read(¤t->mm->mmap_sem); kfree(buf); } -- cgit v1.2.3-59-g8ed1b From 77a3c6fd90c94f635edb00d4a65f485687538791 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 19 Jun 2015 08:50:07 -0300 Subject: [media] vb2: Don't WARN when v4l2_buffer.bytesused is 0 for multiplanar buffers Commit f61bf13b6a07 ("[media] vb2: add allow_zero_bytesused flag to the vb2_queue struct") added a WARN_ONCE to catch usage of a deprecated API using a zero value for v4l2_buffer.bytesused. However, the condition is checked incorrectly, as the v4L2_buffer bytesused field is supposed to be ignored for multiplanar buffers. This results in spurious warnings when using the multiplanar API. Fix it by checking v4l2_buffer.bytesused for uniplanar buffers and v4l2_plane.bytesused for multiplanar buffers. Fixes: f61bf13b6a07 ("[media] vb2: add allow_zero_bytesused flag to the vb2_queue struct") Signed-off-by: Laurent Pinchart Cc: stable@vger.kernel.org # for v4.0 Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-core.c | 33 ++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index d835814a24d4..93b315459098 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -1242,6 +1242,23 @@ void vb2_discard_done(struct vb2_queue *q) } EXPORT_SYMBOL_GPL(vb2_discard_done); +static void vb2_warn_zero_bytesused(struct vb2_buffer *vb) +{ + static bool __check_once __read_mostly; + + if (__check_once) + return; + + __check_once = true; + __WARN(); + + pr_warn_once("use of bytesused == 0 is deprecated and will be removed in the future,\n"); + if (vb->vb2_queue->allow_zero_bytesused) + pr_warn_once("use VIDIOC_DECODER_CMD(V4L2_DEC_CMD_STOP) instead.\n"); + else + pr_warn_once("use the actual size instead.\n"); +} + /** * __fill_vb2_buffer() - fill a vb2_buffer with information provided in a * v4l2_buffer by the userspace. The caller has already verified that struct @@ -1252,16 +1269,6 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b { unsigned int plane; - if (V4L2_TYPE_IS_OUTPUT(b->type)) { - if (WARN_ON_ONCE(b->bytesused == 0)) { - pr_warn_once("use of bytesused == 0 is deprecated and will be removed in the future,\n"); - if (vb->vb2_queue->allow_zero_bytesused) - pr_warn_once("use VIDIOC_DECODER_CMD(V4L2_DEC_CMD_STOP) instead.\n"); - else - pr_warn_once("use the actual size instead.\n"); - } - } - if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) { if (b->memory == V4L2_MEMORY_USERPTR) { for (plane = 0; plane < vb->num_planes; ++plane) { @@ -1302,6 +1309,9 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b struct v4l2_plane *pdst = &v4l2_planes[plane]; struct v4l2_plane *psrc = &b->m.planes[plane]; + if (psrc->bytesused == 0) + vb2_warn_zero_bytesused(vb); + if (vb->vb2_queue->allow_zero_bytesused) pdst->bytesused = psrc->bytesused; else @@ -1336,6 +1346,9 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b } if (V4L2_TYPE_IS_OUTPUT(b->type)) { + if (b->bytesused == 0) + vb2_warn_zero_bytesused(vb); + if (vb->vb2_queue->allow_zero_bytesused) v4l2_planes[0].bytesused = b->bytesused; else -- cgit v1.2.3-59-g8ed1b From 1c8a866d31ec73bd9c7817368fd4c24ca39602de Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 22 Jun 2015 12:19:17 -0300 Subject: [media] bdisp: prevent compiling on random arch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver requires support for DMA attrs function, and not just DMA. Change the options accordingly to remove those errors: /devel/v4l/to_next/drivers/media/platform/sti/bdisp/bdisp-hw.c: In function ‘bdisp_hw_free_nodes’: /devel/v4l/to_next/drivers/media/platform/sti/bdisp/bdisp-hw.c:132:3: error: implicit declaration of function ‘dma_free_attrs’ [-Werror=implicit-function-declaration] dma_free_attrs(ctx->bdisp_dev->dev, ^ /devel/v4l/to_next/drivers/media/platform/sti/bdisp/bdisp-hw.c: In function ‘bdisp_hw_alloc_nodes’: /devel/v4l/to_next/drivers/media/platform/sti/bdisp/bdisp-hw.c:157:9: error: implicit declaration of function ‘dma_alloc_attrs’ [-Werror=implicit-function-declaration] base = dma_alloc_attrs(dev, node_size * MAX_NB_NODE, &paddr, ^ /devel/v4l/to_next/drivers/media/platform/sti/bdisp/bdisp-hw.c:157:7: warning: assignment makes pointer from integer without a cast [-Wint-conversion] base = dma_alloc_attrs(dev, node_size * MAX_NB_NODE, &paddr, ^ /devel/v4l/to_next/drivers/media/platform/sti/bdisp/bdisp-hw.c: In function ‘bdisp_hw_alloc_filters’: /devel/v4l/to_next/drivers/media/platform/sti/bdisp/bdisp-hw.c:219:7: warning: assignment makes pointer from integer without a cast [-Wint-conversion] base = dma_alloc_attrs(dev, size, &paddr, GFP_KERNEL | GFP_DMA, &attrs); Also, get rid of bogus, unused and duplicated symbol declaration for the config option done at bdisp/Kconfig. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/Kconfig | 2 +- drivers/media/platform/sti/bdisp/Kconfig | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) delete mode 100644 drivers/media/platform/sti/bdisp/Kconfig (limited to 'drivers/media') diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 4776a8cb1071..a4e7d21c9e4c 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -216,7 +216,7 @@ config VIDEO_STI_BDISP tristate "STMicroelectronics BDISP 2D blitter driver" depends on VIDEO_DEV && VIDEO_V4L2 depends on ARCH_STI || COMPILE_TEST - depends on HAS_DMA + depends on HAVE_DMA_ATTRS select VIDEOBUF2_DMA_CONTIG select V4L2_MEM2MEM_DEV help diff --git a/drivers/media/platform/sti/bdisp/Kconfig b/drivers/media/platform/sti/bdisp/Kconfig deleted file mode 100644 index afaf4a6ecc72..000000000000 --- a/drivers/media/platform/sti/bdisp/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -config VIDEO_STI_BDISP - tristate "STMicroelectronics BDISP 2D blitter driver" - depends on VIDEO_DEV && VIDEO_V4L2 - select VIDEOBUF2_DMA_CONTIG - select V4L2_MEM2MEM_DEV - help - This v4l2 mem2mem driver is a 2D blitter for STMicroelectronics SoC. - To compile this driver as a module, choose M here: the module will - be called bdisp.ko. -- cgit v1.2.3-59-g8ed1b From dd7a2acf5b7da9449988a99fe671349b3e5ec593 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 22 Jun 2015 15:25:31 -0300 Subject: [media] si470x: cleanup define namespace Some architectures already use CHIPID defines: drivers/media/radio/si470x/radio-si470x.h:57:0: warning: "CHIPID" redefined [enabled by default] drivers/media/radio/si470x/radio-si470x.h:57:0: warning: "CHIPID" redefined [enabled by default] drivers/media/radio/si470x/radio-si470x.h:57:0: warning: "CHIPID" redefined [enabled by default] So, use SI_foo namespace to avoid conflicts. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/si470x/radio-si470x-i2c.c | 6 +++--- drivers/media/radio/si470x/radio-si470x-usb.c | 6 +++--- drivers/media/radio/si470x/radio-si470x.h | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c index 49fe8453e218..471d6a8ae8a4 100644 --- a/drivers/media/radio/si470x/radio-si470x-i2c.c +++ b/drivers/media/radio/si470x/radio-si470x-i2c.c @@ -384,14 +384,14 @@ static int si470x_i2c_probe(struct i2c_client *client, goto err_radio; } dev_info(&client->dev, "DeviceID=0x%4.4hx ChipID=0x%4.4hx\n", - radio->registers[DEVICEID], radio->registers[CHIPID]); - if ((radio->registers[CHIPID] & CHIPID_FIRMWARE) < RADIO_FW_VERSION) { + radio->registers[DEVICEID], radio->registers[SI_CHIPID]); + if ((radio->registers[SI_CHIPID] & SI_CHIPID_FIRMWARE) < RADIO_FW_VERSION) { dev_warn(&client->dev, "This driver is known to work with " "firmware version %hu,\n", RADIO_FW_VERSION); dev_warn(&client->dev, "but the device has firmware version %hu.\n", - radio->registers[CHIPID] & CHIPID_FIRMWARE); + radio->registers[SI_CHIPID] & SI_CHIPID_FIRMWARE); version_warning = 1; } diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c index 57f0bc3b60e7..091d793f6583 100644 --- a/drivers/media/radio/si470x/radio-si470x-usb.c +++ b/drivers/media/radio/si470x/radio-si470x-usb.c @@ -686,14 +686,14 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, goto err_ctrl; } dev_info(&intf->dev, "DeviceID=0x%4.4hx ChipID=0x%4.4hx\n", - radio->registers[DEVICEID], radio->registers[CHIPID]); - if ((radio->registers[CHIPID] & CHIPID_FIRMWARE) < RADIO_FW_VERSION) { + radio->registers[DEVICEID], radio->registers[SI_CHIPID]); + if ((radio->registers[SI_CHIPID] & SI_CHIPID_FIRMWARE) < RADIO_FW_VERSION) { dev_warn(&intf->dev, "This driver is known to work with " "firmware version %hu,\n", RADIO_FW_VERSION); dev_warn(&intf->dev, "but the device has firmware version %hu.\n", - radio->registers[CHIPID] & CHIPID_FIRMWARE); + radio->registers[SI_CHIPID] & SI_CHIPID_FIRMWARE); version_warning = 1; } diff --git a/drivers/media/radio/si470x/radio-si470x.h b/drivers/media/radio/si470x/radio-si470x.h index 4b7660470e2f..6c0ca900702e 100644 --- a/drivers/media/radio/si470x/radio-si470x.h +++ b/drivers/media/radio/si470x/radio-si470x.h @@ -54,10 +54,10 @@ #define DEVICEID_PN 0xf000 /* bits 15..12: Part Number */ #define DEVICEID_MFGID 0x0fff /* bits 11..00: Manufacturer ID */ -#define CHIPID 1 /* Chip ID */ -#define CHIPID_REV 0xfc00 /* bits 15..10: Chip Version */ -#define CHIPID_DEV 0x0200 /* bits 09..09: Device */ -#define CHIPID_FIRMWARE 0x01ff /* bits 08..00: Firmware Version */ +#define SI_CHIPID 1 /* Chip ID */ +#define SI_CHIPID_REV 0xfc00 /* bits 15..10: Chip Version */ +#define SI_CHIPID_DEV 0x0200 /* bits 09..09: Device */ +#define SI_CHIPID_FIRMWARE 0x01ff /* bits 08..00: Firmware Version */ #define POWERCFG 2 /* Power Configuration */ #define POWERCFG_DSMUTE 0x8000 /* bits 15..15: Softmute Disable */ -- cgit v1.2.3-59-g8ed1b From ceefaf5d8e04414a8d9323d6647f36103e8747b7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 22 Jun 2015 16:16:39 -0300 Subject: [media] tuner-i2c: be consistent with I2C declaration On alpha, gcc warns a log about signed/unsigned ballance, with produces 3185 warnings. Ok, this is bogus, but it indicates that the declaration at V4L2 side is not consistent with the one at I2C. With this trivial patch, the number of errors reduce to 2959 warnings. Still too much, but it is 7.1% less. So let's do it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/tuner-i2c.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/tuners/tuner-i2c.h b/drivers/media/tuners/tuner-i2c.h index 18f005634c67..bda67a5a76f2 100644 --- a/drivers/media/tuners/tuner-i2c.h +++ b/drivers/media/tuners/tuner-i2c.h @@ -33,7 +33,8 @@ struct tuner_i2c_props { char *name; }; -static inline int tuner_i2c_xfer_send(struct tuner_i2c_props *props, char *buf, int len) +static inline int tuner_i2c_xfer_send(struct tuner_i2c_props *props, + unsigned char *buf, int len) { struct i2c_msg msg = { .addr = props->addr, .flags = 0, .buf = buf, .len = len }; @@ -42,7 +43,8 @@ static inline int tuner_i2c_xfer_send(struct tuner_i2c_props *props, char *buf, return (ret == 1) ? len : ret; } -static inline int tuner_i2c_xfer_recv(struct tuner_i2c_props *props, char *buf, int len) +static inline int tuner_i2c_xfer_recv(struct tuner_i2c_props *props, + unsigned char *buf, int len) { struct i2c_msg msg = { .addr = props->addr, .flags = I2C_M_RD, .buf = buf, .len = len }; @@ -52,8 +54,8 @@ static inline int tuner_i2c_xfer_recv(struct tuner_i2c_props *props, char *buf, } static inline int tuner_i2c_xfer_send_recv(struct tuner_i2c_props *props, - char *obuf, int olen, - char *ibuf, int ilen) + unsigned char *obuf, int olen, + unsigned char *ibuf, int ilen) { struct i2c_msg msg[2] = { { .addr = props->addr, .flags = 0, .buf = obuf, .len = olen }, -- cgit v1.2.3-59-g8ed1b From 846793b3f926da8224f15c438043f08dd5f11882 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 22 Jun 2015 16:32:53 -0300 Subject: [media] use CONFIG_PM_SLEEP for suspend/resume MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using CONFIG_PM_SLEEP suppress the warnings when the driver is compiled without PM sleep functions: drivers/media/rc/st_rc.c:338:12: warning: ‘st_rc_suspend’ defined but not used [-Wunused-function] drivers/media/rc/st_rc.c:359:12: warning: ‘st_rc_resume’ defined but not used [-Wunused-function] Signed-off-by: Mauro Carvalho Chehab Acked-by: Maxime Coquelin --- drivers/media/rc/st_rc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c index 979b40561b3a..37d040158dff 100644 --- a/drivers/media/rc/st_rc.c +++ b/drivers/media/rc/st_rc.c @@ -334,7 +334,7 @@ err: return ret; } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int st_rc_suspend(struct device *dev) { struct st_rc_device *rc_dev = dev_get_drvdata(dev); -- cgit v1.2.3-59-g8ed1b From 816de50d35743088f18e0da9e03e3347c768b7a2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 22 Jun 2015 16:40:39 -0300 Subject: [media] saa7134: fix page size on some archs On some archs, like tile, the PAGE_SIZE is not 4K. In the case of tile arch, it can be either 16KB or 64KB. Due to that, a warning is produced: drivers/media/pci/saa7134/saa7134.h:678:43: warning: large integer implicitly truncated to unsigned type [-Woverflow] This is actually an error, as it will write trach to the DMA size registers. The logic at saa7134-ts already does the right thing: saa_writeb(SAA7134_TS_DMA0, ((dev->ts.nr_packets-1)&0xff)); saa_writeb(SAA7134_TS_DMA1, (((dev->ts.nr_packets-1)>>8)&0xff)); /* TSNOPIT=0, TSCOLAP=0 */ saa_writeb(SAA7134_TS_DMA2, ((((dev->ts.nr_packets-1)>>16)&0x3f) | 0x00)); So, fix the driver to take larger page sizes into account. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-go7007.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/pci/saa7134/saa7134-go7007.c b/drivers/media/pci/saa7134/saa7134-go7007.c index da7c4be4bed2..8a2abb34186b 100644 --- a/drivers/media/pci/saa7134/saa7134-go7007.c +++ b/drivers/media/pci/saa7134/saa7134-go7007.c @@ -289,9 +289,9 @@ static int saa7134_go7007_stream_start(struct go7007 *go) /* Set up transfer block size */ saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 128 - 1); - saa_writeb(SAA7134_TS_DMA0, (PAGE_SIZE >> 7) - 1); - saa_writeb(SAA7134_TS_DMA1, 0); - saa_writeb(SAA7134_TS_DMA2, 0); + saa_writeb(SAA7134_TS_DMA0, ((PAGE_SIZE >> 7) - 1) & 0xff); + saa_writeb(SAA7134_TS_DMA1, (PAGE_SIZE >> 15) & 0xff); + saa_writeb(SAA7134_TS_DMA2, (PAGE_SIZE >> 31) & 0x3f); /* Enable video streaming mode */ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_VIDEO); -- cgit v1.2.3-59-g8ed1b From 7fd6bd9df1868983ce59ca8fd5d796c5b63100a5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 23 Jun 2015 10:23:43 -0300 Subject: [media] omap3isp: remove unused var MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/media/platform/omap3isp/isppreview.c:932:6: warning: variable ‘features’ set but not used [-Wunused-but-set-variable] Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/isppreview.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c index 15cb254ccc39..13803270d104 100644 --- a/drivers/media/platform/omap3isp/isppreview.c +++ b/drivers/media/platform/omap3isp/isppreview.c @@ -929,14 +929,10 @@ static void preview_setup_hw(struct isp_prev_device *prev, u32 update, u32 active) { unsigned int i; - u32 features; if (update == 0) return; - features = (prev->params.params[0].features & active) - | (prev->params.params[1].features & ~active); - for (i = 0; i < ARRAY_SIZE(update_attrs); i++) { const struct preview_update *attr = &update_attrs[i]; struct prev_params *params; -- cgit v1.2.3-59-g8ed1b From 5ae65db547f3a9887d4edfa2c272879a72fd4f5f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 23 Jun 2015 12:22:06 -0300 Subject: [media] lmedm04: use u32 instead of u64 for relative stats Cleanup this sparse warning: drivers/media/usb/dvb-usb-v2/lmedm04.c:302 lme2510_update_stats() warn: should '((255 - st->signal_sn - 161) * 3) << 8' be a 64 bit type? Both c_tmp and s_tmp actually stores a u16 stat. Using a u64 data there is a waste, specially on u32 archs, as 64 ints there are more expensive. So, change the types to u32 and do the typecast only when storing the result. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/lmedm04.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c index 57fb184184bf..fcef2a33ef3d 100644 --- a/drivers/media/usb/dvb-usb-v2/lmedm04.c +++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c @@ -262,7 +262,7 @@ static void lme2510_update_stats(struct dvb_usb_adapter *adap) struct lme2510_state *st = adap_to_priv(adap); struct dvb_frontend *fe = adap->fe[0]; struct dtv_frontend_properties *c; - u64 s_tmp = 0, c_tmp = 0; + u32 s_tmp = 0, c_tmp = 0; if (!fe) return; @@ -309,11 +309,11 @@ static void lme2510_update_stats(struct dvb_usb_adapter *adap) c->strength.len = 1; c->strength.stat[0].scale = FE_SCALE_RELATIVE; - c->strength.stat[0].uvalue = s_tmp; + c->strength.stat[0].uvalue = (u64)s_tmp; c->cnr.len = 1; c->cnr.stat[0].scale = FE_SCALE_RELATIVE; - c->cnr.stat[0].uvalue = c_tmp; + c->cnr.stat[0].uvalue = (u64)c_tmp; } static void lme2510_int_response(struct urb *lme_urb) -- cgit v1.2.3-59-g8ed1b From faebbd8f134f0c054f372982c8ddd1bbcc41b440 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 23 Jun 2015 12:29:46 -0300 Subject: [media] lmedm04: fix the range for relative measurements Relative measurements are typically between 0 and 0xffff. However, for some tuners (TUNER_S7395 and TUNER_S0194), the range were from 0 to 0xff00, with means that 100% is never archived. Also, TUNER_RS2000 uses a more complex math. So, create a macro that does the conversion using bit operations and use it for all conversions. The code is also easier to read with is a bonus. While here, remove a bogus comment. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/lmedm04.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c index fcef2a33ef3d..4cc55b3a0558 100644 --- a/drivers/media/usb/dvb-usb-v2/lmedm04.c +++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c @@ -257,6 +257,9 @@ static int lme2510_enable_pid(struct dvb_usb_device *d, u8 index, u16 pid_out) return ret; } +/* Convert range from 0x00-0xff to 0x0000-0xffff */ +#define reg_to_16bits(x) ((x) | ((x) << 8)) + static void lme2510_update_stats(struct dvb_usb_adapter *adap) { struct lme2510_state *st = adap_to_priv(adap); @@ -288,23 +291,17 @@ static void lme2510_update_stats(struct dvb_usb_adapter *adap) switch (st->tuner_config) { case TUNER_LG: - s_tmp = 0xff - st->signal_level; - s_tmp |= s_tmp << 8; - - c_tmp = 0xff - st->signal_sn; - c_tmp |= c_tmp << 8; + s_tmp = reg_to_16bits(0xff - st->signal_level); + c_tmp = reg_to_16bits(0xff - st->signal_sn); break; - /* fall through */ case TUNER_S7395: case TUNER_S0194: s_tmp = 0xffff - (((st->signal_level * 2) << 8) * 5 / 4); - - c_tmp = ((0xff - st->signal_sn - 0xa1) * 3) << 8; + c_tmp = reg_to_16bits((0xff - st->signal_sn - 0xa1) * 3); break; case TUNER_RS2000: - s_tmp = st->signal_level * 0xffff / 0xff; - - c_tmp = st->signal_sn * 0xffff / 0x7f; + s_tmp = reg_to_16bits(st->signal_level); + c_tmp = reg_to_16bits(st->signal_sn); } c->strength.len = 1; -- cgit v1.2.3-59-g8ed1b