Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'topic/exynos' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull exynos media updates from Mauro Carvalho Chehab:
"These are the remaining patches I have for the merge windows. It
basically adds a new sensor and adds the needed DT bits for it to
work"

* 'topic/exynos' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media:
[media] s5p-fimc: Remove reference to outdated macro
[media] s5p-jpeg: Fix broken indentation in jpeg-regs.h
[media] exynos4-is: Add the FIMC-IS ISP capture DMA driver
[media] exynos4-is: Add support for asynchronous subdevices registration
[media] exynos4-is: Add clock provider for the SCLK_CAM clock outputs
[media] exynos4-is: Use external s5k6a3 sensor driver
[media] V4L: s5c73m3: Add device tree support
[media] V4L: Add driver for s5k6a3 image sensor
[media] Documentation: devicetree: Update Samsung FIMC DT binding
[media] Documentation: dt: Add binding documentation for S5C73M3 camera
[media] Documentation: dt: Add binding documentation for S5K6A3 image sensor

+1888 -567
+29 -15
Documentation/devicetree/bindings/media/samsung-fimc.txt
··· 15 15 16 16 Required properties: 17 17 18 - - compatible : must be "samsung,fimc", "simple-bus" 19 - - clocks : list of clock specifiers, corresponding to entries in 20 - the clock-names property; 21 - - clock-names : must contain "sclk_cam0", "sclk_cam1", "pxl_async0", 22 - "pxl_async1" entries, matching entries in the clocks property. 18 + - compatible: must be "samsung,fimc", "simple-bus" 19 + - clocks: list of clock specifiers, corresponding to entries in 20 + the clock-names property; 21 + - clock-names : must contain "sclk_cam0", "sclk_cam1", "pxl_async0", 22 + "pxl_async1" entries, matching entries in the clocks property. 23 + 24 + - #clock-cells: from the common clock bindings (../clock/clock-bindings.txt), 25 + must be 1. A clock provider is associated with the 'camera' node and it should 26 + be referenced by external sensors that use clocks provided by the SoC on 27 + CAM_*_CLKOUT pins. The clock specifier cell stores an index of a clock. 28 + The indices are 0, 1 for CAM_A_CLKOUT, CAM_B_CLKOUT clocks respectively. 29 + 30 + - clock-output-names: from the common clock bindings, should contain names of 31 + clocks registered by the camera subsystem corresponding to CAM_A_CLKOUT, 32 + CAM_B_CLKOUT output clocks respectively. 23 33 24 34 The pinctrl bindings defined in ../pinctrl/pinctrl-bindings.txt must be used 25 35 to define a required pinctrl state named "default" and optional pinctrl states: ··· 41 31 way around. 42 32 43 33 The 'camera' node must include at least one 'fimc' child node. 34 + 44 35 45 36 'fimc' device nodes 46 37 ------------------- ··· 99 88 100 89 Optional properties 101 90 102 - - samsung,camclk-out : specifies clock output for remote sensor, 103 - 0 - CAM_A_CLKOUT, 1 - CAM_B_CLKOUT; 91 + - samsung,camclk-out (deprecated) : specifies clock output for remote sensor, 92 + 0 - CAM_A_CLKOUT, 1 - CAM_B_CLKOUT; 104 93 105 94 Image sensor nodes 106 95 ------------------ ··· 108 97 The sensor device nodes should be added to their control bus controller (e.g. 109 98 I2C0) nodes and linked to a port node in the csis or the parallel-ports node, 110 99 using the common video interfaces bindings, defined in video-interfaces.txt. 111 - The implementation of this bindings requires clock-frequency property to be 112 - present in the sensor device nodes. 113 100 114 101 Example: 115 102 ··· 123 114 vddio-supply = <...>; 124 115 125 116 clock-frequency = <24000000>; 126 - clocks = <...>; 117 + clocks = <&camera 1>; 127 118 clock-names = "mclk"; 128 119 129 120 port { ··· 144 135 vddio-supply = <...>; 145 136 146 137 clock-frequency = <24000000>; 147 - clocks = <...>; 138 + clocks = <&camera 0>; 148 139 clock-names = "mclk"; 149 140 150 141 port { ··· 158 149 159 150 camera { 160 151 compatible = "samsung,fimc", "simple-bus"; 161 - #address-cells = <1>; 162 - #size-cells = <1>; 163 - status = "okay"; 164 - 152 + clocks = <&clock 132>, <&clock 133>, <&clock 351>, 153 + <&clock 352>; 154 + clock-names = "sclk_cam0", "sclk_cam1", "pxl_async0", 155 + "pxl_async1"; 156 + #clock-cells = <1>; 157 + clock-output-names = "cam_a_clkout", "cam_b_clkout"; 165 158 pinctrl-names = "default"; 166 159 pinctrl-0 = <&cam_port_a_clk_active>; 160 + status = "okay"; 161 + #address-cells = <1>; 162 + #size-cells = <1>; 167 163 168 164 /* parallel camera ports */ 169 165 parallel-ports {
+97
Documentation/devicetree/bindings/media/samsung-s5c73m3.txt
··· 1 + Samsung S5C73M3 8Mp camera ISP 2 + ------------------------------ 3 + 4 + The S5C73M3 camera ISP supports MIPI CSI-2 and parallel (ITU-R BT.656) video 5 + data busses. The I2C bus is the main control bus and additionally the SPI bus 6 + is used, mostly for transferring the firmware to and from the device. Two 7 + slave device nodes corresponding to these control bus interfaces are required 8 + and should be placed under respective bus controller nodes. 9 + 10 + I2C slave device node 11 + --------------------- 12 + 13 + Required properties: 14 + 15 + - compatible : "samsung,s5c73m3"; 16 + - reg : I2C slave address of the sensor; 17 + - vdd-int-supply : digital power supply (1.2V); 18 + - vdda-supply : analog power supply (1.2V); 19 + - vdd-reg-supply : regulator input power supply (2.8V); 20 + - vddio-host-supply : host I/O power supply (1.8V to 2.8V); 21 + - vddio-cis-supply : CIS I/O power supply (1.2V to 1.8V); 22 + - vdd-af-supply : lens power supply (2.8V); 23 + - xshutdown-gpios : specifier of GPIO connected to the XSHUTDOWN pin; 24 + - standby-gpios : specifier of GPIO connected to the STANDBY pin; 25 + - clocks : should contain list of phandle and clock specifier pairs 26 + according to common clock bindings for the clocks described 27 + in the clock-names property; 28 + - clock-names : should contain "cis_extclk" entry for the CIS_EXTCLK clock; 29 + 30 + Optional properties: 31 + 32 + - clock-frequency : the frequency at which the "cis_extclk" clock should be 33 + configured to operate, in Hz; if this property is not 34 + specified default 24 MHz value will be used. 35 + 36 + The common video interfaces bindings (see video-interfaces.txt) should be used 37 + to specify link from the S5C73M3 to an external image data receiver. The S5C73M3 38 + device node should contain one 'port' child node with an 'endpoint' subnode for 39 + this purpose. The data link from a raw image sensor to the S5C73M3 can be 40 + similarly specified, but it is optional since the S5C73M3 ISP and a raw image 41 + sensor are usually inseparable and form a hybrid module. 42 + 43 + Following properties are valid for the endpoint node(s): 44 + 45 + endpoint subnode 46 + ---------------- 47 + 48 + - data-lanes : (optional) specifies MIPI CSI-2 data lanes as covered in 49 + video-interfaces.txt. This sensor doesn't support data lane remapping 50 + and physical lane indexes in subsequent elements of the array should 51 + be only consecutive ascending values. 52 + 53 + SPI device node 54 + --------------- 55 + 56 + Required properties: 57 + 58 + - compatible : "samsung,s5c73m3"; 59 + 60 + For more details see description of the SPI busses bindings 61 + (../spi/spi-bus.txt) and bindings of a specific bus controller. 62 + 63 + Example: 64 + 65 + i2c@138A000000 { 66 + ... 67 + s5c73m3@3c { 68 + compatible = "samsung,s5c73m3"; 69 + reg = <0x3c>; 70 + vdd-int-supply = <&buck9_reg>; 71 + vdda-supply = <&ldo17_reg>; 72 + vdd-reg-supply = <&cam_io_reg>; 73 + vddio-host-supply = <&ldo18_reg>; 74 + vddio-cis-supply = <&ldo9_reg>; 75 + vdd-af-supply = <&cam_af_reg>; 76 + clock-frequency = <24000000>; 77 + clocks = <&clk 0>; 78 + clock-names = "cis_extclk"; 79 + reset-gpios = <&gpf1 3 1>; 80 + standby-gpios = <&gpm0 1 1>; 81 + port { 82 + s5c73m3_ep: endpoint { 83 + remote-endpoint = <&csis0_ep>; 84 + data-lanes = <1 2 3 4>; 85 + }; 86 + }; 87 + }; 88 + }; 89 + 90 + spi@1392000 { 91 + ... 92 + s5c73m3_spi: s5c73m3@0 { 93 + compatible = "samsung,s5c73m3"; 94 + reg = <0>; 95 + ... 96 + }; 97 + };
+33
Documentation/devicetree/bindings/media/samsung-s5k6a3.txt
··· 1 + Samsung S5K6A3(YX) raw image sensor 2 + --------------------------------- 3 + 4 + S5K6A3(YX) is a raw image sensor with MIPI CSI-2 and CCP2 image data interfaces 5 + and CCI (I2C compatible) control bus. 6 + 7 + Required properties: 8 + 9 + - compatible : "samsung,s5k6a3"; 10 + - reg : I2C slave address of the sensor; 11 + - svdda-supply : core voltage supply; 12 + - svddio-supply : I/O voltage supply; 13 + - afvdd-supply : AF (actuator) voltage supply; 14 + - gpios : specifier of a GPIO connected to the RESET pin; 15 + - clocks : should contain list of phandle and clock specifier pairs 16 + according to common clock bindings for the clocks described 17 + in the clock-names property; 18 + - clock-names : should contain "extclk" entry for the sensor's EXTCLK clock; 19 + 20 + Optional properties: 21 + 22 + - clock-frequency : the frequency at which the "extclk" clock should be 23 + configured to operate, in Hz; if this property is not 24 + specified default 24 MHz value will be used. 25 + 26 + The common video interfaces bindings (see video-interfaces.txt) should be 27 + used to specify link to the image data receiver. The S5K6A3(YX) device 28 + node should contain one 'port' child node with an 'endpoint' subnode. 29 + 30 + Following properties are valid for the endpoint node: 31 + 32 + - data-lanes : (optional) specifies MIPI CSI-2 data lanes as covered in 33 + video-interfaces.txt. The sensor supports only one data lane.
+2 -3
Documentation/video4linux/fimc.txt
··· 151 151 CONFIG_S5P_DEV_FIMC2 | optional 152 152 CONFIG_S5P_DEV_FIMC3 | 153 153 CONFIG_S5P_SETUP_FIMC / 154 - CONFIG_S5P_SETUP_MIPIPHY \ 155 - CONFIG_S5P_DEV_CSIS0 | optional for MIPI-CSI interface 156 - CONFIG_S5P_DEV_CSIS1 / 154 + CONFIG_S5P_DEV_CSIS0 \ optional for MIPI-CSI interface 155 + CONFIG_S5P_DEV_CSIS1 / 157 156 158 157 Except that, relevant s5p_device_fimc? should be registered in the machine code 159 158 in addition to a "s5p-fimc-md" platform device to which the media device driver
+8
drivers/media/i2c/Kconfig
··· 579 579 This is a V4L2 sensor-level driver for Samsung S5K6AA(FX) 1.3M 580 580 camera sensor with an embedded SoC image signal processor. 581 581 582 + config VIDEO_S5K6A3 583 + tristate "Samsung S5K6A3 sensor support" 584 + depends on MEDIA_CAMERA_SUPPORT 585 + depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API 586 + ---help--- 587 + This is a V4L2 sensor-level driver for Samsung S5K6A3 raw 588 + camera sensor. 589 + 582 590 config VIDEO_S5K4ECGX 583 591 tristate "Samsung S5K4ECGX sensor support" 584 592 depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+1
drivers/media/i2c/Makefile
··· 66 66 obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o 67 67 obj-$(CONFIG_VIDEO_NOON010PC30) += noon010pc30.o 68 68 obj-$(CONFIG_VIDEO_S5K6AA) += s5k6aa.o 69 + obj-$(CONFIG_VIDEO_S5K6A3) += s5k6a3.o 69 70 obj-$(CONFIG_VIDEO_S5K4ECGX) += s5k4ecgx.o 70 71 obj-$(CONFIG_VIDEO_S5K5BAF) += s5k5baf.o 71 72 obj-$(CONFIG_VIDEO_S5C73M3) += s5c73m3/
+158 -51
drivers/media/i2c/s5c73m3/s5c73m3-core.c
··· 15 15 * GNU General Public License for more details. 16 16 */ 17 17 18 - #include <linux/sizes.h> 18 + #include <linux/clk.h> 19 19 #include <linux/delay.h> 20 20 #include <linux/firmware.h> 21 21 #include <linux/gpio.h> ··· 23 23 #include <linux/init.h> 24 24 #include <linux/media.h> 25 25 #include <linux/module.h> 26 + #include <linux/of_gpio.h> 26 27 #include <linux/regulator/consumer.h> 28 + #include <linux/sizes.h> 27 29 #include <linux/slab.h> 28 30 #include <linux/spi/spi.h> 29 31 #include <linux/videodev2.h> ··· 35 33 #include <media/v4l2-subdev.h> 36 34 #include <media/v4l2-mediabus.h> 37 35 #include <media/s5c73m3.h> 36 + #include <media/v4l2-of.h> 38 37 39 38 #include "s5c73m3.h" 40 39 ··· 49 46 module_param(update_fw, int, 0644); 50 47 51 48 #define S5C73M3_EMBEDDED_DATA_MAXLEN SZ_4K 49 + #define S5C73M3_MIPI_DATA_LANES 4 50 + #define S5C73M3_CLK_NAME "cis_extclk" 52 51 53 52 static const char * const s5c73m3_supply_names[S5C73M3_MAX_SUPPLIES] = { 54 53 "vdd-int", /* Digital Core supply (1.2V), CAM_ISP_CORE_1.2V */ ··· 1360 1355 for (i = 0; i < S5C73M3_MAX_SUPPLIES; i++) { 1361 1356 ret = regulator_enable(state->supplies[i].consumer); 1362 1357 if (ret) 1363 - goto err; 1358 + goto err_reg_dis; 1364 1359 } 1360 + 1361 + ret = clk_set_rate(state->clock, state->mclk_frequency); 1362 + if (ret < 0) 1363 + goto err_reg_dis; 1364 + 1365 + ret = clk_prepare_enable(state->clock); 1366 + if (ret < 0) 1367 + goto err_reg_dis; 1368 + 1369 + v4l2_dbg(1, s5c73m3_dbg, &state->oif_sd, "clock frequency: %ld\n", 1370 + clk_get_rate(state->clock)); 1365 1371 1366 1372 s5c73m3_gpio_deassert(state, STBY); 1367 1373 usleep_range(100, 200); ··· 1381 1365 usleep_range(50, 100); 1382 1366 1383 1367 return 0; 1384 - err: 1368 + 1369 + err_reg_dis: 1385 1370 for (--i; i >= 0; i--) 1386 1371 regulator_disable(state->supplies[i].consumer); 1387 1372 return ret; ··· 1397 1380 1398 1381 if (s5c73m3_gpio_assert(state, STBY)) 1399 1382 usleep_range(100, 200); 1383 + 1384 + clk_disable_unprepare(state->clock); 1385 + 1400 1386 state->streaming = 0; 1401 1387 state->isp_ready = 0; 1402 1388 ··· 1408 1388 if (ret) 1409 1389 goto err; 1410 1390 } 1391 + 1411 1392 return 0; 1412 1393 err: 1413 1394 for (++i; i < S5C73M3_MAX_SUPPLIES; i++) { ··· 1417 1396 v4l2_err(&state->oif_sd, "Failed to reenable %s: %d\n", 1418 1397 state->supplies[i].supply, r); 1419 1398 } 1399 + 1400 + clk_prepare_enable(state->clock); 1420 1401 return ret; 1421 1402 } 1422 1403 ··· 1473 1450 ret = media_entity_create_link(&state->sensor_sd.entity, 1474 1451 S5C73M3_JPEG_PAD, &state->oif_sd.entity, OIF_JPEG_PAD, 1475 1452 MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); 1476 - 1477 - mutex_lock(&state->lock); 1478 - ret = __s5c73m3_power_on(state); 1479 - if (ret == 0) 1480 - s5c73m3_get_fw_version(state); 1481 - 1482 - __s5c73m3_power_off(state); 1483 - mutex_unlock(&state->lock); 1484 - 1485 - v4l2_dbg(1, s5c73m3_dbg, sd, "%s: Booting %s (%d)\n", 1486 - __func__, ret ? "failed" : "succeeded", ret); 1487 1453 1488 1454 return ret; 1489 1455 } ··· 1531 1519 .video = &s5c73m3_oif_video_ops, 1532 1520 }; 1533 1521 1534 - static int s5c73m3_configure_gpios(struct s5c73m3 *state, 1535 - const struct s5c73m3_platform_data *pdata) 1522 + static int s5c73m3_configure_gpios(struct s5c73m3 *state) 1523 + { 1524 + static const char * const gpio_names[] = { 1525 + "S5C73M3_STBY", "S5C73M3_RST" 1526 + }; 1527 + struct i2c_client *c = state->i2c_client; 1528 + struct s5c73m3_gpio *g = state->gpio; 1529 + int ret, i; 1530 + 1531 + for (i = 0; i < GPIO_NUM; ++i) { 1532 + unsigned int flags = GPIOF_DIR_OUT; 1533 + if (g[i].level) 1534 + flags |= GPIOF_INIT_HIGH; 1535 + ret = devm_gpio_request_one(&c->dev, g[i].gpio, flags, 1536 + gpio_names[i]); 1537 + if (ret) { 1538 + v4l2_err(c, "failed to request gpio %s\n", 1539 + gpio_names[i]); 1540 + return ret; 1541 + } 1542 + } 1543 + return 0; 1544 + } 1545 + 1546 + static int s5c73m3_parse_gpios(struct s5c73m3 *state) 1547 + { 1548 + static const char * const prop_names[] = { 1549 + "standby-gpios", "xshutdown-gpios", 1550 + }; 1551 + struct device *dev = &state->i2c_client->dev; 1552 + struct device_node *node = dev->of_node; 1553 + int ret, i; 1554 + 1555 + for (i = 0; i < GPIO_NUM; ++i) { 1556 + enum of_gpio_flags of_flags; 1557 + 1558 + ret = of_get_named_gpio_flags(node, prop_names[i], 1559 + 0, &of_flags); 1560 + if (ret < 0) { 1561 + dev_err(dev, "failed to parse %s DT property\n", 1562 + prop_names[i]); 1563 + return -EINVAL; 1564 + } 1565 + state->gpio[i].gpio = ret; 1566 + state->gpio[i].level = !(of_flags & OF_GPIO_ACTIVE_LOW); 1567 + } 1568 + return 0; 1569 + } 1570 + 1571 + static int s5c73m3_get_platform_data(struct s5c73m3 *state) 1536 1572 { 1537 1573 struct device *dev = &state->i2c_client->dev; 1538 - const struct s5c73m3_gpio *gpio; 1539 - unsigned long flags; 1574 + const struct s5c73m3_platform_data *pdata = dev->platform_data; 1575 + struct device_node *node = dev->of_node; 1576 + struct device_node *node_ep; 1577 + struct v4l2_of_endpoint ep; 1540 1578 int ret; 1541 1579 1542 - state->gpio[STBY].gpio = -EINVAL; 1543 - state->gpio[RST].gpio = -EINVAL; 1580 + if (!node) { 1581 + if (!pdata) { 1582 + dev_err(dev, "Platform data not specified\n"); 1583 + return -EINVAL; 1584 + } 1544 1585 1545 - gpio = &pdata->gpio_stby; 1546 - if (gpio_is_valid(gpio->gpio)) { 1547 - flags = (gpio->level ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW) 1548 - | GPIOF_EXPORT; 1549 - ret = devm_gpio_request_one(dev, gpio->gpio, flags, 1550 - "S5C73M3_STBY"); 1551 - if (ret < 0) 1552 - return ret; 1553 - 1554 - state->gpio[STBY] = *gpio; 1586 + state->mclk_frequency = pdata->mclk_frequency; 1587 + state->gpio[STBY] = pdata->gpio_stby; 1588 + state->gpio[RST] = pdata->gpio_reset; 1589 + return 0; 1555 1590 } 1556 1591 1557 - gpio = &pdata->gpio_reset; 1558 - if (gpio_is_valid(gpio->gpio)) { 1559 - flags = (gpio->level ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW) 1560 - | GPIOF_EXPORT; 1561 - ret = devm_gpio_request_one(dev, gpio->gpio, flags, 1562 - "S5C73M3_RST"); 1563 - if (ret < 0) 1564 - return ret; 1592 + state->clock = devm_clk_get(dev, S5C73M3_CLK_NAME); 1593 + if (IS_ERR(state->clock)) 1594 + return PTR_ERR(state->clock); 1565 1595 1566 - state->gpio[RST] = *gpio; 1596 + if (of_property_read_u32(node, "clock-frequency", 1597 + &state->mclk_frequency)) { 1598 + state->mclk_frequency = S5C73M3_DEFAULT_MCLK_FREQ; 1599 + dev_info(dev, "using default %u Hz clock frequency\n", 1600 + state->mclk_frequency); 1567 1601 } 1602 + 1603 + ret = s5c73m3_parse_gpios(state); 1604 + if (ret < 0) 1605 + return -EINVAL; 1606 + 1607 + node_ep = v4l2_of_get_next_endpoint(node, NULL); 1608 + if (!node_ep) { 1609 + dev_warn(dev, "no endpoint defined for node: %s\n", 1610 + node->full_name); 1611 + return 0; 1612 + } 1613 + 1614 + v4l2_of_parse_endpoint(node_ep, &ep); 1615 + of_node_put(node_ep); 1616 + 1617 + if (ep.bus_type != V4L2_MBUS_CSI2) { 1618 + dev_err(dev, "unsupported bus type\n"); 1619 + return -EINVAL; 1620 + } 1621 + /* 1622 + * Number of MIPI CSI-2 data lanes is currently not configurable, 1623 + * always a default value of 4 lanes is used. 1624 + */ 1625 + if (ep.bus.mipi_csi2.num_data_lanes != S5C73M3_MIPI_DATA_LANES) 1626 + dev_info(dev, "falling back to 4 MIPI CSI-2 data lanes\n"); 1568 1627 1569 1628 return 0; 1570 1629 } ··· 1644 1561 const struct i2c_device_id *id) 1645 1562 { 1646 1563 struct device *dev = &client->dev; 1647 - const struct s5c73m3_platform_data *pdata = client->dev.platform_data; 1648 1564 struct v4l2_subdev *sd; 1649 1565 struct v4l2_subdev *oif_sd; 1650 1566 struct s5c73m3 *state; 1651 1567 int ret, i; 1652 1568 1653 - if (pdata == NULL) { 1654 - dev_err(&client->dev, "Platform data not specified\n"); 1655 - return -EINVAL; 1656 - } 1657 - 1658 1569 state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); 1659 1570 if (!state) 1660 1571 return -ENOMEM; 1572 + 1573 + state->i2c_client = client; 1574 + ret = s5c73m3_get_platform_data(state); 1575 + if (ret < 0) 1576 + return ret; 1661 1577 1662 1578 mutex_init(&state->lock); 1663 1579 sd = &state->sensor_sd; ··· 1695 1613 if (ret < 0) 1696 1614 return ret; 1697 1615 1698 - state->mclk_frequency = pdata->mclk_frequency; 1699 - state->bus_type = pdata->bus_type; 1700 - state->i2c_client = client; 1701 - 1702 - ret = s5c73m3_configure_gpios(state, pdata); 1616 + ret = s5c73m3_configure_gpios(state); 1703 1617 if (ret) 1704 1618 goto out_err; 1705 1619 ··· 1729 1651 if (ret < 0) 1730 1652 goto out_err; 1731 1653 1654 + oif_sd->dev = dev; 1655 + 1656 + ret = __s5c73m3_power_on(state); 1657 + if (ret < 0) 1658 + goto out_err1; 1659 + 1660 + ret = s5c73m3_get_fw_version(state); 1661 + __s5c73m3_power_off(state); 1662 + 1663 + if (ret < 0) { 1664 + dev_err(dev, "Device detection failed: %d\n", ret); 1665 + goto out_err1; 1666 + } 1667 + 1668 + ret = v4l2_async_register_subdev(oif_sd); 1669 + if (ret < 0) 1670 + goto out_err1; 1671 + 1732 1672 v4l2_info(sd, "%s: completed successfully\n", __func__); 1733 1673 return 0; 1734 1674 1675 + out_err1: 1676 + s5c73m3_unregister_spi_driver(state); 1735 1677 out_err: 1736 1678 media_entity_cleanup(&sd->entity); 1737 1679 return ret; ··· 1763 1665 struct s5c73m3 *state = oif_sd_to_s5c73m3(oif_sd); 1764 1666 struct v4l2_subdev *sensor_sd = &state->sensor_sd; 1765 1667 1766 - v4l2_device_unregister_subdev(oif_sd); 1668 + v4l2_async_unregister_subdev(oif_sd); 1767 1669 1768 1670 v4l2_ctrl_handler_free(oif_sd->ctrl_handler); 1769 1671 media_entity_cleanup(&oif_sd->entity); ··· 1782 1684 }; 1783 1685 MODULE_DEVICE_TABLE(i2c, s5c73m3_id); 1784 1686 1687 + #ifdef CONFIG_OF 1688 + static const struct of_device_id s5c73m3_of_match[] = { 1689 + { .compatible = "samsung,s5c73m3" }, 1690 + { } 1691 + }; 1692 + MODULE_DEVICE_TABLE(of, s5c73m3_of_match); 1693 + #endif 1694 + 1785 1695 static struct i2c_driver s5c73m3_i2c_driver = { 1786 1696 .driver = { 1697 + .of_match_table = of_match_ptr(s5c73m3_of_match), 1787 1698 .name = DRIVER_NAME, 1788 1699 }, 1789 1700 .probe = s5c73m3_probe,
+6
drivers/media/i2c/s5c73m3/s5c73m3-spi.c
··· 27 27 28 28 #define S5C73M3_SPI_DRV_NAME "S5C73M3-SPI" 29 29 30 + static const struct of_device_id s5c73m3_spi_ids[] = { 31 + { .compatible = "samsung,s5c73m3" }, 32 + { } 33 + }; 34 + 30 35 enum spi_direction { 31 36 SPI_DIR_RX, 32 37 SPI_DIR_TX ··· 151 146 spidrv->driver.name = S5C73M3_SPI_DRV_NAME; 152 147 spidrv->driver.bus = &spi_bus_type; 153 148 spidrv->driver.owner = THIS_MODULE; 149 + spidrv->driver.of_match_table = s5c73m3_spi_ids; 154 150 155 151 return spi_register_driver(spidrv); 156 152 }
+4
drivers/media/i2c/s5c73m3/s5c73m3.h
··· 17 17 #ifndef S5C73M3_H_ 18 18 #define S5C73M3_H_ 19 19 20 + #include <linux/clk.h> 20 21 #include <linux/kernel.h> 21 22 #include <linux/regulator/consumer.h> 22 23 #include <media/v4l2-common.h> ··· 322 321 323 322 324 323 #define S5C73M3_MAX_SUPPLIES 6 324 + #define S5C73M3_DEFAULT_MCLK_FREQ 24000000U 325 325 326 326 struct s5c73m3_ctrls { 327 327 struct v4l2_ctrl_handler handler; ··· 392 390 393 391 struct regulator_bulk_data supplies[S5C73M3_MAX_SUPPLIES]; 394 392 struct s5c73m3_gpio gpio[GPIO_NUM]; 393 + 394 + struct clk *clock; 395 395 396 396 /* External master clock frequency */ 397 397 u32 mclk_frequency;
+389
drivers/media/i2c/s5k6a3.c
··· 1 + /* 2 + * Samsung S5K6A3 image sensor driver 3 + * 4 + * Copyright (C) 2013 Samsung Electronics Co., Ltd. 5 + * Author: Sylwester Nawrocki <s.nawrocki@samsung.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 as 9 + * published by the Free Software Foundation. 10 + */ 11 + 12 + #include <linux/clk.h> 13 + #include <linux/delay.h> 14 + #include <linux/device.h> 15 + #include <linux/errno.h> 16 + #include <linux/gpio.h> 17 + #include <linux/i2c.h> 18 + #include <linux/kernel.h> 19 + #include <linux/module.h> 20 + #include <linux/of_gpio.h> 21 + #include <linux/pm_runtime.h> 22 + #include <linux/regulator/consumer.h> 23 + #include <linux/slab.h> 24 + #include <linux/videodev2.h> 25 + #include <media/v4l2-async.h> 26 + #include <media/v4l2-subdev.h> 27 + 28 + #define S5K6A3_SENSOR_MAX_WIDTH 1412 29 + #define S5K6A3_SENSOR_MAX_HEIGHT 1412 30 + #define S5K6A3_SENSOR_MIN_WIDTH 32 31 + #define S5K6A3_SENSOR_MIN_HEIGHT 32 32 + 33 + #define S5K6A3_DEFAULT_WIDTH 1296 34 + #define S5K6A3_DEFAULT_HEIGHT 732 35 + 36 + #define S5K6A3_DRV_NAME "S5K6A3" 37 + #define S5K6A3_CLK_NAME "extclk" 38 + #define S5K6A3_DEFAULT_CLK_FREQ 24000000U 39 + 40 + enum { 41 + S5K6A3_SUPP_VDDA, 42 + S5K6A3_SUPP_VDDIO, 43 + S5K6A3_SUPP_AFVDD, 44 + S5K6A3_NUM_SUPPLIES, 45 + }; 46 + 47 + /** 48 + * struct s5k6a3 - fimc-is sensor data structure 49 + * @dev: pointer to this I2C client device structure 50 + * @subdev: the image sensor's v4l2 subdev 51 + * @pad: subdev media source pad 52 + * @supplies: image sensor's voltage regulator supplies 53 + * @gpio_reset: GPIO connected to the sensor's reset pin 54 + * @lock: mutex protecting the structure's members below 55 + * @format: media bus format at the sensor's source pad 56 + */ 57 + struct s5k6a3 { 58 + struct device *dev; 59 + struct v4l2_subdev subdev; 60 + struct media_pad pad; 61 + struct regulator_bulk_data supplies[S5K6A3_NUM_SUPPLIES]; 62 + int gpio_reset; 63 + struct mutex lock; 64 + struct v4l2_mbus_framefmt format; 65 + struct clk *clock; 66 + u32 clock_frequency; 67 + int power_count; 68 + }; 69 + 70 + static const char * const s5k6a3_supply_names[] = { 71 + [S5K6A3_SUPP_VDDA] = "svdda", 72 + [S5K6A3_SUPP_VDDIO] = "svddio", 73 + [S5K6A3_SUPP_AFVDD] = "afvdd", 74 + }; 75 + 76 + static inline struct s5k6a3 *sd_to_s5k6a3(struct v4l2_subdev *sd) 77 + { 78 + return container_of(sd, struct s5k6a3, subdev); 79 + } 80 + 81 + static const struct v4l2_mbus_framefmt s5k6a3_formats[] = { 82 + { 83 + .code = V4L2_MBUS_FMT_SGRBG10_1X10, 84 + .colorspace = V4L2_COLORSPACE_SRGB, 85 + .field = V4L2_FIELD_NONE, 86 + } 87 + }; 88 + 89 + static const struct v4l2_mbus_framefmt *find_sensor_format( 90 + struct v4l2_mbus_framefmt *mf) 91 + { 92 + int i; 93 + 94 + for (i = 0; i < ARRAY_SIZE(s5k6a3_formats); i++) 95 + if (mf->code == s5k6a3_formats[i].code) 96 + return &s5k6a3_formats[i]; 97 + 98 + return &s5k6a3_formats[0]; 99 + } 100 + 101 + static int s5k6a3_enum_mbus_code(struct v4l2_subdev *sd, 102 + struct v4l2_subdev_fh *fh, 103 + struct v4l2_subdev_mbus_code_enum *code) 104 + { 105 + if (code->index >= ARRAY_SIZE(s5k6a3_formats)) 106 + return -EINVAL; 107 + 108 + code->code = s5k6a3_formats[code->index].code; 109 + return 0; 110 + } 111 + 112 + static void s5k6a3_try_format(struct v4l2_mbus_framefmt *mf) 113 + { 114 + const struct v4l2_mbus_framefmt *fmt; 115 + 116 + fmt = find_sensor_format(mf); 117 + mf->code = fmt->code; 118 + v4l_bound_align_image(&mf->width, S5K6A3_SENSOR_MIN_WIDTH, 119 + S5K6A3_SENSOR_MAX_WIDTH, 0, 120 + &mf->height, S5K6A3_SENSOR_MIN_HEIGHT, 121 + S5K6A3_SENSOR_MAX_HEIGHT, 0, 0); 122 + } 123 + 124 + static struct v4l2_mbus_framefmt *__s5k6a3_get_format( 125 + struct s5k6a3 *sensor, struct v4l2_subdev_fh *fh, 126 + u32 pad, enum v4l2_subdev_format_whence which) 127 + { 128 + if (which == V4L2_SUBDEV_FORMAT_TRY) 129 + return fh ? v4l2_subdev_get_try_format(fh, pad) : NULL; 130 + 131 + return &sensor->format; 132 + } 133 + 134 + static int s5k6a3_set_fmt(struct v4l2_subdev *sd, 135 + struct v4l2_subdev_fh *fh, 136 + struct v4l2_subdev_format *fmt) 137 + { 138 + struct s5k6a3 *sensor = sd_to_s5k6a3(sd); 139 + struct v4l2_mbus_framefmt *mf; 140 + 141 + s5k6a3_try_format(&fmt->format); 142 + 143 + mf = __s5k6a3_get_format(sensor, fh, fmt->pad, fmt->which); 144 + if (mf) { 145 + mutex_lock(&sensor->lock); 146 + if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) 147 + *mf = fmt->format; 148 + mutex_unlock(&sensor->lock); 149 + } 150 + return 0; 151 + } 152 + 153 + static int s5k6a3_get_fmt(struct v4l2_subdev *sd, 154 + struct v4l2_subdev_fh *fh, 155 + struct v4l2_subdev_format *fmt) 156 + { 157 + struct s5k6a3 *sensor = sd_to_s5k6a3(sd); 158 + struct v4l2_mbus_framefmt *mf; 159 + 160 + mf = __s5k6a3_get_format(sensor, fh, fmt->pad, fmt->which); 161 + 162 + mutex_lock(&sensor->lock); 163 + fmt->format = *mf; 164 + mutex_unlock(&sensor->lock); 165 + return 0; 166 + } 167 + 168 + static struct v4l2_subdev_pad_ops s5k6a3_pad_ops = { 169 + .enum_mbus_code = s5k6a3_enum_mbus_code, 170 + .get_fmt = s5k6a3_get_fmt, 171 + .set_fmt = s5k6a3_set_fmt, 172 + }; 173 + 174 + static int s5k6a3_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) 175 + { 176 + struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(fh, 0); 177 + 178 + *format = s5k6a3_formats[0]; 179 + format->width = S5K6A3_DEFAULT_WIDTH; 180 + format->height = S5K6A3_DEFAULT_HEIGHT; 181 + 182 + return 0; 183 + } 184 + 185 + static const struct v4l2_subdev_internal_ops s5k6a3_sd_internal_ops = { 186 + .open = s5k6a3_open, 187 + }; 188 + 189 + static int __s5k6a3_power_on(struct s5k6a3 *sensor) 190 + { 191 + int i = S5K6A3_SUPP_VDDA; 192 + int ret; 193 + 194 + ret = clk_set_rate(sensor->clock, sensor->clock_frequency); 195 + if (ret < 0) 196 + return ret; 197 + 198 + ret = pm_runtime_get(sensor->dev); 199 + if (ret < 0) 200 + return ret; 201 + 202 + ret = regulator_enable(sensor->supplies[i].consumer); 203 + if (ret < 0) 204 + goto error_rpm_put; 205 + 206 + ret = clk_prepare_enable(sensor->clock); 207 + if (ret < 0) 208 + goto error_reg_dis; 209 + 210 + for (i++; i < S5K6A3_NUM_SUPPLIES; i++) { 211 + ret = regulator_enable(sensor->supplies[i].consumer); 212 + if (ret < 0) 213 + goto error_reg_dis; 214 + } 215 + 216 + gpio_set_value(sensor->gpio_reset, 1); 217 + usleep_range(600, 800); 218 + gpio_set_value(sensor->gpio_reset, 0); 219 + usleep_range(600, 800); 220 + gpio_set_value(sensor->gpio_reset, 1); 221 + 222 + /* Delay needed for the sensor initialization */ 223 + msleep(20); 224 + return 0; 225 + 226 + error_reg_dis: 227 + for (--i; i >= 0; --i) 228 + regulator_disable(sensor->supplies[i].consumer); 229 + error_rpm_put: 230 + pm_runtime_put(sensor->dev); 231 + return ret; 232 + } 233 + 234 + static int __s5k6a3_power_off(struct s5k6a3 *sensor) 235 + { 236 + int i; 237 + 238 + gpio_set_value(sensor->gpio_reset, 0); 239 + 240 + for (i = S5K6A3_NUM_SUPPLIES - 1; i >= 0; i--) 241 + regulator_disable(sensor->supplies[i].consumer); 242 + 243 + clk_disable_unprepare(sensor->clock); 244 + pm_runtime_put(sensor->dev); 245 + return 0; 246 + } 247 + 248 + static int s5k6a3_s_power(struct v4l2_subdev *sd, int on) 249 + { 250 + struct s5k6a3 *sensor = sd_to_s5k6a3(sd); 251 + int ret = 0; 252 + 253 + mutex_lock(&sensor->lock); 254 + 255 + if (sensor->power_count == !on) { 256 + if (on) 257 + ret = __s5k6a3_power_on(sensor); 258 + else 259 + ret = __s5k6a3_power_off(sensor); 260 + 261 + if (ret == 0) 262 + sensor->power_count += on ? 1 : -1; 263 + } 264 + 265 + mutex_unlock(&sensor->lock); 266 + return ret; 267 + } 268 + 269 + static struct v4l2_subdev_core_ops s5k6a3_core_ops = { 270 + .s_power = s5k6a3_s_power, 271 + }; 272 + 273 + static struct v4l2_subdev_ops s5k6a3_subdev_ops = { 274 + .core = &s5k6a3_core_ops, 275 + .pad = &s5k6a3_pad_ops, 276 + }; 277 + 278 + static int s5k6a3_probe(struct i2c_client *client, 279 + const struct i2c_device_id *id) 280 + { 281 + struct device *dev = &client->dev; 282 + struct s5k6a3 *sensor; 283 + struct v4l2_subdev *sd; 284 + int gpio, i, ret; 285 + 286 + sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL); 287 + if (!sensor) 288 + return -ENOMEM; 289 + 290 + mutex_init(&sensor->lock); 291 + sensor->gpio_reset = -EINVAL; 292 + sensor->clock = ERR_PTR(-EINVAL); 293 + sensor->dev = dev; 294 + 295 + sensor->clock = devm_clk_get(sensor->dev, S5K6A3_CLK_NAME); 296 + if (IS_ERR(sensor->clock)) 297 + return PTR_ERR(sensor->clock); 298 + 299 + gpio = of_get_gpio_flags(dev->of_node, 0, NULL); 300 + if (!gpio_is_valid(gpio)) 301 + return gpio; 302 + 303 + ret = devm_gpio_request_one(dev, gpio, GPIOF_OUT_INIT_LOW, 304 + S5K6A3_DRV_NAME); 305 + if (ret < 0) 306 + return ret; 307 + 308 + sensor->gpio_reset = gpio; 309 + 310 + if (of_property_read_u32(dev->of_node, "clock-frequency", 311 + &sensor->clock_frequency)) { 312 + sensor->clock_frequency = S5K6A3_DEFAULT_CLK_FREQ; 313 + dev_info(dev, "using default %u Hz clock frequency\n", 314 + sensor->clock_frequency); 315 + } 316 + 317 + for (i = 0; i < S5K6A3_NUM_SUPPLIES; i++) 318 + sensor->supplies[i].supply = s5k6a3_supply_names[i]; 319 + 320 + ret = devm_regulator_bulk_get(&client->dev, S5K6A3_NUM_SUPPLIES, 321 + sensor->supplies); 322 + if (ret < 0) 323 + return ret; 324 + 325 + sd = &sensor->subdev; 326 + v4l2_i2c_subdev_init(sd, client, &s5k6a3_subdev_ops); 327 + sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 328 + sd->internal_ops = &s5k6a3_sd_internal_ops; 329 + 330 + sensor->format.code = s5k6a3_formats[0].code; 331 + sensor->format.width = S5K6A3_DEFAULT_WIDTH; 332 + sensor->format.height = S5K6A3_DEFAULT_HEIGHT; 333 + 334 + sensor->pad.flags = MEDIA_PAD_FL_SOURCE; 335 + ret = media_entity_init(&sd->entity, 1, &sensor->pad, 0); 336 + if (ret < 0) 337 + return ret; 338 + 339 + pm_runtime_no_callbacks(dev); 340 + pm_runtime_enable(dev); 341 + 342 + ret = v4l2_async_register_subdev(sd); 343 + 344 + if (ret < 0) { 345 + pm_runtime_disable(&client->dev); 346 + media_entity_cleanup(&sd->entity); 347 + } 348 + 349 + return ret; 350 + } 351 + 352 + static int s5k6a3_remove(struct i2c_client *client) 353 + { 354 + struct v4l2_subdev *sd = i2c_get_clientdata(client); 355 + 356 + pm_runtime_disable(&client->dev); 357 + v4l2_async_unregister_subdev(sd); 358 + media_entity_cleanup(&sd->entity); 359 + return 0; 360 + } 361 + 362 + static const struct i2c_device_id s5k6a3_ids[] = { 363 + { } 364 + }; 365 + 366 + #ifdef CONFIG_OF 367 + static const struct of_device_id s5k6a3_of_match[] = { 368 + { .compatible = "samsung,s5k6a3" }, 369 + { /* sentinel */ } 370 + }; 371 + MODULE_DEVICE_TABLE(of, s5k6a3_of_match); 372 + #endif 373 + 374 + static struct i2c_driver s5k6a3_driver = { 375 + .driver = { 376 + .of_match_table = of_match_ptr(s5k6a3_of_match), 377 + .name = S5K6A3_DRV_NAME, 378 + .owner = THIS_MODULE, 379 + }, 380 + .probe = s5k6a3_probe, 381 + .remove = s5k6a3_remove, 382 + .id_table = s5k6a3_ids, 383 + }; 384 + 385 + module_i2c_driver(s5k6a3_driver); 386 + 387 + MODULE_DESCRIPTION("S5K6A3 image sensor subdev driver"); 388 + MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>"); 389 + MODULE_LICENSE("GPL v2");
+9
drivers/media/platform/exynos4-is/Kconfig
··· 64 64 To compile this driver as a module, choose M here: the 65 65 module will be called exynos4-fimc-is. 66 66 67 + config VIDEO_EXYNOS4_ISP_DMA_CAPTURE 68 + bool "EXYNOS4x12 FIMC-IS ISP Direct DMA capture support" 69 + depends on VIDEO_EXYNOS4_FIMC_IS 70 + select VIDEO_EXYNOS4_IS_COMMON 71 + default y 72 + help 73 + This option enables an additional video device node exposing a V4L2 74 + video capture interface for the FIMC-IS ISP raw (Bayer) capture DMA. 75 + 67 76 endif # VIDEO_SAMSUNG_EXYNOS4_IS
+4
drivers/media/platform/exynos4-is/Makefile
··· 6 6 exynos-fimc-is-objs := fimc-is.o fimc-isp.o fimc-is-sensor.o fimc-is-regs.o 7 7 exynos-fimc-is-objs += fimc-is-param.o fimc-is-errno.o fimc-is-i2c.o 8 8 9 + ifeq ($(CONFIG_VIDEO_EXYNOS4_ISP_DMA_CAPTURE),y) 10 + exynos-fimc-is-objs += fimc-isp-video.o 11 + endif 12 + 9 13 obj-$(CONFIG_VIDEO_S5P_MIPI_CSIS) += s5p-csis.o 10 14 obj-$(CONFIG_VIDEO_EXYNOS_FIMC_LITE) += exynos-fimc-lite.o 11 15 obj-$(CONFIG_VIDEO_EXYNOS4_FIMC_IS) += exynos-fimc-is.o
+1 -1
drivers/media/platform/exynos4-is/fimc-is-param.c
··· 56 56 __hw_param_copy(dst, src); 57 57 } 58 58 59 - static int __fimc_is_hw_update_param(struct fimc_is *is, u32 offset) 59 + int __fimc_is_hw_update_param(struct fimc_is *is, u32 offset) 60 60 { 61 61 struct is_param_region *par = &is->is_p_region->parameter; 62 62 struct chain_config *cfg = &is->config[is->config_index];
+5
drivers/media/platform/exynos4-is/fimc-is-param.h
··· 911 911 u32 shared[MAX_SHARED_COUNT]; 912 912 } __packed; 913 913 914 + /* Offset to the ISP DMA2 output buffer address array. */ 915 + #define DMA2_OUTPUT_ADDR_ARRAY_OFFS \ 916 + (offsetof(struct is_region, shared) + 32 * sizeof(u32)) 917 + 914 918 struct is_debug_frame_descriptor { 915 919 u32 sensor_frame_time; 916 920 u32 sensor_exposure_time; ··· 992 988 struct fimc_is; 993 989 994 990 int fimc_is_hw_get_sensor_max_framerate(struct fimc_is *is); 991 + int __fimc_is_hw_update_param(struct fimc_is *is, u32 offset); 995 992 void fimc_is_set_initial_params(struct fimc_is *is); 996 993 unsigned int __get_pending_param_count(struct fimc_is *is); 997 994
+15 -1
drivers/media/platform/exynos4-is/fimc-is-regs.c
··· 105 105 return 0; 106 106 } 107 107 108 + void fimc_is_hw_set_isp_buf_mask(struct fimc_is *is, unsigned int mask) 109 + { 110 + if (hweight32(mask) == 1) { 111 + dev_err(&is->pdev->dev, "%s(): not enough buffers (mask %#x)\n", 112 + __func__, mask); 113 + return; 114 + } 115 + 116 + if (mcuctl_read(is, MCUCTL_REG_ISSR(23)) != 0) 117 + dev_dbg(&is->pdev->dev, "non-zero DMA buffer mask\n"); 118 + 119 + mcuctl_write(mask, is, MCUCTL_REG_ISSR(23)); 120 + } 121 + 108 122 void fimc_is_hw_set_sensor_num(struct fimc_is *is) 109 123 { 110 124 pr_debug("setting sensor index to: %d\n", is->sensor_index); ··· 126 112 mcuctl_write(IH_REPLY_DONE, is, MCUCTL_REG_ISSR(0)); 127 113 mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1)); 128 114 mcuctl_write(IHC_GET_SENSOR_NUM, is, MCUCTL_REG_ISSR(2)); 129 - mcuctl_write(FIMC_IS_SENSOR_NUM, is, MCUCTL_REG_ISSR(3)); 115 + mcuctl_write(FIMC_IS_SENSORS_NUM, is, MCUCTL_REG_ISSR(3)); 130 116 } 131 117 132 118 void fimc_is_hw_close_sensor(struct fimc_is *is, unsigned int index)
+1
drivers/media/platform/exynos4-is/fimc-is-regs.h
··· 147 147 void fimc_is_hw_set_intgr0_gd0(struct fimc_is *is); 148 148 int fimc_is_hw_wait_intmsr0_intmsd0(struct fimc_is *is); 149 149 void fimc_is_hw_set_sensor_num(struct fimc_is *is); 150 + void fimc_is_hw_set_isp_buf_mask(struct fimc_is *is, unsigned int mask); 150 151 void fimc_is_hw_stream_on(struct fimc_is *is); 151 152 void fimc_is_hw_stream_off(struct fimc_is *is); 152 153 int fimc_is_hw_set_param(struct fimc_is *is);
+7 -278
drivers/media/platform/exynos4-is/fimc-is-sensor.c
··· 2 2 * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver 3 3 * 4 4 * Copyright (C) 2013 Samsung Electronics Co., Ltd. 5 - * 6 5 * Author: Sylwester Nawrocki <s.nawrocki@samsung.com> 7 6 * 8 7 * This program is free software; you can redistribute it and/or modify 9 8 * it under the terms of the GNU General Public License version 2 as 10 9 * published by the Free Software Foundation. 11 10 */ 12 - #include <linux/delay.h> 13 - #include <linux/device.h> 14 - #include <linux/errno.h> 15 - #include <linux/gpio.h> 16 - #include <linux/i2c.h> 17 - #include <linux/kernel.h> 18 - #include <linux/module.h> 19 - #include <linux/of_gpio.h> 20 - #include <linux/pm_runtime.h> 21 - #include <linux/regulator/consumer.h> 22 - #include <linux/slab.h> 23 - #include <media/v4l2-subdev.h> 24 11 25 - #include "fimc-is.h" 26 12 #include "fimc-is-sensor.h" 27 - 28 - #define DRIVER_NAME "FIMC-IS-SENSOR" 29 - 30 - static const char * const sensor_supply_names[] = { 31 - "svdda", 32 - "svddio", 33 - }; 34 - 35 - static const struct v4l2_mbus_framefmt fimc_is_sensor_formats[] = { 36 - { 37 - .code = V4L2_MBUS_FMT_SGRBG10_1X10, 38 - .colorspace = V4L2_COLORSPACE_SRGB, 39 - .field = V4L2_FIELD_NONE, 40 - } 41 - }; 42 - 43 - static const struct v4l2_mbus_framefmt *find_sensor_format( 44 - struct v4l2_mbus_framefmt *mf) 45 - { 46 - int i; 47 - 48 - for (i = 0; i < ARRAY_SIZE(fimc_is_sensor_formats); i++) 49 - if (mf->code == fimc_is_sensor_formats[i].code) 50 - return &fimc_is_sensor_formats[i]; 51 - 52 - return &fimc_is_sensor_formats[0]; 53 - } 54 - 55 - static int fimc_is_sensor_enum_mbus_code(struct v4l2_subdev *sd, 56 - struct v4l2_subdev_fh *fh, 57 - struct v4l2_subdev_mbus_code_enum *code) 58 - { 59 - if (code->index >= ARRAY_SIZE(fimc_is_sensor_formats)) 60 - return -EINVAL; 61 - 62 - code->code = fimc_is_sensor_formats[code->index].code; 63 - return 0; 64 - } 65 - 66 - static void fimc_is_sensor_try_format(struct fimc_is_sensor *sensor, 67 - struct v4l2_mbus_framefmt *mf) 68 - { 69 - const struct sensor_drv_data *dd = sensor->drvdata; 70 - const struct v4l2_mbus_framefmt *fmt; 71 - 72 - fmt = find_sensor_format(mf); 73 - mf->code = fmt->code; 74 - v4l_bound_align_image(&mf->width, 16 + 8, dd->width, 0, 75 - &mf->height, 12 + 8, dd->height, 0, 0); 76 - } 77 - 78 - static struct v4l2_mbus_framefmt *__fimc_is_sensor_get_format( 79 - struct fimc_is_sensor *sensor, struct v4l2_subdev_fh *fh, 80 - u32 pad, enum v4l2_subdev_format_whence which) 81 - { 82 - if (which == V4L2_SUBDEV_FORMAT_TRY) 83 - return fh ? v4l2_subdev_get_try_format(fh, pad) : NULL; 84 - 85 - return &sensor->format; 86 - } 87 - 88 - static int fimc_is_sensor_set_fmt(struct v4l2_subdev *sd, 89 - struct v4l2_subdev_fh *fh, 90 - struct v4l2_subdev_format *fmt) 91 - { 92 - struct fimc_is_sensor *sensor = sd_to_fimc_is_sensor(sd); 93 - struct v4l2_mbus_framefmt *mf; 94 - 95 - fimc_is_sensor_try_format(sensor, &fmt->format); 96 - 97 - mf = __fimc_is_sensor_get_format(sensor, fh, fmt->pad, fmt->which); 98 - if (mf) { 99 - mutex_lock(&sensor->lock); 100 - if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) 101 - *mf = fmt->format; 102 - mutex_unlock(&sensor->lock); 103 - } 104 - return 0; 105 - } 106 - 107 - static int fimc_is_sensor_get_fmt(struct v4l2_subdev *sd, 108 - struct v4l2_subdev_fh *fh, 109 - struct v4l2_subdev_format *fmt) 110 - { 111 - struct fimc_is_sensor *sensor = sd_to_fimc_is_sensor(sd); 112 - struct v4l2_mbus_framefmt *mf; 113 - 114 - mf = __fimc_is_sensor_get_format(sensor, fh, fmt->pad, fmt->which); 115 - 116 - mutex_lock(&sensor->lock); 117 - fmt->format = *mf; 118 - mutex_unlock(&sensor->lock); 119 - return 0; 120 - } 121 - 122 - static struct v4l2_subdev_pad_ops fimc_is_sensor_pad_ops = { 123 - .enum_mbus_code = fimc_is_sensor_enum_mbus_code, 124 - .get_fmt = fimc_is_sensor_get_fmt, 125 - .set_fmt = fimc_is_sensor_set_fmt, 126 - }; 127 - 128 - static int fimc_is_sensor_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) 129 - { 130 - struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(fh, 0); 131 - 132 - *format = fimc_is_sensor_formats[0]; 133 - format->width = FIMC_IS_SENSOR_DEF_PIX_WIDTH; 134 - format->height = FIMC_IS_SENSOR_DEF_PIX_HEIGHT; 135 - 136 - return 0; 137 - } 138 - 139 - static const struct v4l2_subdev_internal_ops fimc_is_sensor_sd_internal_ops = { 140 - .open = fimc_is_sensor_open, 141 - }; 142 - 143 - static int fimc_is_sensor_s_power(struct v4l2_subdev *sd, int on) 144 - { 145 - struct fimc_is_sensor *sensor = sd_to_fimc_is_sensor(sd); 146 - int gpio = sensor->gpio_reset; 147 - int ret; 148 - 149 - if (on) { 150 - ret = pm_runtime_get(sensor->dev); 151 - if (ret < 0) 152 - return ret; 153 - 154 - ret = regulator_bulk_enable(SENSOR_NUM_SUPPLIES, 155 - sensor->supplies); 156 - if (ret < 0) { 157 - pm_runtime_put(sensor->dev); 158 - return ret; 159 - } 160 - if (gpio_is_valid(gpio)) { 161 - gpio_set_value(gpio, 1); 162 - usleep_range(600, 800); 163 - gpio_set_value(gpio, 0); 164 - usleep_range(10000, 11000); 165 - gpio_set_value(gpio, 1); 166 - } 167 - 168 - /* A delay needed for the sensor initialization. */ 169 - msleep(20); 170 - } else { 171 - if (gpio_is_valid(gpio)) 172 - gpio_set_value(gpio, 0); 173 - 174 - ret = regulator_bulk_disable(SENSOR_NUM_SUPPLIES, 175 - sensor->supplies); 176 - if (!ret) 177 - pm_runtime_put(sensor->dev); 178 - } 179 - 180 - pr_info("%s:%d: on: %d, ret: %d\n", __func__, __LINE__, on, ret); 181 - 182 - return ret; 183 - } 184 - 185 - static struct v4l2_subdev_core_ops fimc_is_sensor_core_ops = { 186 - .s_power = fimc_is_sensor_s_power, 187 - }; 188 - 189 - static struct v4l2_subdev_ops fimc_is_sensor_subdev_ops = { 190 - .core = &fimc_is_sensor_core_ops, 191 - .pad = &fimc_is_sensor_pad_ops, 192 - }; 193 - 194 - static const struct of_device_id fimc_is_sensor_of_match[]; 195 - 196 - static int fimc_is_sensor_probe(struct i2c_client *client, 197 - const struct i2c_device_id *id) 198 - { 199 - struct device *dev = &client->dev; 200 - struct fimc_is_sensor *sensor; 201 - const struct of_device_id *of_id; 202 - struct v4l2_subdev *sd; 203 - int gpio, i, ret; 204 - 205 - sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL); 206 - if (!sensor) 207 - return -ENOMEM; 208 - 209 - mutex_init(&sensor->lock); 210 - sensor->gpio_reset = -EINVAL; 211 - 212 - gpio = of_get_gpio_flags(dev->of_node, 0, NULL); 213 - if (gpio_is_valid(gpio)) { 214 - ret = devm_gpio_request_one(dev, gpio, GPIOF_OUT_INIT_LOW, 215 - DRIVER_NAME); 216 - if (ret < 0) 217 - return ret; 218 - } 219 - sensor->gpio_reset = gpio; 220 - 221 - for (i = 0; i < SENSOR_NUM_SUPPLIES; i++) 222 - sensor->supplies[i].supply = sensor_supply_names[i]; 223 - 224 - ret = devm_regulator_bulk_get(&client->dev, SENSOR_NUM_SUPPLIES, 225 - sensor->supplies); 226 - if (ret < 0) 227 - return ret; 228 - 229 - of_id = of_match_node(fimc_is_sensor_of_match, dev->of_node); 230 - if (!of_id) 231 - return -ENODEV; 232 - 233 - sensor->drvdata = of_id->data; 234 - sensor->dev = dev; 235 - 236 - sd = &sensor->subdev; 237 - v4l2_i2c_subdev_init(sd, client, &fimc_is_sensor_subdev_ops); 238 - snprintf(sd->name, sizeof(sd->name), sensor->drvdata->subdev_name); 239 - sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 240 - 241 - sensor->format.code = fimc_is_sensor_formats[0].code; 242 - sensor->format.width = FIMC_IS_SENSOR_DEF_PIX_WIDTH; 243 - sensor->format.height = FIMC_IS_SENSOR_DEF_PIX_HEIGHT; 244 - 245 - sensor->pad.flags = MEDIA_PAD_FL_SOURCE; 246 - ret = media_entity_init(&sd->entity, 1, &sensor->pad, 0); 247 - if (ret < 0) 248 - return ret; 249 - 250 - pm_runtime_no_callbacks(dev); 251 - pm_runtime_enable(dev); 252 - 253 - return ret; 254 - } 255 - 256 - static int fimc_is_sensor_remove(struct i2c_client *client) 257 - { 258 - struct v4l2_subdev *sd = i2c_get_clientdata(client); 259 - media_entity_cleanup(&sd->entity); 260 - return 0; 261 - } 262 - 263 - static const struct i2c_device_id fimc_is_sensor_ids[] = { 264 - { } 265 - }; 266 13 267 14 static const struct sensor_drv_data s5k6a3_drvdata = { 268 15 .id = FIMC_IS_SENSOR_ID_S5K6A3, 269 - .subdev_name = "S5K6A3", 270 - .width = S5K6A3_SENSOR_WIDTH, 271 - .height = S5K6A3_SENSOR_HEIGHT, 16 + .open_timeout = S5K6A3_OPEN_TIMEOUT, 272 17 }; 273 18 274 - static const struct of_device_id fimc_is_sensor_of_match[] = { 19 + static const struct of_device_id fimc_is_sensor_of_ids[] = { 275 20 { 276 21 .compatible = "samsung,s5k6a3", 277 22 .data = &s5k6a3_drvdata, ··· 24 279 { } 25 280 }; 26 281 27 - static struct i2c_driver fimc_is_sensor_driver = { 28 - .driver = { 29 - .of_match_table = fimc_is_sensor_of_match, 30 - .name = DRIVER_NAME, 31 - .owner = THIS_MODULE, 32 - }, 33 - .probe = fimc_is_sensor_probe, 34 - .remove = fimc_is_sensor_remove, 35 - .id_table = fimc_is_sensor_ids, 36 - }; 37 - 38 - int fimc_is_register_sensor_driver(void) 282 + const struct sensor_drv_data *fimc_is_sensor_get_drvdata( 283 + struct device_node *node) 39 284 { 40 - return i2c_add_driver(&fimc_is_sensor_driver); 41 - } 285 + const struct of_device_id *of_id; 42 286 43 - void fimc_is_unregister_sensor_driver(void) 44 - { 45 - i2c_del_driver(&fimc_is_sensor_driver); 287 + of_id = of_match_node(fimc_is_sensor_of_ids, node); 288 + return of_id ? of_id->data : NULL; 46 289 } 47 - 48 - MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>"); 49 - MODULE_DESCRIPTION("Exynos4x12 FIMC-IS image sensor subdev driver"); 50 - MODULE_LICENSE("GPL");
+8 -41
drivers/media/platform/exynos4-is/fimc-is-sensor.h
··· 13 13 #ifndef FIMC_IS_SENSOR_H_ 14 14 #define FIMC_IS_SENSOR_H_ 15 15 16 - #include <linux/clk.h> 17 - #include <linux/device.h> 18 - #include <linux/kernel.h> 19 - #include <linux/platform_device.h> 20 - #include <linux/regulator/consumer.h> 21 - #include <linux/videodev2.h> 22 - #include <media/v4l2-subdev.h> 16 + #include <linux/of.h> 17 + #include <linux/types.h> 23 18 24 - #define FIMC_IS_SENSOR_OPEN_TIMEOUT 2000 /* ms */ 25 - 26 - #define FIMC_IS_SENSOR_DEF_PIX_WIDTH 1296 27 - #define FIMC_IS_SENSOR_DEF_PIX_HEIGHT 732 28 - 19 + #define S5K6A3_OPEN_TIMEOUT 2000 /* ms */ 29 20 #define S5K6A3_SENSOR_WIDTH 1392 30 21 #define S5K6A3_SENSOR_HEIGHT 1392 31 - 32 - #define SENSOR_NUM_SUPPLIES 2 33 22 34 23 enum fimc_is_sensor_id { 35 24 FIMC_IS_SENSOR_ID_S5K3H2 = 1, ··· 34 45 35 46 struct sensor_drv_data { 36 47 enum fimc_is_sensor_id id; 37 - const char * const subdev_name; 38 - unsigned int width; 39 - unsigned int height; 48 + /* sensor open timeout in ms */ 49 + unsigned short open_timeout; 40 50 }; 41 51 42 52 /** 43 53 * struct fimc_is_sensor - fimc-is sensor data structure 44 - * @dev: pointer to this I2C client device structure 45 - * @subdev: the image sensor's v4l2 subdev 46 - * @pad: subdev media source pad 47 - * @supplies: image sensor's voltage regulator supplies 48 - * @gpio_reset: GPIO connected to the sensor's reset pin 49 54 * @drvdata: a pointer to the sensor's parameters data structure 50 55 * @i2c_bus: ISP I2C bus index (0...1) 51 56 * @test_pattern: true to enable video test pattern 52 - * @lock: mutex protecting the structure's members below 53 - * @format: media bus format at the sensor's source pad 54 57 */ 55 58 struct fimc_is_sensor { 56 - struct device *dev; 57 - struct v4l2_subdev subdev; 58 - struct media_pad pad; 59 - struct regulator_bulk_data supplies[SENSOR_NUM_SUPPLIES]; 60 - int gpio_reset; 61 59 const struct sensor_drv_data *drvdata; 62 60 unsigned int i2c_bus; 63 - bool test_pattern; 64 - 65 - struct mutex lock; 66 - struct v4l2_mbus_framefmt format; 61 + u8 test_pattern; 67 62 }; 68 63 69 - static inline 70 - struct fimc_is_sensor *sd_to_fimc_is_sensor(struct v4l2_subdev *sd) 71 - { 72 - return container_of(sd, struct fimc_is_sensor, subdev); 73 - } 74 - 75 - int fimc_is_register_sensor_driver(void); 76 - void fimc_is_unregister_sensor_driver(void); 64 + const struct sensor_drv_data *fimc_is_sensor_get_drvdata( 65 + struct device_node *node); 77 66 78 67 #endif /* FIMC_IS_SENSOR_H_ */
+42 -58
drivers/media/platform/exynos4-is/fimc-is.c
··· 161 161 } 162 162 } 163 163 164 - static int fimc_is_parse_sensor_config(struct fimc_is_sensor *sensor, 165 - struct device_node *np) 164 + static int fimc_is_parse_sensor_config(struct fimc_is *is, unsigned int index, 165 + struct device_node *node) 166 166 { 167 + struct fimc_is_sensor *sensor = &is->sensor[index]; 167 168 u32 tmp = 0; 168 169 int ret; 169 170 170 - np = of_graph_get_next_endpoint(np, NULL); 171 - if (!np) 171 + sensor->drvdata = fimc_is_sensor_get_drvdata(node); 172 + if (!sensor->drvdata) { 173 + dev_err(&is->pdev->dev, "no driver data found for: %s\n", 174 + node->full_name); 175 + return -EINVAL; 176 + } 177 + 178 + node = of_graph_get_next_endpoint(node, NULL); 179 + if (!node) 172 180 return -ENXIO; 173 - np = of_graph_get_remote_port(np); 174 - if (!np) 181 + 182 + node = of_graph_get_remote_port(node); 183 + if (!node) 175 184 return -ENXIO; 176 185 177 186 /* Use MIPI-CSIS channel id to determine the ISP I2C bus index. */ 178 - ret = of_property_read_u32(np, "reg", &tmp); 179 - sensor->i2c_bus = tmp - FIMC_INPUT_MIPI_CSI2_0; 187 + ret = of_property_read_u32(node, "reg", &tmp); 188 + if (ret < 0) { 189 + dev_err(&is->pdev->dev, "reg property not found at: %s\n", 190 + node->full_name); 191 + return ret; 192 + } 180 193 181 - return ret; 194 + sensor->i2c_bus = tmp - FIMC_INPUT_MIPI_CSI2_0; 195 + return 0; 182 196 } 183 197 184 198 static int fimc_is_register_subdevs(struct fimc_is *is) 185 199 { 186 - struct device_node *adapter, *child; 187 - int ret; 200 + struct device_node *i2c_bus, *child; 201 + int ret, index = 0; 188 202 189 203 ret = fimc_isp_subdev_create(&is->isp); 190 204 if (ret < 0) 191 205 return ret; 192 206 193 - for_each_compatible_node(adapter, NULL, FIMC_IS_I2C_COMPATIBLE) { 194 - if (!of_find_device_by_node(adapter)) { 195 - of_node_put(adapter); 196 - return -EPROBE_DEFER; 197 - } 207 + /* Initialize memory allocator context for the ISP DMA. */ 208 + is->isp.alloc_ctx = is->alloc_ctx; 198 209 199 - for_each_available_child_of_node(adapter, child) { 200 - struct i2c_client *client; 201 - struct v4l2_subdev *sd; 210 + for_each_compatible_node(i2c_bus, NULL, FIMC_IS_I2C_COMPATIBLE) { 211 + for_each_available_child_of_node(i2c_bus, child) { 212 + ret = fimc_is_parse_sensor_config(is, index, child); 202 213 203 - client = of_find_i2c_device_by_node(child); 204 - if (!client) 205 - goto e_retry; 206 - 207 - sd = i2c_get_clientdata(client); 208 - if (!sd) 209 - goto e_retry; 210 - 211 - /* FIXME: Add support for multiple sensors. */ 212 - if (WARN_ON(is->sensor)) 213 - continue; 214 - 215 - is->sensor = sd_to_fimc_is_sensor(sd); 216 - 217 - if (fimc_is_parse_sensor_config(is->sensor, child)) { 218 - dev_warn(&is->pdev->dev, "DT parse error: %s\n", 219 - child->full_name); 214 + if (ret < 0 || index >= FIMC_IS_SENSORS_NUM) { 215 + of_node_put(child); 216 + return ret; 220 217 } 221 - pr_debug("%s(): registered subdev: %p\n", 222 - __func__, sd->name); 218 + index++; 223 219 } 224 220 } 225 221 return 0; 226 - 227 - e_retry: 228 - of_node_put(child); 229 - return -EPROBE_DEFER; 230 222 } 231 223 232 224 static int fimc_is_unregister_subdevs(struct fimc_is *is) 233 225 { 234 226 fimc_isp_subdev_destroy(&is->isp); 235 - is->sensor = NULL; 236 227 return 0; 237 228 } 238 229 ··· 638 647 fimc_is_hw_set_intgr0_gd0(is); 639 648 640 649 return fimc_is_wait_event(is, IS_ST_OPEN_SENSOR, 1, 641 - FIMC_IS_SENSOR_OPEN_TIMEOUT); 650 + sensor->drvdata->open_timeout); 642 651 } 643 652 644 653 ··· 652 661 u32 prev_id; 653 662 int i, ret; 654 663 655 - /* Sensor initialization. */ 656 - ret = fimc_is_hw_open_sensor(is, is->sensor); 664 + /* Sensor initialization. Only one sensor is currently supported. */ 665 + ret = fimc_is_hw_open_sensor(is, &is->sensor[0]); 657 666 if (ret < 0) 658 667 return ret; 659 668 ··· 968 977 { 969 978 int ret; 970 979 971 - ret = fimc_is_register_sensor_driver(); 972 - if (ret < 0) 973 - return ret; 974 - 975 980 ret = fimc_is_register_i2c_driver(); 976 981 if (ret < 0) 977 - goto err_sens; 978 - 979 - ret = platform_driver_register(&fimc_is_driver); 980 - if (!ret) 981 982 return ret; 982 983 983 - fimc_is_unregister_i2c_driver(); 984 - err_sens: 985 - fimc_is_unregister_sensor_driver(); 984 + ret = platform_driver_register(&fimc_is_driver); 985 + 986 + if (ret < 0) 987 + fimc_is_unregister_i2c_driver(); 988 + 986 989 return ret; 987 990 } 988 991 989 992 static void fimc_is_module_exit(void) 990 993 { 991 - fimc_is_unregister_sensor_driver(); 992 994 fimc_is_unregister_i2c_driver(); 993 995 platform_driver_unregister(&fimc_is_driver); 994 996 }
+7 -2
drivers/media/platform/exynos4-is/fimc-is.h
··· 39 39 #define FIMC_IS_FW_LOAD_TIMEOUT 1000 /* ms */ 40 40 #define FIMC_IS_POWER_ON_TIMEOUT 1000 /* us */ 41 41 42 - #define FIMC_IS_SENSOR_NUM 2 42 + #define FIMC_IS_SENSORS_NUM 2 43 43 44 44 /* Memory definitions */ 45 45 #define FIMC_IS_CPU_MEM_SIZE (0xa00000) ··· 253 253 struct firmware *f_w; 254 254 255 255 struct fimc_isp isp; 256 - struct fimc_is_sensor *sensor; 256 + struct fimc_is_sensor sensor[FIMC_IS_SENSORS_NUM]; 257 257 struct fimc_is_setfile setfile; 258 258 259 259 struct vb2_alloc_ctx *alloc_ctx; ··· 290 290 static inline struct fimc_is *fimc_isp_to_is(struct fimc_isp *isp) 291 291 { 292 292 return container_of(isp, struct fimc_is, isp); 293 + } 294 + 295 + static inline struct chain_config *__get_curr_is_config(struct fimc_is *is) 296 + { 297 + return &is->config[is->config_index]; 293 298 } 294 299 295 300 static inline void fimc_is_mem_barrier(void)
+660
drivers/media/platform/exynos4-is/fimc-isp-video.c
··· 1 + /* 2 + * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver 3 + * 4 + * FIMC-IS ISP video input and video output DMA interface driver 5 + * 6 + * Copyright (C) 2013 Samsung Electronics Co., Ltd. 7 + * Author: Sylwester Nawrocki <s.nawrocki@samsung.com> 8 + * 9 + * The hardware handling code derived from a driver written by 10 + * Younghwan Joo <yhwan.joo@samsung.com>. 11 + * 12 + * This program is free software; you can redistribute it and/or modify 13 + * it under the terms of the GNU General Public License version 2 as 14 + * published by the Free Software Foundation. 15 + */ 16 + 17 + #include <linux/bitops.h> 18 + #include <linux/device.h> 19 + #include <linux/delay.h> 20 + #include <linux/errno.h> 21 + #include <linux/kernel.h> 22 + #include <linux/module.h> 23 + #include <linux/types.h> 24 + #include <linux/printk.h> 25 + #include <linux/pm_runtime.h> 26 + #include <linux/slab.h> 27 + #include <linux/videodev2.h> 28 + 29 + #include <media/v4l2-device.h> 30 + #include <media/v4l2-ioctl.h> 31 + #include <media/videobuf2-core.h> 32 + #include <media/videobuf2-dma-contig.h> 33 + #include <media/s5p_fimc.h> 34 + 35 + #include "common.h" 36 + #include "media-dev.h" 37 + #include "fimc-is.h" 38 + #include "fimc-isp-video.h" 39 + #include "fimc-is-param.h" 40 + 41 + static int isp_video_capture_queue_setup(struct vb2_queue *vq, 42 + const struct v4l2_format *pfmt, 43 + unsigned int *num_buffers, unsigned int *num_planes, 44 + unsigned int sizes[], void *allocators[]) 45 + { 46 + struct fimc_isp *isp = vb2_get_drv_priv(vq); 47 + struct v4l2_pix_format_mplane *vid_fmt = &isp->video_capture.pixfmt; 48 + const struct v4l2_pix_format_mplane *pixm = NULL; 49 + const struct fimc_fmt *fmt; 50 + unsigned int wh, i; 51 + 52 + if (pfmt) { 53 + pixm = &pfmt->fmt.pix_mp; 54 + fmt = fimc_isp_find_format(&pixm->pixelformat, NULL, -1); 55 + wh = pixm->width * pixm->height; 56 + } else { 57 + fmt = isp->video_capture.format; 58 + wh = vid_fmt->width * vid_fmt->height; 59 + } 60 + 61 + if (fmt == NULL) 62 + return -EINVAL; 63 + 64 + *num_buffers = clamp_t(u32, *num_buffers, FIMC_ISP_REQ_BUFS_MIN, 65 + FIMC_ISP_REQ_BUFS_MAX); 66 + *num_planes = fmt->memplanes; 67 + 68 + for (i = 0; i < fmt->memplanes; i++) { 69 + unsigned int size = (wh * fmt->depth[i]) / 8; 70 + if (pixm) 71 + sizes[i] = max(size, pixm->plane_fmt[i].sizeimage); 72 + else 73 + sizes[i] = size; 74 + allocators[i] = isp->alloc_ctx; 75 + } 76 + 77 + return 0; 78 + } 79 + 80 + static inline struct param_dma_output *__get_isp_dma2(struct fimc_is *is) 81 + { 82 + return &__get_curr_is_config(is)->isp.dma2_output; 83 + } 84 + 85 + static int isp_video_capture_start_streaming(struct vb2_queue *q, 86 + unsigned int count) 87 + { 88 + struct fimc_isp *isp = vb2_get_drv_priv(q); 89 + struct fimc_is *is = fimc_isp_to_is(isp); 90 + struct param_dma_output *dma = __get_isp_dma2(is); 91 + struct fimc_is_video *video = &isp->video_capture; 92 + int ret; 93 + 94 + if (!test_bit(ST_ISP_VID_CAP_BUF_PREP, &isp->state) || 95 + test_bit(ST_ISP_VID_CAP_STREAMING, &isp->state)) 96 + return 0; 97 + 98 + 99 + dma->cmd = DMA_OUTPUT_COMMAND_ENABLE; 100 + dma->notify_dma_done = DMA_OUTPUT_NOTIFY_DMA_DONE_ENABLE; 101 + dma->buffer_address = is->is_dma_p_region + 102 + DMA2_OUTPUT_ADDR_ARRAY_OFFS; 103 + dma->buffer_number = video->reqbufs_count; 104 + dma->dma_out_mask = video->buf_mask; 105 + 106 + isp_dbg(2, &video->ve.vdev, 107 + "buf_count: %d, planes: %d, dma addr table: %#x\n", 108 + video->buf_count, video->format->memplanes, 109 + dma->buffer_address); 110 + 111 + fimc_is_mem_barrier(); 112 + 113 + fimc_is_set_param_bit(is, PARAM_ISP_DMA2_OUTPUT); 114 + __fimc_is_hw_update_param(is, PARAM_ISP_DMA2_OUTPUT); 115 + 116 + ret = fimc_is_itf_s_param(is, false); 117 + if (ret < 0) 118 + return ret; 119 + 120 + ret = fimc_pipeline_call(&video->ve, set_stream, 1); 121 + if (ret < 0) 122 + return ret; 123 + 124 + set_bit(ST_ISP_VID_CAP_STREAMING, &isp->state); 125 + return ret; 126 + } 127 + 128 + static int isp_video_capture_stop_streaming(struct vb2_queue *q) 129 + { 130 + struct fimc_isp *isp = vb2_get_drv_priv(q); 131 + struct fimc_is *is = fimc_isp_to_is(isp); 132 + struct param_dma_output *dma = __get_isp_dma2(is); 133 + int ret; 134 + 135 + ret = fimc_pipeline_call(&isp->video_capture.ve, set_stream, 0); 136 + if (ret < 0) 137 + return ret; 138 + 139 + dma->cmd = DMA_OUTPUT_COMMAND_DISABLE; 140 + dma->notify_dma_done = DMA_OUTPUT_NOTIFY_DMA_DONE_DISABLE; 141 + dma->buffer_number = 0; 142 + dma->buffer_address = 0; 143 + dma->dma_out_mask = 0; 144 + 145 + fimc_is_set_param_bit(is, PARAM_ISP_DMA2_OUTPUT); 146 + __fimc_is_hw_update_param(is, PARAM_ISP_DMA2_OUTPUT); 147 + 148 + ret = fimc_is_itf_s_param(is, false); 149 + if (ret < 0) 150 + dev_warn(&is->pdev->dev, "%s: DMA stop failed\n", __func__); 151 + 152 + fimc_is_hw_set_isp_buf_mask(is, 0); 153 + 154 + clear_bit(ST_ISP_VID_CAP_BUF_PREP, &isp->state); 155 + clear_bit(ST_ISP_VID_CAP_STREAMING, &isp->state); 156 + 157 + isp->video_capture.buf_count = 0; 158 + return 0; 159 + } 160 + 161 + static int isp_video_capture_buffer_prepare(struct vb2_buffer *vb) 162 + { 163 + struct fimc_isp *isp = vb2_get_drv_priv(vb->vb2_queue); 164 + struct fimc_is_video *video = &isp->video_capture; 165 + int i; 166 + 167 + if (video->format == NULL) 168 + return -EINVAL; 169 + 170 + for (i = 0; i < video->format->memplanes; i++) { 171 + unsigned long size = video->pixfmt.plane_fmt[i].sizeimage; 172 + 173 + if (vb2_plane_size(vb, i) < size) { 174 + v4l2_err(&video->ve.vdev, 175 + "User buffer too small (%ld < %ld)\n", 176 + vb2_plane_size(vb, i), size); 177 + return -EINVAL; 178 + } 179 + vb2_set_plane_payload(vb, i, size); 180 + } 181 + 182 + /* Check if we get one of the already known buffers. */ 183 + if (test_bit(ST_ISP_VID_CAP_BUF_PREP, &isp->state)) { 184 + dma_addr_t dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0); 185 + int i; 186 + 187 + for (i = 0; i < video->buf_count; i++) 188 + if (video->buffers[i]->dma_addr[0] == dma_addr) 189 + return 0; 190 + return -ENXIO; 191 + } 192 + 193 + return 0; 194 + } 195 + 196 + static void isp_video_capture_buffer_queue(struct vb2_buffer *vb) 197 + { 198 + struct fimc_isp *isp = vb2_get_drv_priv(vb->vb2_queue); 199 + struct fimc_is_video *video = &isp->video_capture; 200 + struct fimc_is *is = fimc_isp_to_is(isp); 201 + struct isp_video_buf *ivb = to_isp_video_buf(vb); 202 + unsigned long flags; 203 + unsigned int i; 204 + 205 + if (test_bit(ST_ISP_VID_CAP_BUF_PREP, &isp->state)) { 206 + spin_lock_irqsave(&is->slock, flags); 207 + video->buf_mask |= BIT(ivb->index); 208 + spin_unlock_irqrestore(&is->slock, flags); 209 + } else { 210 + unsigned int num_planes = video->format->memplanes; 211 + 212 + ivb->index = video->buf_count; 213 + video->buffers[ivb->index] = ivb; 214 + 215 + for (i = 0; i < num_planes; i++) { 216 + int buf_index = ivb->index * num_planes + i; 217 + 218 + ivb->dma_addr[i] = vb2_dma_contig_plane_dma_addr(vb, i); 219 + is->is_p_region->shared[32 + buf_index] = 220 + ivb->dma_addr[i]; 221 + 222 + isp_dbg(2, &video->ve.vdev, 223 + "dma_buf %d (%d/%d/%d) addr: %#x\n", 224 + buf_index, ivb->index, i, vb->v4l2_buf.index, 225 + ivb->dma_addr[i]); 226 + } 227 + 228 + if (++video->buf_count < video->reqbufs_count) 229 + return; 230 + 231 + video->buf_mask = (1UL << video->buf_count) - 1; 232 + set_bit(ST_ISP_VID_CAP_BUF_PREP, &isp->state); 233 + } 234 + 235 + if (!test_bit(ST_ISP_VID_CAP_STREAMING, &isp->state)) 236 + isp_video_capture_start_streaming(vb->vb2_queue, 0); 237 + } 238 + 239 + /* 240 + * FIMC-IS ISP input and output DMA interface interrupt handler. 241 + * Locking: called with is->slock spinlock held. 242 + */ 243 + void fimc_isp_video_irq_handler(struct fimc_is *is) 244 + { 245 + struct fimc_is_video *video = &is->isp.video_capture; 246 + struct vb2_buffer *vb; 247 + int buf_index; 248 + 249 + /* TODO: Ensure the DMA is really stopped in stop_streaming callback */ 250 + if (!test_bit(ST_ISP_VID_CAP_STREAMING, &is->isp.state)) 251 + return; 252 + 253 + buf_index = (is->i2h_cmd.args[1] - 1) % video->buf_count; 254 + vb = &video->buffers[buf_index]->vb; 255 + 256 + v4l2_get_timestamp(&vb->v4l2_buf.timestamp); 257 + vb2_buffer_done(vb, VB2_BUF_STATE_DONE); 258 + 259 + video->buf_mask &= ~BIT(buf_index); 260 + fimc_is_hw_set_isp_buf_mask(is, video->buf_mask); 261 + } 262 + 263 + static const struct vb2_ops isp_video_capture_qops = { 264 + .queue_setup = isp_video_capture_queue_setup, 265 + .buf_prepare = isp_video_capture_buffer_prepare, 266 + .buf_queue = isp_video_capture_buffer_queue, 267 + .wait_prepare = vb2_ops_wait_prepare, 268 + .wait_finish = vb2_ops_wait_finish, 269 + .start_streaming = isp_video_capture_start_streaming, 270 + .stop_streaming = isp_video_capture_stop_streaming, 271 + }; 272 + 273 + static int isp_video_open(struct file *file) 274 + { 275 + struct fimc_isp *isp = video_drvdata(file); 276 + struct exynos_video_entity *ve = &isp->video_capture.ve; 277 + struct media_entity *me = &ve->vdev.entity; 278 + int ret; 279 + 280 + if (mutex_lock_interruptible(&isp->video_lock)) 281 + return -ERESTARTSYS; 282 + 283 + ret = v4l2_fh_open(file); 284 + if (ret < 0) 285 + goto unlock; 286 + 287 + ret = pm_runtime_get_sync(&isp->pdev->dev); 288 + if (ret < 0) 289 + goto rel_fh; 290 + 291 + if (v4l2_fh_is_singular_file(file)) { 292 + mutex_lock(&me->parent->graph_mutex); 293 + 294 + ret = fimc_pipeline_call(ve, open, me, true); 295 + 296 + /* Mark the video pipeline as in use. */ 297 + if (ret == 0) 298 + me->use_count++; 299 + 300 + mutex_unlock(&me->parent->graph_mutex); 301 + } 302 + if (!ret) 303 + goto unlock; 304 + rel_fh: 305 + v4l2_fh_release(file); 306 + unlock: 307 + mutex_unlock(&isp->video_lock); 308 + return ret; 309 + } 310 + 311 + static int isp_video_release(struct file *file) 312 + { 313 + struct fimc_isp *isp = video_drvdata(file); 314 + struct fimc_is_video *ivc = &isp->video_capture; 315 + struct media_entity *entity = &ivc->ve.vdev.entity; 316 + struct media_device *mdev = entity->parent; 317 + int ret = 0; 318 + 319 + mutex_lock(&isp->video_lock); 320 + 321 + if (v4l2_fh_is_singular_file(file) && ivc->streaming) { 322 + media_entity_pipeline_stop(entity); 323 + ivc->streaming = 0; 324 + } 325 + 326 + vb2_fop_release(file); 327 + 328 + if (v4l2_fh_is_singular_file(file)) { 329 + fimc_pipeline_call(&ivc->ve, close); 330 + 331 + mutex_lock(&mdev->graph_mutex); 332 + entity->use_count--; 333 + mutex_unlock(&mdev->graph_mutex); 334 + } 335 + 336 + pm_runtime_put(&isp->pdev->dev); 337 + mutex_unlock(&isp->video_lock); 338 + 339 + return ret; 340 + } 341 + 342 + static const struct v4l2_file_operations isp_video_fops = { 343 + .owner = THIS_MODULE, 344 + .open = isp_video_open, 345 + .release = isp_video_release, 346 + .poll = vb2_fop_poll, 347 + .unlocked_ioctl = video_ioctl2, 348 + .mmap = vb2_fop_mmap, 349 + }; 350 + 351 + /* 352 + * Video node ioctl operations 353 + */ 354 + static int isp_video_querycap(struct file *file, void *priv, 355 + struct v4l2_capability *cap) 356 + { 357 + struct fimc_isp *isp = video_drvdata(file); 358 + 359 + __fimc_vidioc_querycap(&isp->pdev->dev, cap, V4L2_CAP_STREAMING); 360 + return 0; 361 + } 362 + 363 + static int isp_video_enum_fmt_mplane(struct file *file, void *priv, 364 + struct v4l2_fmtdesc *f) 365 + { 366 + const struct fimc_fmt *fmt; 367 + 368 + if (f->index >= FIMC_ISP_NUM_FORMATS) 369 + return -EINVAL; 370 + 371 + fmt = fimc_isp_find_format(NULL, NULL, f->index); 372 + if (WARN_ON(fmt == NULL)) 373 + return -EINVAL; 374 + 375 + strlcpy(f->description, fmt->name, sizeof(f->description)); 376 + f->pixelformat = fmt->fourcc; 377 + 378 + return 0; 379 + } 380 + 381 + static int isp_video_g_fmt_mplane(struct file *file, void *fh, 382 + struct v4l2_format *f) 383 + { 384 + struct fimc_isp *isp = video_drvdata(file); 385 + 386 + f->fmt.pix_mp = isp->video_capture.pixfmt; 387 + return 0; 388 + } 389 + 390 + static void __isp_video_try_fmt(struct fimc_isp *isp, 391 + struct v4l2_pix_format_mplane *pixm, 392 + const struct fimc_fmt **fmt) 393 + { 394 + *fmt = fimc_isp_find_format(&pixm->pixelformat, NULL, 2); 395 + 396 + pixm->colorspace = V4L2_COLORSPACE_SRGB; 397 + pixm->field = V4L2_FIELD_NONE; 398 + pixm->num_planes = (*fmt)->memplanes; 399 + pixm->pixelformat = (*fmt)->fourcc; 400 + /* 401 + * TODO: double check with the docmentation these width/height 402 + * constraints are correct. 403 + */ 404 + v4l_bound_align_image(&pixm->width, FIMC_ISP_SOURCE_WIDTH_MIN, 405 + FIMC_ISP_SOURCE_WIDTH_MAX, 3, 406 + &pixm->height, FIMC_ISP_SOURCE_HEIGHT_MIN, 407 + FIMC_ISP_SOURCE_HEIGHT_MAX, 0, 0); 408 + } 409 + 410 + static int isp_video_try_fmt_mplane(struct file *file, void *fh, 411 + struct v4l2_format *f) 412 + { 413 + struct fimc_isp *isp = video_drvdata(file); 414 + 415 + __isp_video_try_fmt(isp, &f->fmt.pix_mp, NULL); 416 + return 0; 417 + } 418 + 419 + static int isp_video_s_fmt_mplane(struct file *file, void *priv, 420 + struct v4l2_format *f) 421 + { 422 + struct fimc_isp *isp = video_drvdata(file); 423 + struct fimc_is *is = fimc_isp_to_is(isp); 424 + struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp; 425 + const struct fimc_fmt *ifmt = NULL; 426 + struct param_dma_output *dma = __get_isp_dma2(is); 427 + 428 + __isp_video_try_fmt(isp, pixm, &ifmt); 429 + 430 + if (WARN_ON(ifmt == NULL)) 431 + return -EINVAL; 432 + 433 + dma->format = DMA_OUTPUT_FORMAT_BAYER; 434 + dma->order = DMA_OUTPUT_ORDER_GB_BG; 435 + dma->plane = ifmt->memplanes; 436 + dma->bitwidth = ifmt->depth[0]; 437 + dma->width = pixm->width; 438 + dma->height = pixm->height; 439 + 440 + fimc_is_mem_barrier(); 441 + 442 + isp->video_capture.format = ifmt; 443 + isp->video_capture.pixfmt = *pixm; 444 + 445 + return 0; 446 + } 447 + 448 + /* 449 + * Check for source/sink format differences at each link. 450 + * Return 0 if the formats match or -EPIPE otherwise. 451 + */ 452 + static int isp_video_pipeline_validate(struct fimc_isp *isp) 453 + { 454 + struct v4l2_subdev *sd = &isp->subdev; 455 + struct v4l2_subdev_format sink_fmt, src_fmt; 456 + struct media_pad *pad; 457 + int ret; 458 + 459 + while (1) { 460 + /* Retrieve format at the sink pad */ 461 + pad = &sd->entity.pads[0]; 462 + if (!(pad->flags & MEDIA_PAD_FL_SINK)) 463 + break; 464 + sink_fmt.pad = pad->index; 465 + sink_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; 466 + ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sink_fmt); 467 + if (ret < 0 && ret != -ENOIOCTLCMD) 468 + return -EPIPE; 469 + 470 + /* Retrieve format at the source pad */ 471 + pad = media_entity_remote_pad(pad); 472 + if (pad == NULL || 473 + media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) 474 + break; 475 + 476 + sd = media_entity_to_v4l2_subdev(pad->entity); 477 + src_fmt.pad = pad->index; 478 + src_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; 479 + ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &src_fmt); 480 + if (ret < 0 && ret != -ENOIOCTLCMD) 481 + return -EPIPE; 482 + 483 + if (src_fmt.format.width != sink_fmt.format.width || 484 + src_fmt.format.height != sink_fmt.format.height || 485 + src_fmt.format.code != sink_fmt.format.code) 486 + return -EPIPE; 487 + } 488 + 489 + return 0; 490 + } 491 + 492 + static int isp_video_streamon(struct file *file, void *priv, 493 + enum v4l2_buf_type type) 494 + { 495 + struct fimc_isp *isp = video_drvdata(file); 496 + struct exynos_video_entity *ve = &isp->video_capture.ve; 497 + struct media_entity *me = &ve->vdev.entity; 498 + int ret; 499 + 500 + ret = media_entity_pipeline_start(me, &ve->pipe->mp); 501 + if (ret < 0) 502 + return ret; 503 + 504 + ret = isp_video_pipeline_validate(isp); 505 + if (ret < 0) 506 + goto p_stop; 507 + 508 + ret = vb2_ioctl_streamon(file, priv, type); 509 + if (ret < 0) 510 + goto p_stop; 511 + 512 + isp->video_capture.streaming = 1; 513 + return 0; 514 + p_stop: 515 + media_entity_pipeline_stop(me); 516 + return ret; 517 + } 518 + 519 + static int isp_video_streamoff(struct file *file, void *priv, 520 + enum v4l2_buf_type type) 521 + { 522 + struct fimc_isp *isp = video_drvdata(file); 523 + struct fimc_is_video *video = &isp->video_capture; 524 + int ret; 525 + 526 + ret = vb2_ioctl_streamoff(file, priv, type); 527 + if (ret < 0) 528 + return ret; 529 + 530 + media_entity_pipeline_stop(&video->ve.vdev.entity); 531 + video->streaming = 0; 532 + return 0; 533 + } 534 + 535 + static int isp_video_reqbufs(struct file *file, void *priv, 536 + struct v4l2_requestbuffers *rb) 537 + { 538 + struct fimc_isp *isp = video_drvdata(file); 539 + int ret; 540 + 541 + ret = vb2_ioctl_reqbufs(file, priv, rb); 542 + if (ret < 0) 543 + return ret; 544 + 545 + if (rb->count && rb->count < FIMC_ISP_REQ_BUFS_MIN) { 546 + rb->count = 0; 547 + vb2_ioctl_reqbufs(file, priv, rb); 548 + ret = -ENOMEM; 549 + } 550 + 551 + isp->video_capture.reqbufs_count = rb->count; 552 + return ret; 553 + } 554 + 555 + static const struct v4l2_ioctl_ops isp_video_ioctl_ops = { 556 + .vidioc_querycap = isp_video_querycap, 557 + .vidioc_enum_fmt_vid_cap_mplane = isp_video_enum_fmt_mplane, 558 + .vidioc_try_fmt_vid_cap_mplane = isp_video_try_fmt_mplane, 559 + .vidioc_s_fmt_vid_cap_mplane = isp_video_s_fmt_mplane, 560 + .vidioc_g_fmt_vid_cap_mplane = isp_video_g_fmt_mplane, 561 + .vidioc_reqbufs = isp_video_reqbufs, 562 + .vidioc_querybuf = vb2_ioctl_querybuf, 563 + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, 564 + .vidioc_create_bufs = vb2_ioctl_create_bufs, 565 + .vidioc_qbuf = vb2_ioctl_qbuf, 566 + .vidioc_dqbuf = vb2_ioctl_dqbuf, 567 + .vidioc_streamon = isp_video_streamon, 568 + .vidioc_streamoff = isp_video_streamoff, 569 + }; 570 + 571 + int fimc_isp_video_device_register(struct fimc_isp *isp, 572 + struct v4l2_device *v4l2_dev, 573 + enum v4l2_buf_type type) 574 + { 575 + struct vb2_queue *q = &isp->video_capture.vb_queue; 576 + struct fimc_is_video *iv; 577 + struct video_device *vdev; 578 + int ret; 579 + 580 + if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 581 + iv = &isp->video_capture; 582 + else 583 + return -ENOSYS; 584 + 585 + mutex_init(&isp->video_lock); 586 + INIT_LIST_HEAD(&iv->pending_buf_q); 587 + INIT_LIST_HEAD(&iv->active_buf_q); 588 + iv->format = fimc_isp_find_format(NULL, NULL, 0); 589 + iv->pixfmt.width = IS_DEFAULT_WIDTH; 590 + iv->pixfmt.height = IS_DEFAULT_HEIGHT; 591 + iv->pixfmt.pixelformat = iv->format->fourcc; 592 + iv->pixfmt.colorspace = V4L2_COLORSPACE_SRGB; 593 + iv->reqbufs_count = 0; 594 + 595 + memset(q, 0, sizeof(*q)); 596 + q->type = type; 597 + q->io_modes = VB2_MMAP | VB2_USERPTR; 598 + q->ops = &isp_video_capture_qops; 599 + q->mem_ops = &vb2_dma_contig_memops; 600 + q->buf_struct_size = sizeof(struct isp_video_buf); 601 + q->drv_priv = isp; 602 + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 603 + q->lock = &isp->video_lock; 604 + 605 + ret = vb2_queue_init(q); 606 + if (ret < 0) 607 + return ret; 608 + 609 + vdev = &iv->ve.vdev; 610 + memset(vdev, 0, sizeof(*vdev)); 611 + snprintf(vdev->name, sizeof(vdev->name), "fimc-is-isp.%s", 612 + type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ? 613 + "capture" : "output"); 614 + vdev->queue = q; 615 + vdev->fops = &isp_video_fops; 616 + vdev->ioctl_ops = &isp_video_ioctl_ops; 617 + vdev->v4l2_dev = v4l2_dev; 618 + vdev->minor = -1; 619 + vdev->release = video_device_release_empty; 620 + vdev->lock = &isp->video_lock; 621 + 622 + iv->pad.flags = MEDIA_PAD_FL_SINK; 623 + ret = media_entity_init(&vdev->entity, 1, &iv->pad, 0); 624 + if (ret < 0) 625 + return ret; 626 + 627 + video_set_drvdata(vdev, isp); 628 + 629 + ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); 630 + if (ret < 0) { 631 + media_entity_cleanup(&vdev->entity); 632 + return ret; 633 + } 634 + 635 + v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n", 636 + vdev->name, video_device_node_name(vdev)); 637 + 638 + return 0; 639 + } 640 + 641 + void fimc_isp_video_device_unregister(struct fimc_isp *isp, 642 + enum v4l2_buf_type type) 643 + { 644 + struct exynos_video_entity *ve; 645 + 646 + if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 647 + ve = &isp->video_capture.ve; 648 + else 649 + return; 650 + 651 + mutex_lock(&isp->video_lock); 652 + 653 + if (video_is_registered(&ve->vdev)) { 654 + video_unregister_device(&ve->vdev); 655 + media_entity_cleanup(&ve->vdev.entity); 656 + ve->pipe = NULL; 657 + } 658 + 659 + mutex_unlock(&isp->video_lock); 660 + }
+44
drivers/media/platform/exynos4-is/fimc-isp-video.h
··· 1 + /* 2 + * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver 3 + * 4 + * Copyright (C) 2013 Samsung Electronics Co., Ltd. 5 + * Sylwester Nawrocki <s.nawrocki@samsung.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 as 9 + * published by the Free Software Foundation. 10 + */ 11 + #ifndef FIMC_ISP_VIDEO__ 12 + #define FIMC_ISP_VIDEO__ 13 + 14 + #include <media/videobuf2-core.h> 15 + #include "fimc-isp.h" 16 + 17 + #ifdef CONFIG_VIDEO_EXYNOS4_ISP_DMA_CAPTURE 18 + int fimc_isp_video_device_register(struct fimc_isp *isp, 19 + struct v4l2_device *v4l2_dev, 20 + enum v4l2_buf_type type); 21 + 22 + void fimc_isp_video_device_unregister(struct fimc_isp *isp, 23 + enum v4l2_buf_type type); 24 + 25 + void fimc_isp_video_irq_handler(struct fimc_is *is); 26 + #else 27 + static inline void fimc_isp_video_irq_handler(struct fimc_is *is) 28 + { 29 + } 30 + 31 + static inline int fimc_isp_video_device_register(struct fimc_isp *isp, 32 + struct v4l2_device *v4l2_dev, 33 + enum v4l2_buf_type type) 34 + { 35 + return 0; 36 + } 37 + 38 + void fimc_isp_video_device_unregister(struct fimc_isp *isp, 39 + enum v4l2_buf_type type) 40 + { 41 + } 42 + #endif /* !CONFIG_VIDEO_EXYNOS4_ISP_DMA_CAPTURE */ 43 + 44 + #endif /* FIMC_ISP_VIDEO__ */
+28 -1
drivers/media/platform/exynos4-is/fimc-isp.c
··· 25 25 #include <media/v4l2-device.h> 26 26 27 27 #include "media-dev.h" 28 + #include "fimc-isp-video.h" 28 29 #include "fimc-is-command.h" 29 30 #include "fimc-is-param.h" 30 31 #include "fimc-is-regs.h" ··· 94 93 is->i2h_cmd.args[1] = mcuctl_read(is, MCUCTL_REG_ISSR(21)); 95 94 96 95 fimc_is_fw_clear_irq1(is, FIMC_IS_INT_FRAME_DONE_ISP); 96 + fimc_isp_video_irq_handler(is); 97 97 98 - /* TODO: Complete ISP DMA interrupt handler */ 99 98 wake_up(&is->irq_queue); 100 99 } 101 100 ··· 389 388 return 0; 390 389 } 391 390 391 + static int fimc_isp_subdev_registered(struct v4l2_subdev *sd) 392 + { 393 + struct fimc_isp *isp = v4l2_get_subdevdata(sd); 394 + int ret; 395 + 396 + /* Use pipeline object allocated by the media device. */ 397 + isp->video_capture.ve.pipe = v4l2_get_subdev_hostdata(sd); 398 + 399 + ret = fimc_isp_video_device_register(isp, sd->v4l2_dev, 400 + V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 401 + if (ret < 0) 402 + isp->video_capture.ve.pipe = NULL; 403 + 404 + return ret; 405 + } 406 + 407 + static void fimc_isp_subdev_unregistered(struct v4l2_subdev *sd) 408 + { 409 + struct fimc_isp *isp = v4l2_get_subdevdata(sd); 410 + 411 + fimc_isp_video_device_unregister(isp, 412 + V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 413 + } 414 + 392 415 static const struct v4l2_subdev_internal_ops fimc_is_subdev_internal_ops = { 416 + .registered = fimc_isp_subdev_registered, 417 + .unregistered = fimc_isp_subdev_unregistered, 393 418 .open = fimc_isp_subdev_open, 394 419 }; 395 420
+23 -4
drivers/media/platform/exynos4-is/fimc-isp.h
··· 35 35 #define FIMC_ISP_SINK_WIDTH_MIN (16 + 8) 36 36 #define FIMC_ISP_SINK_HEIGHT_MIN (12 + 8) 37 37 #define FIMC_ISP_SOURCE_WIDTH_MIN 8 38 - #define FIMC_ISP_SOURC_HEIGHT_MIN 8 38 + #define FIMC_ISP_SOURCE_HEIGHT_MIN 8 39 39 #define FIMC_ISP_CAC_MARGIN_WIDTH 16 40 40 #define FIMC_ISP_CAC_MARGIN_HEIGHT 12 41 41 42 42 #define FIMC_ISP_SINK_WIDTH_MAX (4000 - 16) 43 43 #define FIMC_ISP_SINK_HEIGHT_MAX (4000 + 12) 44 44 #define FIMC_ISP_SOURCE_WIDTH_MAX 4000 45 - #define FIMC_ISP_SOURC_HEIGHT_MAX 4000 45 + #define FIMC_ISP_SOURCE_HEIGHT_MAX 4000 46 46 47 47 #define FIMC_ISP_NUM_FORMATS 3 48 48 #define FIMC_ISP_REQ_BUFS_MIN 2 49 + #define FIMC_ISP_REQ_BUFS_MAX 32 49 50 50 51 #define FIMC_ISP_SD_PAD_SINK 0 51 52 #define FIMC_ISP_SD_PAD_SRC_FIFO 1 ··· 101 100 struct v4l2_ctrl *colorfx; 102 101 }; 103 102 103 + struct isp_video_buf { 104 + struct vb2_buffer vb; 105 + dma_addr_t dma_addr[FIMC_ISP_MAX_PLANES]; 106 + unsigned int index; 107 + }; 108 + 109 + #define to_isp_video_buf(_b) container_of(_b, struct isp_video_buf, vb) 110 + 111 + #define FIMC_ISP_MAX_BUFS 4 112 + 104 113 /** 105 114 * struct fimc_is_video - fimc-is video device structure 106 115 * @vdev: video_device structure ··· 125 114 * @format: current pixel format 126 115 */ 127 116 struct fimc_is_video { 128 - struct video_device vdev; 117 + struct exynos_video_entity ve; 129 118 enum v4l2_buf_type type; 130 119 struct media_pad pad; 131 120 struct list_head pending_buf_q; 132 121 struct list_head active_buf_q; 133 122 struct vb2_queue vb_queue; 134 - unsigned int frame_count; 135 123 unsigned int reqbufs_count; 124 + unsigned int buf_count; 125 + unsigned int buf_mask; 126 + unsigned int frame_count; 136 127 int streaming; 128 + struct isp_video_buf *buffers[FIMC_ISP_MAX_BUFS]; 137 129 const struct fimc_fmt *format; 130 + struct v4l2_pix_format_mplane pixfmt; 138 131 }; 132 + 133 + /* struct fimc_isp:state bit definitions */ 134 + #define ST_ISP_VID_CAP_BUF_PREP 0 135 + #define ST_ISP_VID_CAP_STREAMING 1 139 136 140 137 /** 141 138 * struct fimc_isp - FIMC-IS ISP data structure
+265 -98
drivers/media/platform/exynos4-is/media-dev.c
··· 11 11 */ 12 12 13 13 #include <linux/bug.h> 14 + #include <linux/clk.h> 15 + #include <linux/clk-provider.h> 14 16 #include <linux/device.h> 15 17 #include <linux/errno.h> 16 18 #include <linux/i2c.h> ··· 27 25 #include <linux/pm_runtime.h> 28 26 #include <linux/types.h> 29 27 #include <linux/slab.h> 28 + #include <media/v4l2-async.h> 30 29 #include <media/v4l2-ctrls.h> 31 30 #include <media/v4l2-of.h> 32 31 #include <media/media-device.h> ··· 222 219 if (ret < 0) 223 220 return ret; 224 221 } 222 + 225 223 ret = fimc_md_set_camclk(sd, true); 226 224 if (ret < 0) 227 225 goto err_wbclk; ··· 383 379 struct i2c_client *client = v4l2_get_subdevdata(sd); 384 380 struct i2c_adapter *adapter; 385 381 386 - if (!client) 382 + if (!client || client->dev.of_node) 387 383 return; 388 384 389 385 v4l2_device_unregister_subdev(sd); 390 386 391 - if (!client->dev.of_node) { 392 - adapter = client->adapter; 393 - i2c_unregister_device(client); 394 - if (adapter) 395 - i2c_put_adapter(adapter); 396 - } 387 + adapter = client->adapter; 388 + i2c_unregister_device(client); 389 + if (adapter) 390 + i2c_put_adapter(adapter); 397 391 } 398 392 399 393 #ifdef CONFIG_OF 400 - /* Register I2C client subdev associated with @node. */ 401 - static int fimc_md_of_add_sensor(struct fimc_md *fmd, 402 - struct device_node *node, int index) 403 - { 404 - struct fimc_sensor_info *si; 405 - struct i2c_client *client; 406 - struct v4l2_subdev *sd; 407 - int ret; 408 - 409 - if (WARN_ON(index >= ARRAY_SIZE(fmd->sensor))) 410 - return -EINVAL; 411 - si = &fmd->sensor[index]; 412 - 413 - client = of_find_i2c_device_by_node(node); 414 - if (!client) 415 - return -EPROBE_DEFER; 416 - 417 - device_lock(&client->dev); 418 - 419 - if (!client->dev.driver || 420 - !try_module_get(client->dev.driver->owner)) { 421 - ret = -EPROBE_DEFER; 422 - v4l2_info(&fmd->v4l2_dev, "No driver found for %s\n", 423 - node->full_name); 424 - goto dev_put; 425 - } 426 - 427 - /* Enable sensor's master clock */ 428 - ret = __fimc_md_set_camclk(fmd, &si->pdata, true); 429 - if (ret < 0) 430 - goto mod_put; 431 - sd = i2c_get_clientdata(client); 432 - 433 - ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); 434 - __fimc_md_set_camclk(fmd, &si->pdata, false); 435 - if (ret < 0) 436 - goto mod_put; 437 - 438 - v4l2_set_subdev_hostdata(sd, &si->pdata); 439 - if (si->pdata.fimc_bus_type == FIMC_BUS_TYPE_ISP_WRITEBACK) 440 - sd->grp_id = GRP_ID_FIMC_IS_SENSOR; 441 - else 442 - sd->grp_id = GRP_ID_SENSOR; 443 - 444 - si->subdev = sd; 445 - v4l2_info(&fmd->v4l2_dev, "Registered sensor subdevice: %s (%d)\n", 446 - sd->name, fmd->num_sensors); 447 - fmd->num_sensors++; 448 - 449 - mod_put: 450 - module_put(client->dev.driver->owner); 451 - dev_put: 452 - device_unlock(&client->dev); 453 - put_device(&client->dev); 454 - return ret; 455 - } 456 - 457 394 /* Parse port node and register as a sub-device any sensor specified there. */ 458 395 static int fimc_md_parse_port_node(struct fimc_md *fmd, 459 396 struct device_node *port, ··· 403 458 struct device_node *rem, *ep, *np; 404 459 struct fimc_source_info *pd; 405 460 struct v4l2_of_endpoint endpoint; 406 - int ret; 407 461 u32 val; 408 462 409 463 pd = &fmd->sensor[index].pdata; ··· 430 486 431 487 if (!of_property_read_u32(rem, "clock-frequency", &val)) 432 488 pd->clk_frequency = val; 489 + else 490 + pd->clk_frequency = DEFAULT_SENSOR_CLK_FREQ; 433 491 434 492 if (pd->clk_frequency == 0) { 435 493 v4l2_err(&fmd->v4l2_dev, "Wrong clock frequency at node %s\n", ··· 471 525 else 472 526 pd->fimc_bus_type = pd->sensor_bus_type; 473 527 474 - ret = fimc_md_of_add_sensor(fmd, rem, index); 475 - of_node_put(rem); 528 + if (WARN_ON(index >= ARRAY_SIZE(fmd->sensor))) 529 + return -EINVAL; 476 530 477 - return ret; 531 + fmd->sensor[index].asd.match_type = V4L2_ASYNC_MATCH_OF; 532 + fmd->sensor[index].asd.match.of.node = rem; 533 + fmd->async_subdevs[index] = &fmd->sensor[index].asd; 534 + 535 + fmd->num_sensors++; 536 + 537 + of_node_put(rem); 538 + return 0; 478 539 } 479 540 480 541 /* Register all SoC external sub-devices */ ··· 685 732 static int register_fimc_is_entity(struct fimc_md *fmd, struct fimc_is *is) 686 733 { 687 734 struct v4l2_subdev *sd = &is->isp.subdev; 735 + struct exynos_media_pipeline *ep; 688 736 int ret; 737 + 738 + /* Allocate pipeline object for the ISP capture video node. */ 739 + ep = fimc_md_pipeline_create(fmd); 740 + if (!ep) 741 + return -ENOMEM; 742 + 743 + v4l2_set_subdev_hostdata(sd, ep); 689 744 690 745 ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); 691 746 if (ret) { ··· 845 884 v4l2_device_unregister_subdev(fmd->csis[i].sd); 846 885 fmd->csis[i].sd = NULL; 847 886 } 848 - for (i = 0; i < fmd->num_sensors; i++) { 849 - if (fmd->sensor[i].subdev == NULL) 850 - continue; 851 - fimc_md_unregister_sensor(fmd->sensor[i].subdev); 852 - fmd->sensor[i].subdev = NULL; 887 + if (fmd->pdev->dev.of_node == NULL) { 888 + for (i = 0; i < fmd->num_sensors; i++) { 889 + if (fmd->sensor[i].subdev == NULL) 890 + continue; 891 + fimc_md_unregister_sensor(fmd->sensor[i].subdev); 892 + fmd->sensor[i].subdev = NULL; 893 + } 853 894 } 854 895 855 896 if (fmd->fimc_is) ··· 968 1005 /* Create FIMC-IS links */ 969 1006 static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd) 970 1007 { 1008 + struct fimc_isp *isp = &fmd->fimc_is->isp; 971 1009 struct media_entity *source, *sink; 972 1010 int i, ret; 973 1011 974 - source = &fmd->fimc_is->isp.subdev.entity; 1012 + source = &isp->subdev.entity; 975 1013 976 1014 for (i = 0; i < FIMC_MAX_DEVS; i++) { 977 1015 if (fmd->fimc[i] == NULL) 978 1016 continue; 979 1017 980 - /* Link from IS-ISP subdev to FIMC */ 1018 + /* Link from FIMC-IS-ISP subdev to FIMC */ 981 1019 sink = &fmd->fimc[i]->vid_cap.subdev.entity; 982 1020 ret = media_entity_create_link(source, FIMC_ISP_SD_PAD_SRC_FIFO, 983 1021 sink, FIMC_SD_PAD_SINK_FIFO, 0); ··· 986 1022 return ret; 987 1023 } 988 1024 989 - return ret; 1025 + /* Link from FIMC-IS-ISP subdev to fimc-is-isp.capture video node */ 1026 + sink = &isp->video_capture.ve.vdev.entity; 1027 + 1028 + /* Skip this link if the fimc-is-isp video node driver isn't built-in */ 1029 + if (sink->num_pads == 0) 1030 + return 0; 1031 + 1032 + return media_entity_create_link(source, FIMC_ISP_SD_PAD_SRC_DMA, 1033 + sink, 0, 0); 990 1034 } 991 1035 992 1036 /** ··· 1195 1223 struct fimc_camclk_info *camclk; 1196 1224 int ret = 0; 1197 1225 1226 + /* 1227 + * When device tree is used the sensor drivers are supposed to 1228 + * control the clock themselves. This whole function will be 1229 + * removed once S5PV210 platform is converted to the device tree. 1230 + */ 1231 + if (fmd->pdev->dev.of_node) 1232 + return 0; 1233 + 1198 1234 if (WARN_ON(si->clk_id >= FIMC_MAX_CAMCLKS) || !fmd || !fmd->pmf) 1199 1235 return -EINVAL; 1200 1236 ··· 1256 1276 { 1257 1277 struct fimc_source_info *si = v4l2_get_subdev_hostdata(sd); 1258 1278 struct fimc_md *fmd = entity_to_fimc_mdev(&sd->entity); 1279 + 1280 + /* 1281 + * If there is a clock provider registered the sensors will 1282 + * handle their clock themselves, no need to control it on 1283 + * the host interface side. 1284 + */ 1285 + if (fmd->clk_provider.num_clocks > 0) 1286 + return 0; 1259 1287 1260 1288 return __fimc_md_set_camclk(fmd, si, on); 1261 1289 } ··· 1426 1438 return 0; 1427 1439 } 1428 1440 1441 + #ifdef CONFIG_OF 1442 + static int cam_clk_prepare(struct clk_hw *hw) 1443 + { 1444 + struct cam_clk *camclk = to_cam_clk(hw); 1445 + int ret; 1446 + 1447 + if (camclk->fmd->pmf == NULL) 1448 + return -ENODEV; 1449 + 1450 + ret = pm_runtime_get_sync(camclk->fmd->pmf); 1451 + return ret < 0 ? ret : 0; 1452 + } 1453 + 1454 + static void cam_clk_unprepare(struct clk_hw *hw) 1455 + { 1456 + struct cam_clk *camclk = to_cam_clk(hw); 1457 + 1458 + if (camclk->fmd->pmf == NULL) 1459 + return; 1460 + 1461 + pm_runtime_put_sync(camclk->fmd->pmf); 1462 + } 1463 + 1464 + static const struct clk_ops cam_clk_ops = { 1465 + .prepare = cam_clk_prepare, 1466 + .unprepare = cam_clk_unprepare, 1467 + }; 1468 + 1469 + static void fimc_md_unregister_clk_provider(struct fimc_md *fmd) 1470 + { 1471 + struct cam_clk_provider *cp = &fmd->clk_provider; 1472 + unsigned int i; 1473 + 1474 + if (cp->of_node) 1475 + of_clk_del_provider(cp->of_node); 1476 + 1477 + for (i = 0; i < cp->num_clocks; i++) 1478 + clk_unregister(cp->clks[i]); 1479 + } 1480 + 1481 + static int fimc_md_register_clk_provider(struct fimc_md *fmd) 1482 + { 1483 + struct cam_clk_provider *cp = &fmd->clk_provider; 1484 + struct device *dev = &fmd->pdev->dev; 1485 + int i, ret; 1486 + 1487 + for (i = 0; i < FIMC_MAX_CAMCLKS; i++) { 1488 + struct cam_clk *camclk = &cp->camclk[i]; 1489 + struct clk_init_data init; 1490 + const char *p_name; 1491 + 1492 + ret = of_property_read_string_index(dev->of_node, 1493 + "clock-output-names", i, &init.name); 1494 + if (ret < 0) 1495 + break; 1496 + 1497 + p_name = __clk_get_name(fmd->camclk[i].clock); 1498 + 1499 + /* It's safe since clk_register() will duplicate the string. */ 1500 + init.parent_names = &p_name; 1501 + init.num_parents = 1; 1502 + init.ops = &cam_clk_ops; 1503 + init.flags = CLK_SET_RATE_PARENT; 1504 + camclk->hw.init = &init; 1505 + camclk->fmd = fmd; 1506 + 1507 + cp->clks[i] = clk_register(NULL, &camclk->hw); 1508 + if (IS_ERR(cp->clks[i])) { 1509 + dev_err(dev, "failed to register clock: %s (%ld)\n", 1510 + init.name, PTR_ERR(cp->clks[i])); 1511 + ret = PTR_ERR(cp->clks[i]); 1512 + goto err; 1513 + } 1514 + cp->num_clocks++; 1515 + } 1516 + 1517 + if (cp->num_clocks == 0) { 1518 + dev_warn(dev, "clk provider not registered\n"); 1519 + return 0; 1520 + } 1521 + 1522 + cp->clk_data.clks = cp->clks; 1523 + cp->clk_data.clk_num = cp->num_clocks; 1524 + cp->of_node = dev->of_node; 1525 + ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, 1526 + &cp->clk_data); 1527 + if (ret == 0) 1528 + return 0; 1529 + err: 1530 + fimc_md_unregister_clk_provider(fmd); 1531 + return ret; 1532 + } 1533 + #else 1534 + #define fimc_md_register_clk_provider(fmd) (0) 1535 + #define fimc_md_unregister_clk_provider(fmd) (0) 1536 + #endif 1537 + 1538 + static int subdev_notifier_bound(struct v4l2_async_notifier *notifier, 1539 + struct v4l2_subdev *subdev, 1540 + struct v4l2_async_subdev *asd) 1541 + { 1542 + struct fimc_md *fmd = notifier_to_fimc_md(notifier); 1543 + struct fimc_sensor_info *si = NULL; 1544 + int i; 1545 + 1546 + /* Find platform data for this sensor subdev */ 1547 + for (i = 0; i < ARRAY_SIZE(fmd->sensor); i++) 1548 + if (fmd->sensor[i].asd.match.of.node == subdev->dev->of_node) 1549 + si = &fmd->sensor[i]; 1550 + 1551 + if (si == NULL) 1552 + return -EINVAL; 1553 + 1554 + v4l2_set_subdev_hostdata(subdev, &si->pdata); 1555 + 1556 + if (si->pdata.fimc_bus_type == FIMC_BUS_TYPE_ISP_WRITEBACK) 1557 + subdev->grp_id = GRP_ID_FIMC_IS_SENSOR; 1558 + else 1559 + subdev->grp_id = GRP_ID_SENSOR; 1560 + 1561 + si->subdev = subdev; 1562 + 1563 + v4l2_info(&fmd->v4l2_dev, "Registered sensor subdevice: %s (%d)\n", 1564 + subdev->name, fmd->num_sensors); 1565 + 1566 + fmd->num_sensors++; 1567 + 1568 + return 0; 1569 + } 1570 + 1571 + static int subdev_notifier_complete(struct v4l2_async_notifier *notifier) 1572 + { 1573 + struct fimc_md *fmd = notifier_to_fimc_md(notifier); 1574 + int ret; 1575 + 1576 + mutex_lock(&fmd->media_dev.graph_mutex); 1577 + 1578 + ret = fimc_md_create_links(fmd); 1579 + if (ret < 0) 1580 + goto unlock; 1581 + 1582 + ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev); 1583 + unlock: 1584 + mutex_unlock(&fmd->media_dev.graph_mutex); 1585 + return ret; 1586 + } 1587 + 1429 1588 static int fimc_md_probe(struct platform_device *pdev) 1430 1589 { 1431 1590 struct device *dev = &pdev->dev; ··· 1605 1470 v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret); 1606 1471 return ret; 1607 1472 } 1473 + 1608 1474 ret = media_device_register(&fmd->media_dev); 1609 1475 if (ret < 0) { 1610 1476 v4l2_err(v4l2_dev, "Failed to register media device: %d\n", ret); 1611 - goto err_md; 1477 + goto err_v4l2_dev; 1612 1478 } 1479 + 1613 1480 ret = fimc_md_get_clocks(fmd); 1614 1481 if (ret) 1615 - goto err_clk; 1482 + goto err_md; 1616 1483 1617 1484 fmd->user_subdev_api = (dev->of_node != NULL); 1618 - 1619 - /* Protect the media graph while we're registering entities */ 1620 - mutex_lock(&fmd->media_dev.graph_mutex); 1621 1485 1622 1486 ret = fimc_md_get_pinctrl(fmd); 1623 1487 if (ret < 0) { 1624 1488 if (ret != EPROBE_DEFER) 1625 1489 dev_err(dev, "Failed to get pinctrl: %d\n", ret); 1626 - goto err_unlock; 1490 + goto err_clk; 1627 1491 } 1492 + 1493 + platform_set_drvdata(pdev, fmd); 1494 + 1495 + /* Protect the media graph while we're registering entities */ 1496 + mutex_lock(&fmd->media_dev.graph_mutex); 1628 1497 1629 1498 if (dev->of_node) 1630 1499 ret = fimc_md_register_of_platform_entities(fmd, dev->of_node); 1631 1500 else 1632 1501 ret = bus_for_each_dev(&platform_bus_type, NULL, fmd, 1633 1502 fimc_md_pdev_match); 1634 - if (ret) 1635 - goto err_unlock; 1503 + if (ret) { 1504 + mutex_unlock(&fmd->media_dev.graph_mutex); 1505 + goto err_clk; 1506 + } 1636 1507 1637 1508 if (dev->platform_data || dev->of_node) { 1638 1509 ret = fimc_md_register_sensor_entities(fmd); 1639 - if (ret) 1640 - goto err_unlock; 1510 + if (ret) { 1511 + mutex_unlock(&fmd->media_dev.graph_mutex); 1512 + goto err_m_ent; 1513 + } 1641 1514 } 1642 1515 1643 - ret = fimc_md_create_links(fmd); 1644 - if (ret) 1645 - goto err_unlock; 1646 - ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev); 1647 - if (ret) 1648 - goto err_unlock; 1516 + mutex_unlock(&fmd->media_dev.graph_mutex); 1649 1517 1650 1518 ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode); 1651 1519 if (ret) 1652 - goto err_unlock; 1520 + goto err_m_ent; 1521 + /* 1522 + * FIMC platform devices need to be registered before the sclk_cam 1523 + * clocks provider, as one of these devices needs to be activated 1524 + * to enable the clock. 1525 + */ 1526 + ret = fimc_md_register_clk_provider(fmd); 1527 + if (ret < 0) { 1528 + v4l2_err(v4l2_dev, "clock provider registration failed\n"); 1529 + goto err_attr; 1530 + } 1653 1531 1654 - platform_set_drvdata(pdev, fmd); 1655 - mutex_unlock(&fmd->media_dev.graph_mutex); 1532 + if (fmd->num_sensors > 0) { 1533 + fmd->subdev_notifier.subdevs = fmd->async_subdevs; 1534 + fmd->subdev_notifier.num_subdevs = fmd->num_sensors; 1535 + fmd->subdev_notifier.bound = subdev_notifier_bound; 1536 + fmd->subdev_notifier.complete = subdev_notifier_complete; 1537 + fmd->num_sensors = 0; 1538 + 1539 + ret = v4l2_async_notifier_register(&fmd->v4l2_dev, 1540 + &fmd->subdev_notifier); 1541 + if (ret) 1542 + goto err_clk_p; 1543 + } 1544 + 1656 1545 return 0; 1657 1546 1658 - err_unlock: 1659 - mutex_unlock(&fmd->media_dev.graph_mutex); 1547 + err_clk_p: 1548 + fimc_md_unregister_clk_provider(fmd); 1549 + err_attr: 1550 + device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode); 1660 1551 err_clk: 1661 1552 fimc_md_put_clocks(fmd); 1553 + err_m_ent: 1662 1554 fimc_md_unregister_entities(fmd); 1663 - media_device_unregister(&fmd->media_dev); 1664 1555 err_md: 1556 + media_device_unregister(&fmd->media_dev); 1557 + err_v4l2_dev: 1665 1558 v4l2_device_unregister(&fmd->v4l2_dev); 1666 1559 return ret; 1667 1560 } ··· 1701 1538 if (!fmd) 1702 1539 return 0; 1703 1540 1541 + fimc_md_unregister_clk_provider(fmd); 1542 + v4l2_async_notifier_unregister(&fmd->subdev_notifier); 1543 + 1704 1544 v4l2_device_unregister(&fmd->v4l2_dev); 1705 1545 device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode); 1706 1546 fimc_md_unregister_entities(fmd); 1707 1547 fimc_md_pipelines_free(fmd); 1708 1548 media_device_unregister(&fmd->media_dev); 1709 1549 fimc_md_put_clocks(fmd); 1550 + 1710 1551 return 0; 1711 1552 } 1712 1553
+30 -2
drivers/media/platform/exynos4-is/media-dev.h
··· 10 10 #define FIMC_MDEVICE_H_ 11 11 12 12 #include <linux/clk.h> 13 + #include <linux/clk-provider.h> 13 14 #include <linux/platform_device.h> 14 15 #include <linux/mutex.h> 15 16 #include <linux/of.h> ··· 32 31 33 32 #define PINCTRL_STATE_IDLE "idle" 34 33 35 - #define FIMC_MAX_SENSORS 8 34 + #define FIMC_MAX_SENSORS 4 36 35 #define FIMC_MAX_CAMCLKS 2 36 + #define DEFAULT_SENSOR_CLK_FREQ 24000000U 37 37 38 38 /* LCD/ISP Writeback clocks (PIXELASYNCMx) */ 39 39 enum { ··· 80 78 /** 81 79 * struct fimc_sensor_info - image data source subdev information 82 80 * @pdata: sensor's atrributes passed as media device's platform data 81 + * @asd: asynchronous subdev registration data structure 83 82 * @subdev: image sensor v4l2 subdev 84 83 * @host: fimc device the sensor is currently linked to 85 84 * ··· 88 85 */ 89 86 struct fimc_sensor_info { 90 87 struct fimc_source_info pdata; 88 + struct v4l2_async_subdev asd; 91 89 struct v4l2_subdev *subdev; 92 90 struct fimc_dev *host; 93 91 }; 92 + 93 + struct cam_clk { 94 + struct clk_hw hw; 95 + struct fimc_md *fmd; 96 + }; 97 + #define to_cam_clk(_hw) container_of(_hw, struct cam_clk, hw) 94 98 95 99 /** 96 100 * struct fimc_md - fimc media device information ··· 115 105 * @pinctrl: camera port pinctrl handle 116 106 * @state_default: pinctrl default state handle 117 107 * @state_idle: pinctrl idle state handle 108 + * @cam_clk_provider: CAMCLK clock provider structure 118 109 * @user_subdev_api: true if subdevs are not configured by the host driver 119 110 * @slock: spinlock protecting @sensor array 120 111 */ ··· 133 122 struct media_device media_dev; 134 123 struct v4l2_device v4l2_dev; 135 124 struct platform_device *pdev; 125 + 136 126 struct fimc_pinctrl { 137 127 struct pinctrl *pinctrl; 138 128 struct pinctrl_state *state_default; 139 129 struct pinctrl_state *state_idle; 140 130 } pinctl; 141 - bool user_subdev_api; 142 131 132 + struct cam_clk_provider { 133 + struct clk *clks[FIMC_MAX_CAMCLKS]; 134 + struct clk_onecell_data clk_data; 135 + struct device_node *of_node; 136 + struct cam_clk camclk[FIMC_MAX_CAMCLKS]; 137 + int num_clocks; 138 + } clk_provider; 139 + 140 + struct v4l2_async_notifier subdev_notifier; 141 + struct v4l2_async_subdev *async_subdevs[FIMC_MAX_SENSORS]; 142 + 143 + bool user_subdev_api; 143 144 spinlock_t slock; 144 145 struct list_head pipelines; 145 146 }; ··· 166 143 { 167 144 return me->parent == NULL ? NULL : 168 145 container_of(me->parent, struct fimc_md, media_dev); 146 + } 147 + 148 + static inline struct fimc_md *notifier_to_fimc_md(struct v4l2_async_notifier *n) 149 + { 150 + return container_of(n, struct fimc_md, subdev_notifier); 169 151 } 170 152 171 153 static inline void fimc_md_graph_lock(struct exynos_video_entity *ve)
+12 -12
drivers/media/platform/s5p-jpeg/jpeg-regs.h
··· 210 210 211 211 /* JPEG CNTL Register bit */ 212 212 #define EXYNOS4_ENC_DEC_MODE_MASK (0xfffffffc << 0) 213 - #define EXYNOS4_DEC_MODE (1 << 0) 214 - #define EXYNOS4_ENC_MODE (1 << 1) 213 + #define EXYNOS4_DEC_MODE (1 << 0) 214 + #define EXYNOS4_ENC_MODE (1 << 1) 215 215 #define EXYNOS4_AUTO_RST_MARKER (1 << 2) 216 216 #define EXYNOS4_RST_INTERVAL_SHIFT 3 217 217 #define EXYNOS4_RST_INTERVAL(x) (((x) & 0xffff) \ 218 218 << EXYNOS4_RST_INTERVAL_SHIFT) 219 219 #define EXYNOS4_HUF_TBL_EN (1 << 19) 220 220 #define EXYNOS4_HOR_SCALING_SHIFT 20 221 - #define EXYNOS4_HOR_SCALING_MASK (3 << EXYNOS4_HOR_SCALING_SHIFT) 221 + #define EXYNOS4_HOR_SCALING_MASK (3 << EXYNOS4_HOR_SCALING_SHIFT) 222 222 #define EXYNOS4_HOR_SCALING(x) (((x) & 0x3) \ 223 223 << EXYNOS4_HOR_SCALING_SHIFT) 224 224 #define EXYNOS4_VER_SCALING_SHIFT 22 225 - #define EXYNOS4_VER_SCALING_MASK (3 << EXYNOS4_VER_SCALING_SHIFT) 225 + #define EXYNOS4_VER_SCALING_MASK (3 << EXYNOS4_VER_SCALING_SHIFT) 226 226 #define EXYNOS4_VER_SCALING(x) (((x) & 0x3) \ 227 227 << EXYNOS4_VER_SCALING_SHIFT) 228 228 #define EXYNOS4_PADDING (1 << 27) ··· 238 238 #define EXYNOS4_FRAME_ERR_EN (1 << 4) 239 239 #define EXYNOS4_INT_EN_ALL (0x1f << 0) 240 240 241 - #define EXYNOS4_MOD_REG_PROC_ENC (0 << 3) 242 - #define EXYNOS4_MOD_REG_PROC_DEC (1 << 3) 241 + #define EXYNOS4_MOD_REG_PROC_ENC (0 << 3) 242 + #define EXYNOS4_MOD_REG_PROC_DEC (1 << 3) 243 243 244 244 #define EXYNOS4_MOD_REG_SUBSAMPLE_444 (0 << 0) 245 245 #define EXYNOS4_MOD_REG_SUBSAMPLE_422 (1 << 0) ··· 270 270 #define EXYNOS4_DEC_YUV_420_IMG (4 << 0) 271 271 272 272 #define EXYNOS4_GRAY_IMG_IP_SHIFT 3 273 - #define EXYNOS4_GRAY_IMG_IP_MASK (7 << EXYNOS4_GRAY_IMG_IP_SHIFT) 273 + #define EXYNOS4_GRAY_IMG_IP_MASK (7 << EXYNOS4_GRAY_IMG_IP_SHIFT) 274 274 #define EXYNOS4_GRAY_IMG_IP (4 << EXYNOS4_GRAY_IMG_IP_SHIFT) 275 275 276 276 #define EXYNOS4_RGB_IP_SHIFT 6 ··· 278 278 #define EXYNOS4_RGB_IP_RGB_16BIT_IMG (4 << EXYNOS4_RGB_IP_SHIFT) 279 279 #define EXYNOS4_RGB_IP_RGB_32BIT_IMG (5 << EXYNOS4_RGB_IP_SHIFT) 280 280 281 - #define EXYNOS4_YUV_444_IP_SHIFT 9 281 + #define EXYNOS4_YUV_444_IP_SHIFT 9 282 282 #define EXYNOS4_YUV_444_IP_MASK (7 << EXYNOS4_YUV_444_IP_SHIFT) 283 283 #define EXYNOS4_YUV_444_IP_YUV_444_2P_IMG (4 << EXYNOS4_YUV_444_IP_SHIFT) 284 284 #define EXYNOS4_YUV_444_IP_YUV_444_3P_IMG (5 << EXYNOS4_YUV_444_IP_SHIFT) 285 285 286 - #define EXYNOS4_YUV_422_IP_SHIFT 12 286 + #define EXYNOS4_YUV_422_IP_SHIFT 12 287 287 #define EXYNOS4_YUV_422_IP_MASK (7 << EXYNOS4_YUV_422_IP_SHIFT) 288 288 #define EXYNOS4_YUV_422_IP_YUV_422_1P_IMG (4 << EXYNOS4_YUV_422_IP_SHIFT) 289 289 #define EXYNOS4_YUV_422_IP_YUV_422_2P_IMG (5 << EXYNOS4_YUV_422_IP_SHIFT) 290 290 #define EXYNOS4_YUV_422_IP_YUV_422_3P_IMG (6 << EXYNOS4_YUV_422_IP_SHIFT) 291 291 292 - #define EXYNOS4_YUV_420_IP_SHIFT 15 292 + #define EXYNOS4_YUV_420_IP_SHIFT 15 293 293 #define EXYNOS4_YUV_420_IP_MASK (7 << EXYNOS4_YUV_420_IP_SHIFT) 294 294 #define EXYNOS4_YUV_420_IP_YUV_420_2P_IMG (4 << EXYNOS4_YUV_420_IP_SHIFT) 295 295 #define EXYNOS4_YUV_420_IP_YUV_420_3P_IMG (5 << EXYNOS4_YUV_420_IP_SHIFT) ··· 303 303 304 304 #define EXYNOS4_JPEG_DECODED_IMG_FMT_MASK 0x03 305 305 306 - #define EXYNOS4_SWAP_CHROMA_CRCB (1 << 26) 307 - #define EXYNOS4_SWAP_CHROMA_CBCR (0 << 26) 306 + #define EXYNOS4_SWAP_CHROMA_CRCB (1 << 26) 307 + #define EXYNOS4_SWAP_CHROMA_CBCR (0 << 26) 308 308 309 309 /* JPEG HUFF count Register bit */ 310 310 #define EXYNOS4_HUFF_COUNT_MASK 0xffff