| .. | .. |
|---|
| 41 | 41 | #include <linux/v4l2-dv-timings.h> |
|---|
| 42 | 42 | #include <linux/hdmi.h> |
|---|
| 43 | 43 | #include <linux/version.h> |
|---|
| 44 | +#include <linux/compat.h> |
|---|
| 44 | 45 | #include <linux/rk-camera-module.h> |
|---|
| 45 | 46 | #include <media/v4l2-dv-timings.h> |
|---|
| 46 | 47 | #include <media/v4l2-device.h> |
|---|
| .. | .. |
|---|
| 1517 | 1518 | static irqreturn_t tc35874x_irq_handler(int irq, void *dev_id) |
|---|
| 1518 | 1519 | { |
|---|
| 1519 | 1520 | struct tc35874x_state *state = dev_id; |
|---|
| 1520 | | - bool handled; |
|---|
| 1521 | + bool handled = false; |
|---|
| 1521 | 1522 | |
|---|
| 1522 | 1523 | tc35874x_isr(&state->sd, 0, &handled); |
|---|
| 1523 | 1524 | |
|---|
| .. | .. |
|---|
| 1660 | 1661 | } |
|---|
| 1661 | 1662 | |
|---|
| 1662 | 1663 | static int tc35874x_g_mbus_config(struct v4l2_subdev *sd, |
|---|
| 1663 | | - struct v4l2_mbus_config *cfg) |
|---|
| 1664 | + unsigned int pad, struct v4l2_mbus_config *cfg) |
|---|
| 1664 | 1665 | { |
|---|
| 1665 | 1666 | struct tc35874x_state *state = to_state(sd); |
|---|
| 1666 | 1667 | |
|---|
| 1667 | | - cfg->type = V4L2_MBUS_CSI2; |
|---|
| 1668 | + cfg->type = V4L2_MBUS_CSI2_DPHY; |
|---|
| 1668 | 1669 | |
|---|
| 1669 | 1670 | /* Support for non-continuous CSI-2 clock is missing in the driver */ |
|---|
| 1670 | 1671 | cfg->flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; |
|---|
| .. | .. |
|---|
| 1747 | 1748 | if (fie->index >= ARRAY_SIZE(supported_modes)) |
|---|
| 1748 | 1749 | return -EINVAL; |
|---|
| 1749 | 1750 | |
|---|
| 1750 | | - if (fie->code != MEDIA_BUS_FMT_UYVY8_2X8) |
|---|
| 1751 | | - return -EINVAL; |
|---|
| 1751 | + fie->code = MEDIA_BUS_FMT_UYVY8_2X8; |
|---|
| 1752 | 1752 | |
|---|
| 1753 | 1753 | fie->width = supported_modes[fie->index].width; |
|---|
| 1754 | 1754 | fie->height = supported_modes[fie->index].height; |
|---|
| .. | .. |
|---|
| 1997 | 1997 | } |
|---|
| 1998 | 1998 | |
|---|
| 1999 | 1999 | ret = tc35874x_ioctl(sd, cmd, inf); |
|---|
| 2000 | | - if (!ret) |
|---|
| 2000 | + if (!ret) { |
|---|
| 2001 | 2001 | ret = copy_to_user(up, inf, sizeof(*inf)); |
|---|
| 2002 | + if (ret) |
|---|
| 2003 | + ret = -EFAULT; |
|---|
| 2004 | + } |
|---|
| 2002 | 2005 | kfree(inf); |
|---|
| 2003 | 2006 | break; |
|---|
| 2004 | 2007 | case RKMODULE_AWB_CFG: |
|---|
| .. | .. |
|---|
| 2011 | 2014 | ret = copy_from_user(cfg, up, sizeof(*cfg)); |
|---|
| 2012 | 2015 | if (!ret) |
|---|
| 2013 | 2016 | ret = tc35874x_ioctl(sd, cmd, cfg); |
|---|
| 2017 | + else |
|---|
| 2018 | + ret = -EFAULT; |
|---|
| 2014 | 2019 | kfree(cfg); |
|---|
| 2015 | 2020 | break; |
|---|
| 2016 | 2021 | default: |
|---|
| .. | .. |
|---|
| 2048 | 2053 | .s_dv_timings = tc35874x_s_dv_timings, |
|---|
| 2049 | 2054 | .g_dv_timings = tc35874x_g_dv_timings, |
|---|
| 2050 | 2055 | .query_dv_timings = tc35874x_query_dv_timings, |
|---|
| 2051 | | - .g_mbus_config = tc35874x_g_mbus_config, |
|---|
| 2052 | 2056 | .s_stream = tc35874x_s_stream, |
|---|
| 2053 | 2057 | .g_frame_interval = tc35874x_g_frame_interval, |
|---|
| 2054 | 2058 | }; |
|---|
| .. | .. |
|---|
| 2063 | 2067 | .set_edid = tc35874x_s_edid, |
|---|
| 2064 | 2068 | .enum_dv_timings = tc35874x_enum_dv_timings, |
|---|
| 2065 | 2069 | .dv_timings_cap = tc35874x_dv_timings_cap, |
|---|
| 2070 | + .get_mbus_config = tc35874x_g_mbus_config, |
|---|
| 2066 | 2071 | }; |
|---|
| 2067 | 2072 | |
|---|
| 2068 | 2073 | static const struct v4l2_subdev_ops tc35874x_ops = { |
|---|
| .. | .. |
|---|
| 2129 | 2134 | static int tc35874x_probe_of(struct tc35874x_state *state) |
|---|
| 2130 | 2135 | { |
|---|
| 2131 | 2136 | struct device *dev = &state->i2c_client->dev; |
|---|
| 2132 | | - struct v4l2_fwnode_endpoint *endpoint; |
|---|
| 2137 | + struct v4l2_fwnode_endpoint endpoint = { .bus_type = 0 }; |
|---|
| 2133 | 2138 | struct device_node *ep; |
|---|
| 2134 | 2139 | struct clk *refclk; |
|---|
| 2135 | 2140 | u32 bps_pr_lane; |
|---|
| .. | .. |
|---|
| 2149 | 2154 | return -EINVAL; |
|---|
| 2150 | 2155 | } |
|---|
| 2151 | 2156 | |
|---|
| 2152 | | - endpoint = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(ep)); |
|---|
| 2153 | | - if (IS_ERR(endpoint)) { |
|---|
| 2157 | + ret = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(ep), &endpoint); |
|---|
| 2158 | + if (ret) { |
|---|
| 2154 | 2159 | dev_err(dev, "failed to parse endpoint\n"); |
|---|
| 2155 | | - return PTR_ERR(endpoint); |
|---|
| 2160 | + goto put_node; |
|---|
| 2156 | 2161 | } |
|---|
| 2157 | 2162 | |
|---|
| 2158 | | - if (endpoint->bus_type != V4L2_MBUS_CSI2 || |
|---|
| 2159 | | - endpoint->bus.mipi_csi2.num_data_lanes == 0 || |
|---|
| 2160 | | - endpoint->nr_of_link_frequencies == 0) { |
|---|
| 2163 | + if (endpoint.bus_type != V4L2_MBUS_CSI2_DPHY || |
|---|
| 2164 | + endpoint.bus.mipi_csi2.num_data_lanes == 0 || |
|---|
| 2165 | + endpoint.nr_of_link_frequencies == 0) { |
|---|
| 2161 | 2166 | dev_err(dev, "missing CSI-2 properties in endpoint\n"); |
|---|
| 2162 | 2167 | goto free_endpoint; |
|---|
| 2163 | 2168 | } |
|---|
| 2164 | 2169 | |
|---|
| 2165 | | - state->csi_lanes_in_use = endpoint->bus.mipi_csi2.num_data_lanes; |
|---|
| 2166 | | - state->bus = endpoint->bus.mipi_csi2; |
|---|
| 2170 | + state->csi_lanes_in_use = endpoint.bus.mipi_csi2.num_data_lanes; |
|---|
| 2171 | + state->bus = endpoint.bus.mipi_csi2; |
|---|
| 2167 | 2172 | |
|---|
| 2168 | 2173 | ret = clk_prepare_enable(refclk); |
|---|
| 2169 | 2174 | if (ret) { |
|---|
| .. | .. |
|---|
| 2196 | 2201 | * The CSI bps per lane must be between 62.5 Mbps and 1 Gbps. |
|---|
| 2197 | 2202 | * The default is 594 Mbps for 4-lane 1080p60 or 2-lane 720p60. |
|---|
| 2198 | 2203 | */ |
|---|
| 2199 | | - bps_pr_lane = 2 * endpoint->link_frequencies[0]; |
|---|
| 2204 | + bps_pr_lane = 2 * endpoint.link_frequencies[0]; |
|---|
| 2200 | 2205 | if (bps_pr_lane < 62500000U || bps_pr_lane > 1000000000U) { |
|---|
| 2201 | 2206 | dev_err(dev, "unsupported bps per lane: %u bps\n", bps_pr_lane); |
|---|
| 2202 | 2207 | goto disable_clk; |
|---|
| .. | .. |
|---|
| 2242 | 2247 | disable_clk: |
|---|
| 2243 | 2248 | clk_disable_unprepare(refclk); |
|---|
| 2244 | 2249 | free_endpoint: |
|---|
| 2245 | | - v4l2_fwnode_endpoint_free(endpoint); |
|---|
| 2250 | + v4l2_fwnode_endpoint_free(&endpoint); |
|---|
| 2251 | +put_node: |
|---|
| 2252 | + of_node_put(ep); |
|---|
| 2246 | 2253 | return ret; |
|---|
| 2247 | 2254 | } |
|---|
| 2248 | 2255 | #else |
|---|