.. | .. |
---|
107 | 107 | |
---|
108 | 108 | #define GC4C33_NUM_SUPPLIES ARRAY_SIZE(gc4c33_supply_names) |
---|
109 | 109 | |
---|
110 | | -enum gc4c33_max_pad { |
---|
111 | | - PAD0, /* link to isp */ |
---|
112 | | - PAD1, /* link to csi wr0 | hdr x2:L x3:M */ |
---|
113 | | - PAD2, /* link to csi wr1 | hdr x3:L */ |
---|
114 | | - PAD3, /* link to csi wr2 | hdr x2:M x3:S */ |
---|
115 | | - PAD_MAX, |
---|
116 | | -}; |
---|
117 | | - |
---|
118 | 110 | struct regval { |
---|
119 | 111 | u16 addr; |
---|
120 | 112 | u8 val; |
---|
.. | .. |
---|
1322 | 1314 | fmt->format.height = mode->height; |
---|
1323 | 1315 | fmt->format.code = mode->bus_fmt; |
---|
1324 | 1316 | fmt->format.field = V4L2_FIELD_NONE; |
---|
1325 | | - /* format info: width/height/data type/virctual channel */ |
---|
1326 | | - if (fmt->pad < PAD_MAX && mode->hdr_mode != NO_HDR) |
---|
1327 | | - fmt->reserved[0] = mode->vc[fmt->pad]; |
---|
1328 | | - else |
---|
1329 | | - fmt->reserved[0] = mode->vc[PAD0]; |
---|
1330 | 1317 | } |
---|
1331 | 1318 | mutex_unlock(&gc4c33->mutex); |
---|
1332 | 1319 | |
---|
.. | .. |
---|
1523 | 1510 | struct gc4c33 *gc4c33 = to_gc4c33(sd); |
---|
1524 | 1511 | const struct gc4c33_mode *mode = gc4c33->cur_mode; |
---|
1525 | 1512 | |
---|
1526 | | - mutex_lock(&gc4c33->mutex); |
---|
1527 | 1513 | fi->interval = mode->max_fps; |
---|
1528 | | - mutex_unlock(&gc4c33->mutex); |
---|
1529 | 1514 | |
---|
1530 | 1515 | return 0; |
---|
1531 | 1516 | } |
---|
1532 | 1517 | |
---|
1533 | | -static int gc4c33_g_mbus_config(struct v4l2_subdev *sd, |
---|
| 1518 | +static int gc4c33_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id, |
---|
1534 | 1519 | struct v4l2_mbus_config *config) |
---|
1535 | 1520 | { |
---|
1536 | 1521 | struct gc4c33 *gc4c33 = to_gc4c33(sd); |
---|
.. | .. |
---|
1544 | 1529 | if (mode->hdr_mode == HDR_X3) |
---|
1545 | 1530 | val |= V4L2_MBUS_CSI2_CHANNEL_2; |
---|
1546 | 1531 | |
---|
1547 | | - config->type = V4L2_MBUS_CSI2; |
---|
| 1532 | + config->type = V4L2_MBUS_CSI2_DPHY; |
---|
1548 | 1533 | config->flags = val; |
---|
1549 | 1534 | |
---|
1550 | 1535 | return 0; |
---|
.. | .. |
---|
1560 | 1545 | strlcpy(inf->base.lens, gc4c33->len_name, sizeof(inf->base.lens)); |
---|
1561 | 1546 | } |
---|
1562 | 1547 | |
---|
| 1548 | +static int gc4c33_get_channel_info(struct gc4c33 *gc4c33, struct rkmodule_channel_info *ch_info) |
---|
| 1549 | +{ |
---|
| 1550 | + if (ch_info->index < PAD0 || ch_info->index >= PAD_MAX) |
---|
| 1551 | + return -EINVAL; |
---|
| 1552 | + ch_info->vc = gc4c33->cur_mode->vc[ch_info->index]; |
---|
| 1553 | + ch_info->width = gc4c33->cur_mode->width; |
---|
| 1554 | + ch_info->height = gc4c33->cur_mode->height; |
---|
| 1555 | + ch_info->bus_fmt = gc4c33->cur_mode->bus_fmt; |
---|
| 1556 | + return 0; |
---|
| 1557 | +} |
---|
| 1558 | + |
---|
1563 | 1559 | static long gc4c33_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) |
---|
1564 | 1560 | { |
---|
1565 | 1561 | struct gc4c33 *gc4c33 = to_gc4c33(sd); |
---|
.. | .. |
---|
1568 | 1564 | u32 i, h, w; |
---|
1569 | 1565 | long ret = 0; |
---|
1570 | 1566 | u32 stream = 0; |
---|
| 1567 | + struct rkmodule_channel_info *ch_info; |
---|
1571 | 1568 | |
---|
1572 | 1569 | switch (cmd) { |
---|
1573 | 1570 | case RKMODULE_GET_MODULE_INFO: |
---|
.. | .. |
---|
1629 | 1626 | ret = gc4c33_write_reg(gc4c33->client, GC4C33_REG_CTRL_MODE, |
---|
1630 | 1627 | GC4C33_REG_VALUE_08BIT, GC4C33_MODE_SW_STANDBY); |
---|
1631 | 1628 | break; |
---|
| 1629 | + case RKMODULE_GET_CHANNEL_INFO: |
---|
| 1630 | + ch_info = (struct rkmodule_channel_info *)arg; |
---|
| 1631 | + ret = gc4c33_get_channel_info(gc4c33, ch_info); |
---|
| 1632 | + break; |
---|
1632 | 1633 | default: |
---|
1633 | 1634 | ret = -ENOIOCTLCMD; |
---|
1634 | 1635 | break; |
---|
.. | .. |
---|
1650 | 1651 | struct rkmodule_nr_switch_threshold *nr_switch; |
---|
1651 | 1652 | long ret; |
---|
1652 | 1653 | u32 stream = 0; |
---|
| 1654 | + struct rkmodule_channel_info *ch_info; |
---|
1653 | 1655 | |
---|
1654 | 1656 | switch (cmd) { |
---|
1655 | 1657 | case RKMODULE_GET_MODULE_INFO: |
---|
.. | .. |
---|
1660 | 1662 | } |
---|
1661 | 1663 | |
---|
1662 | 1664 | ret = gc4c33_ioctl(sd, cmd, inf); |
---|
1663 | | - if (!ret) |
---|
| 1665 | + if (!ret) { |
---|
1664 | 1666 | ret = copy_to_user(up, inf, sizeof(*inf)); |
---|
| 1667 | + if (ret) |
---|
| 1668 | + ret = -EFAULT; |
---|
| 1669 | + } |
---|
1665 | 1670 | kfree(inf); |
---|
1666 | 1671 | break; |
---|
1667 | 1672 | case RKMODULE_AWB_CFG: |
---|
.. | .. |
---|
1674 | 1679 | ret = copy_from_user(cfg, up, sizeof(*cfg)); |
---|
1675 | 1680 | if (!ret) |
---|
1676 | 1681 | ret = gc4c33_ioctl(sd, cmd, cfg); |
---|
| 1682 | + else |
---|
| 1683 | + ret = -EFAULT; |
---|
1677 | 1684 | kfree(cfg); |
---|
1678 | 1685 | break; |
---|
1679 | 1686 | case RKMODULE_GET_HDR_CFG: |
---|
.. | .. |
---|
1684 | 1691 | } |
---|
1685 | 1692 | |
---|
1686 | 1693 | ret = gc4c33_ioctl(sd, cmd, hdr); |
---|
1687 | | - if (!ret) |
---|
| 1694 | + if (!ret) { |
---|
1688 | 1695 | ret = copy_to_user(up, hdr, sizeof(*hdr)); |
---|
| 1696 | + if (ret) |
---|
| 1697 | + ret = -EFAULT; |
---|
| 1698 | + } |
---|
1689 | 1699 | kfree(hdr); |
---|
1690 | 1700 | break; |
---|
1691 | 1701 | case RKMODULE_SET_HDR_CFG: |
---|
.. | .. |
---|
1698 | 1708 | ret = copy_from_user(hdr, up, sizeof(*hdr)); |
---|
1699 | 1709 | if (!ret) |
---|
1700 | 1710 | ret = gc4c33_ioctl(sd, cmd, hdr); |
---|
| 1711 | + else |
---|
| 1712 | + ret = -EFAULT; |
---|
1701 | 1713 | kfree(hdr); |
---|
1702 | 1714 | break; |
---|
1703 | 1715 | case RKMODULE_SET_DPCC_CFG: |
---|
.. | .. |
---|
1710 | 1722 | ret = copy_from_user(dpcc, up, sizeof(*dpcc)); |
---|
1711 | 1723 | if (!ret) |
---|
1712 | 1724 | ret = gc4c33_ioctl(sd, cmd, dpcc); |
---|
| 1725 | + else |
---|
| 1726 | + ret = -EFAULT; |
---|
1713 | 1727 | kfree(dpcc); |
---|
1714 | 1728 | break; |
---|
1715 | 1729 | case PREISP_CMD_SET_HDRAE_EXP: |
---|
.. | .. |
---|
1722 | 1736 | ret = copy_from_user(hdrae, up, sizeof(*hdrae)); |
---|
1723 | 1737 | if (!ret) |
---|
1724 | 1738 | ret = gc4c33_ioctl(sd, cmd, hdrae); |
---|
| 1739 | + else |
---|
| 1740 | + ret = -EFAULT; |
---|
1725 | 1741 | kfree(hdrae); |
---|
1726 | 1742 | break; |
---|
1727 | 1743 | case RKMODULE_GET_NR_SWITCH_THRESHOLD: |
---|
.. | .. |
---|
1732 | 1748 | } |
---|
1733 | 1749 | |
---|
1734 | 1750 | ret = gc4c33_ioctl(sd, cmd, nr_switch); |
---|
1735 | | - if (!ret) |
---|
| 1751 | + if (!ret) { |
---|
1736 | 1752 | ret = copy_to_user(up, nr_switch, sizeof(*nr_switch)); |
---|
| 1753 | + if (ret) |
---|
| 1754 | + ret = -EFAULT; |
---|
| 1755 | + } |
---|
1737 | 1756 | kfree(nr_switch); |
---|
1738 | 1757 | break; |
---|
1739 | 1758 | case RKMODULE_SET_QUICK_STREAM: |
---|
1740 | 1759 | ret = copy_from_user(&stream, up, sizeof(u32)); |
---|
1741 | 1760 | if (!ret) |
---|
1742 | 1761 | ret = gc4c33_ioctl(sd, cmd, &stream); |
---|
| 1762 | + else |
---|
| 1763 | + ret = -EFAULT; |
---|
| 1764 | + break; |
---|
| 1765 | + case RKMODULE_GET_CHANNEL_INFO: |
---|
| 1766 | + ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL); |
---|
| 1767 | + if (!ch_info) { |
---|
| 1768 | + ret = -ENOMEM; |
---|
| 1769 | + return ret; |
---|
| 1770 | + } |
---|
| 1771 | + |
---|
| 1772 | + ret = gc4c33_ioctl(sd, cmd, ch_info); |
---|
| 1773 | + if (!ret) { |
---|
| 1774 | + ret = copy_to_user(up, ch_info, sizeof(*ch_info)); |
---|
| 1775 | + if (ret) |
---|
| 1776 | + ret = -EFAULT; |
---|
| 1777 | + } |
---|
| 1778 | + kfree(ch_info); |
---|
1743 | 1779 | break; |
---|
1744 | 1780 | default: |
---|
1745 | 1781 | ret = -ENOIOCTLCMD; |
---|
.. | .. |
---|
2046 | 2082 | gpiod_set_value_cansleep(gc4c33->pwren_gpio, 0); |
---|
2047 | 2083 | } |
---|
2048 | 2084 | |
---|
2049 | | -static int gc4c33_runtime_resume(struct device *dev) |
---|
| 2085 | +static int __maybe_unused gc4c33_runtime_resume(struct device *dev) |
---|
2050 | 2086 | { |
---|
2051 | 2087 | struct i2c_client *client = to_i2c_client(dev); |
---|
2052 | 2088 | struct v4l2_subdev *sd = i2c_get_clientdata(client); |
---|
.. | .. |
---|
2055 | 2091 | return __gc4c33_power_on(gc4c33); |
---|
2056 | 2092 | } |
---|
2057 | 2093 | |
---|
2058 | | -static int gc4c33_runtime_suspend(struct device *dev) |
---|
| 2094 | +static int __maybe_unused gc4c33_runtime_suspend(struct device *dev) |
---|
2059 | 2095 | { |
---|
2060 | 2096 | struct i2c_client *client = to_i2c_client(dev); |
---|
2061 | 2097 | struct v4l2_subdev *sd = i2c_get_clientdata(client); |
---|
.. | .. |
---|
2127 | 2163 | static const struct v4l2_subdev_video_ops gc4c33_video_ops = { |
---|
2128 | 2164 | .s_stream = gc4c33_s_stream, |
---|
2129 | 2165 | .g_frame_interval = gc4c33_g_frame_interval, |
---|
2130 | | - .g_mbus_config = gc4c33_g_mbus_config, |
---|
2131 | 2166 | }; |
---|
2132 | 2167 | |
---|
2133 | 2168 | static const struct v4l2_subdev_pad_ops gc4c33_pad_ops = { |
---|
.. | .. |
---|
2136 | 2171 | .enum_frame_interval = gc4c33_enum_frame_interval, |
---|
2137 | 2172 | .get_fmt = gc4c33_get_fmt, |
---|
2138 | 2173 | .set_fmt = gc4c33_set_fmt, |
---|
| 2174 | + .get_mbus_config = gc4c33_g_mbus_config, |
---|
2139 | 2175 | }; |
---|
2140 | 2176 | |
---|
2141 | 2177 | static const struct v4l2_subdev_ops gc4c33_subdev_ops = { |
---|