diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2016-07-31 07:12:22 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@s-opensource.com> | 2016-08-24 05:35:19 -0400 |
commit | f304562ed3c97e237a77b3da57b0e43f264bd82a (patch) | |
tree | 5464da90804b1a655ffa054412d638dc120c369f | |
parent | 563bf7a72eac823b06953cd3dce9b71b499fa438 (diff) |
[media] soc-camera/sh_mobile_csi2: remove unused driver
The sh_mobile_csi2 isn't used anymore (was it ever?), so remove it.
Especially since the soc-camera framework is being deprecated.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
-rw-r--r-- | drivers/media/platform/soc_camera/Kconfig | 7 | ||||
-rw-r--r-- | drivers/media/platform/soc_camera/Makefile | 1 | ||||
-rw-r--r-- | drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c | 229 | ||||
-rw-r--r-- | drivers/media/platform/soc_camera/sh_mobile_csi2.c | 400 | ||||
-rw-r--r-- | include/media/drv-intf/sh_mobile_ceu.h | 1 | ||||
-rw-r--r-- | include/media/drv-intf/sh_mobile_csi2.h | 48 |
6 files changed, 10 insertions, 676 deletions
diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig index 39f66414f621..99cf471a5fc0 100644 --- a/drivers/media/platform/soc_camera/Kconfig +++ b/drivers/media/platform/soc_camera/Kconfig | |||
@@ -35,13 +35,6 @@ config VIDEO_RCAR_VIN_OLD | |||
35 | ---help--- | 35 | ---help--- |
36 | This is a v4l2 driver for the R-Car VIN Interface | 36 | This is a v4l2 driver for the R-Car VIN Interface |
37 | 37 | ||
38 | config VIDEO_SH_MOBILE_CSI2 | ||
39 | tristate "SuperH Mobile MIPI CSI-2 Interface driver" | ||
40 | depends on VIDEO_DEV && SOC_CAMERA && HAVE_CLK | ||
41 | depends on ARCH_SHMOBILE || SUPERH || COMPILE_TEST | ||
42 | ---help--- | ||
43 | This is a v4l2 driver for the SuperH MIPI CSI-2 Interface | ||
44 | |||
45 | config VIDEO_SH_MOBILE_CEU | 38 | config VIDEO_SH_MOBILE_CEU |
46 | tristate "SuperH Mobile CEU Interface driver" | 39 | tristate "SuperH Mobile CEU Interface driver" |
47 | depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA && HAVE_CLK | 40 | depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA && HAVE_CLK |
diff --git a/drivers/media/platform/soc_camera/Makefile b/drivers/media/platform/soc_camera/Makefile index 7703cb7ce456..ee8f9a4ae2a4 100644 --- a/drivers/media/platform/soc_camera/Makefile +++ b/drivers/media/platform/soc_camera/Makefile | |||
@@ -9,5 +9,4 @@ obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o | |||
9 | obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o | 9 | obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o |
10 | obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o | 10 | obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o |
11 | obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o | 11 | obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o |
12 | obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2) += sh_mobile_csi2.o | ||
13 | obj-$(CONFIG_VIDEO_RCAR_VIN_OLD) += rcar_vin.o | 12 | obj-$(CONFIG_VIDEO_RCAR_VIN_OLD) += rcar_vin.o |
diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 02b519dde42a..05eafe3a421e 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #include <media/v4l2-dev.h> | 41 | #include <media/v4l2-dev.h> |
42 | #include <media/soc_camera.h> | 42 | #include <media/soc_camera.h> |
43 | #include <media/drv-intf/sh_mobile_ceu.h> | 43 | #include <media/drv-intf/sh_mobile_ceu.h> |
44 | #include <media/drv-intf/sh_mobile_csi2.h> | ||
45 | #include <media/videobuf2-dma-contig.h> | 44 | #include <media/videobuf2-dma-contig.h> |
46 | #include <media/v4l2-mediabus.h> | 45 | #include <media/v4l2-mediabus.h> |
47 | #include <media/drv-intf/soc_mediabus.h> | 46 | #include <media/drv-intf/soc_mediabus.h> |
@@ -99,11 +98,6 @@ struct sh_mobile_ceu_buffer { | |||
99 | 98 | ||
100 | struct sh_mobile_ceu_dev { | 99 | struct sh_mobile_ceu_dev { |
101 | struct soc_camera_host ici; | 100 | struct soc_camera_host ici; |
102 | /* Asynchronous CSI2 linking */ | ||
103 | struct v4l2_async_subdev *csi2_asd; | ||
104 | struct v4l2_subdev *csi2_sd; | ||
105 | /* Synchronous probing compatibility */ | ||
106 | struct platform_device *csi2_pdev; | ||
107 | 101 | ||
108 | unsigned int irq; | 102 | unsigned int irq; |
109 | void __iomem *base; | 103 | void __iomem *base; |
@@ -517,74 +511,20 @@ out: | |||
517 | return IRQ_HANDLED; | 511 | return IRQ_HANDLED; |
518 | } | 512 | } |
519 | 513 | ||
520 | static struct v4l2_subdev *find_csi2(struct sh_mobile_ceu_dev *pcdev) | ||
521 | { | ||
522 | struct v4l2_subdev *sd; | ||
523 | |||
524 | if (pcdev->csi2_sd) | ||
525 | return pcdev->csi2_sd; | ||
526 | |||
527 | if (pcdev->csi2_asd) { | ||
528 | char name[] = "sh-mobile-csi2"; | ||
529 | v4l2_device_for_each_subdev(sd, &pcdev->ici.v4l2_dev) | ||
530 | if (!strncmp(name, sd->name, sizeof(name) - 1)) { | ||
531 | pcdev->csi2_sd = sd; | ||
532 | return sd; | ||
533 | } | ||
534 | } | ||
535 | |||
536 | return NULL; | ||
537 | } | ||
538 | |||
539 | static struct v4l2_subdev *csi2_subdev(struct sh_mobile_ceu_dev *pcdev, | ||
540 | struct soc_camera_device *icd) | ||
541 | { | ||
542 | struct v4l2_subdev *sd = pcdev->csi2_sd; | ||
543 | |||
544 | return sd && sd->grp_id == soc_camera_grp_id(icd) ? sd : NULL; | ||
545 | } | ||
546 | |||
547 | static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) | 514 | static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) |
548 | { | 515 | { |
549 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | ||
550 | struct sh_mobile_ceu_dev *pcdev = ici->priv; | ||
551 | struct v4l2_subdev *csi2_sd = find_csi2(pcdev); | ||
552 | int ret; | ||
553 | |||
554 | if (csi2_sd) { | ||
555 | csi2_sd->grp_id = soc_camera_grp_id(icd); | ||
556 | v4l2_set_subdev_hostdata(csi2_sd, icd); | ||
557 | } | ||
558 | |||
559 | ret = v4l2_subdev_call(csi2_sd, core, s_power, 1); | ||
560 | if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) | ||
561 | return ret; | ||
562 | |||
563 | /* | ||
564 | * -ENODEV is special: either csi2_sd == NULL or the CSI-2 driver | ||
565 | * has not found this soc-camera device among its clients | ||
566 | */ | ||
567 | if (csi2_sd && ret == -ENODEV) | ||
568 | csi2_sd->grp_id = 0; | ||
569 | |||
570 | dev_info(icd->parent, | 516 | dev_info(icd->parent, |
571 | "SuperH Mobile CEU%s driver attached to camera %d\n", | 517 | "SuperH Mobile CEU driver attached to camera %d\n", |
572 | csi2_sd && csi2_sd->grp_id ? "/CSI-2" : "", icd->devnum); | 518 | icd->devnum); |
573 | 519 | ||
574 | return 0; | 520 | return 0; |
575 | } | 521 | } |
576 | 522 | ||
577 | static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) | 523 | static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) |
578 | { | 524 | { |
579 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | ||
580 | struct sh_mobile_ceu_dev *pcdev = ici->priv; | ||
581 | struct v4l2_subdev *csi2_sd = find_csi2(pcdev); | ||
582 | |||
583 | dev_info(icd->parent, | 525 | dev_info(icd->parent, |
584 | "SuperH Mobile CEU driver detached from camera %d\n", | 526 | "SuperH Mobile CEU driver detached from camera %d\n", |
585 | icd->devnum); | 527 | icd->devnum); |
586 | |||
587 | v4l2_subdev_call(csi2_sd, core, s_power, 0); | ||
588 | } | 528 | } |
589 | 529 | ||
590 | /* Called with .host_lock held */ | 530 | /* Called with .host_lock held */ |
@@ -704,12 +644,6 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd) | |||
704 | cdwdr_width *= 2; | 644 | cdwdr_width *= 2; |
705 | } | 645 | } |
706 | 646 | ||
707 | /* CSI2 special configuration */ | ||
708 | if (csi2_subdev(pcdev, icd)) { | ||
709 | in_width = ((in_width - 2) * 2); | ||
710 | left_offset *= 2; | ||
711 | } | ||
712 | |||
713 | /* Set CAMOR, CAPWR, CFSZR, take care of CDWDR */ | 647 | /* Set CAMOR, CAPWR, CFSZR, take care of CDWDR */ |
714 | camor = left_offset | (top_offset << 16); | 648 | camor = left_offset | (top_offset << 16); |
715 | 649 | ||
@@ -758,13 +692,6 @@ static void capture_restore(struct sh_mobile_ceu_dev *pcdev, u32 capsr) | |||
758 | ceu_write(pcdev, CAPSR, capsr); | 692 | ceu_write(pcdev, CAPSR, capsr); |
759 | } | 693 | } |
760 | 694 | ||
761 | /* Find the bus subdevice driver, e.g., CSI2 */ | ||
762 | static struct v4l2_subdev *find_bus_subdev(struct sh_mobile_ceu_dev *pcdev, | ||
763 | struct soc_camera_device *icd) | ||
764 | { | ||
765 | return csi2_subdev(pcdev, icd) ? : soc_camera_to_subdev(icd); | ||
766 | } | ||
767 | |||
768 | #define CEU_BUS_FLAGS (V4L2_MBUS_MASTER | \ | 695 | #define CEU_BUS_FLAGS (V4L2_MBUS_MASTER | \ |
769 | V4L2_MBUS_PCLK_SAMPLE_RISING | \ | 696 | V4L2_MBUS_PCLK_SAMPLE_RISING | \ |
770 | V4L2_MBUS_HSYNC_ACTIVE_HIGH | \ | 697 | V4L2_MBUS_HSYNC_ACTIVE_HIGH | \ |
@@ -778,7 +705,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) | |||
778 | { | 705 | { |
779 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 706 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
780 | struct sh_mobile_ceu_dev *pcdev = ici->priv; | 707 | struct sh_mobile_ceu_dev *pcdev = ici->priv; |
781 | struct v4l2_subdev *sd = find_bus_subdev(pcdev, icd); | 708 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
782 | struct sh_mobile_ceu_cam *cam = icd->host_priv; | 709 | struct sh_mobile_ceu_cam *cam = icd->host_priv; |
783 | struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; | 710 | struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; |
784 | unsigned long value, common_flags = CEU_BUS_FLAGS; | 711 | unsigned long value, common_flags = CEU_BUS_FLAGS; |
@@ -866,9 +793,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) | |||
866 | value |= common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 << 1 : 0; | 793 | value |= common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 << 1 : 0; |
867 | value |= common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 << 0 : 0; | 794 | value |= common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 << 0 : 0; |
868 | 795 | ||
869 | if (csi2_subdev(pcdev, icd)) /* CSI2 mode */ | 796 | if (pcdev->is_16bit) |
870 | value |= 3 << 12; | ||
871 | else if (pcdev->is_16bit) | ||
872 | value |= 1 << 12; | 797 | value |= 1 << 12; |
873 | else if (pcdev->flags & SH_CEU_FLAG_LOWER_8BIT) | 798 | else if (pcdev->flags & SH_CEU_FLAG_LOWER_8BIT) |
874 | value |= 2 << 12; | 799 | value |= 2 << 12; |
@@ -923,9 +848,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) | |||
923 | static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd, | 848 | static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd, |
924 | unsigned char buswidth) | 849 | unsigned char buswidth) |
925 | { | 850 | { |
926 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 851 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
927 | struct sh_mobile_ceu_dev *pcdev = ici->priv; | ||
928 | struct v4l2_subdev *sd = find_bus_subdev(pcdev, icd); | ||
929 | unsigned long common_flags = CEU_BUS_FLAGS; | 852 | unsigned long common_flags = CEU_BUS_FLAGS; |
930 | struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; | 853 | struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; |
931 | int ret; | 854 | int ret; |
@@ -1046,12 +969,9 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int | |||
1046 | return 0; | 969 | return 0; |
1047 | } | 970 | } |
1048 | 971 | ||
1049 | if (!csi2_subdev(pcdev, icd)) { | 972 | ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample); |
1050 | /* Are there any restrictions in the CSI-2 case? */ | 973 | if (ret < 0) |
1051 | ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample); | 974 | return 0; |
1052 | if (ret < 0) | ||
1053 | return 0; | ||
1054 | } | ||
1055 | 975 | ||
1056 | if (!icd->host_priv) { | 976 | if (!icd->host_priv) { |
1057 | struct v4l2_subdev_format fmt = { | 977 | struct v4l2_subdev_format fmt = { |
@@ -1721,12 +1641,11 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) | |||
1721 | struct resource *res; | 1641 | struct resource *res; |
1722 | void __iomem *base; | 1642 | void __iomem *base; |
1723 | unsigned int irq; | 1643 | unsigned int irq; |
1724 | int err, i; | 1644 | int err; |
1725 | struct bus_wait wait = { | 1645 | struct bus_wait wait = { |
1726 | .completion = COMPLETION_INITIALIZER_ONSTACK(wait.completion), | 1646 | .completion = COMPLETION_INITIALIZER_ONSTACK(wait.completion), |
1727 | .notifier.notifier_call = bus_notify, | 1647 | .notifier.notifier_call = bus_notify, |
1728 | }; | 1648 | }; |
1729 | struct sh_mobile_ceu_companion *csi2; | ||
1730 | 1649 | ||
1731 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1650 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1732 | irq = platform_get_irq(pdev, 0); | 1651 | irq = platform_get_irq(pdev, 0); |
@@ -1821,132 +1740,16 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) | |||
1821 | pcdev->ici.capabilities = SOCAM_HOST_CAP_STRIDE; | 1740 | pcdev->ici.capabilities = SOCAM_HOST_CAP_STRIDE; |
1822 | 1741 | ||
1823 | if (pcdev->pdata && pcdev->pdata->asd_sizes) { | 1742 | if (pcdev->pdata && pcdev->pdata->asd_sizes) { |
1824 | struct v4l2_async_subdev **asd; | ||
1825 | char name[] = "sh-mobile-csi2"; | ||
1826 | int j; | ||
1827 | |||
1828 | /* | ||
1829 | * CSI2 interfacing: several groups can use CSI2, pick up the | ||
1830 | * first one | ||
1831 | */ | ||
1832 | asd = pcdev->pdata->asd; | ||
1833 | for (j = 0; pcdev->pdata->asd_sizes[j]; j++) { | ||
1834 | for (i = 0; i < pcdev->pdata->asd_sizes[j]; i++, asd++) { | ||
1835 | dev_dbg(&pdev->dev, "%s(): subdev #%d, type %u\n", | ||
1836 | __func__, i, (*asd)->match_type); | ||
1837 | if ((*asd)->match_type == V4L2_ASYNC_MATCH_DEVNAME && | ||
1838 | !strncmp(name, (*asd)->match.device_name.name, | ||
1839 | sizeof(name) - 1)) { | ||
1840 | pcdev->csi2_asd = *asd; | ||
1841 | break; | ||
1842 | } | ||
1843 | } | ||
1844 | if (pcdev->csi2_asd) | ||
1845 | break; | ||
1846 | } | ||
1847 | |||
1848 | pcdev->ici.asd = pcdev->pdata->asd; | 1743 | pcdev->ici.asd = pcdev->pdata->asd; |
1849 | pcdev->ici.asd_sizes = pcdev->pdata->asd_sizes; | 1744 | pcdev->ici.asd_sizes = pcdev->pdata->asd_sizes; |
1850 | } | 1745 | } |
1851 | 1746 | ||
1852 | /* Legacy CSI2 interfacing */ | ||
1853 | csi2 = pcdev->pdata ? pcdev->pdata->csi2 : NULL; | ||
1854 | if (csi2) { | ||
1855 | /* | ||
1856 | * TODO: remove this once all users are converted to | ||
1857 | * asynchronous CSI2 probing. If it has to be kept, csi2 | ||
1858 | * platform device resources have to be added, using | ||
1859 | * platform_device_add_resources() | ||
1860 | */ | ||
1861 | struct platform_device *csi2_pdev = | ||
1862 | platform_device_alloc("sh-mobile-csi2", csi2->id); | ||
1863 | struct sh_csi2_pdata *csi2_pdata = csi2->platform_data; | ||
1864 | |||
1865 | if (!csi2_pdev) { | ||
1866 | err = -ENOMEM; | ||
1867 | goto exit_free_clk; | ||
1868 | } | ||
1869 | |||
1870 | pcdev->csi2_pdev = csi2_pdev; | ||
1871 | |||
1872 | err = platform_device_add_data(csi2_pdev, csi2_pdata, | ||
1873 | sizeof(*csi2_pdata)); | ||
1874 | if (err < 0) | ||
1875 | goto exit_pdev_put; | ||
1876 | |||
1877 | csi2_pdev->resource = csi2->resource; | ||
1878 | csi2_pdev->num_resources = csi2->num_resources; | ||
1879 | |||
1880 | err = platform_device_add(csi2_pdev); | ||
1881 | if (err < 0) | ||
1882 | goto exit_pdev_put; | ||
1883 | |||
1884 | wait.dev = &csi2_pdev->dev; | ||
1885 | |||
1886 | err = bus_register_notifier(&platform_bus_type, &wait.notifier); | ||
1887 | if (err < 0) | ||
1888 | goto exit_pdev_unregister; | ||
1889 | |||
1890 | /* | ||
1891 | * From this point the driver module will not unload, until | ||
1892 | * we complete the completion. | ||
1893 | */ | ||
1894 | |||
1895 | if (!csi2_pdev->dev.driver) { | ||
1896 | complete(&wait.completion); | ||
1897 | /* Either too late, or probing failed */ | ||
1898 | bus_unregister_notifier(&platform_bus_type, &wait.notifier); | ||
1899 | err = -ENXIO; | ||
1900 | goto exit_pdev_unregister; | ||
1901 | } | ||
1902 | |||
1903 | /* | ||
1904 | * The module is still loaded, in the worst case it is hanging | ||
1905 | * in device release on our completion. So, _now_ dereferencing | ||
1906 | * the "owner" is safe! | ||
1907 | */ | ||
1908 | |||
1909 | err = try_module_get(csi2_pdev->dev.driver->owner); | ||
1910 | |||
1911 | /* Let notifier complete, if it has been locked */ | ||
1912 | complete(&wait.completion); | ||
1913 | bus_unregister_notifier(&platform_bus_type, &wait.notifier); | ||
1914 | if (!err) { | ||
1915 | err = -ENODEV; | ||
1916 | goto exit_pdev_unregister; | ||
1917 | } | ||
1918 | |||
1919 | pcdev->csi2_sd = platform_get_drvdata(csi2_pdev); | ||
1920 | } | ||
1921 | |||
1922 | err = soc_camera_host_register(&pcdev->ici); | 1747 | err = soc_camera_host_register(&pcdev->ici); |
1923 | if (err) | 1748 | if (err) |
1924 | goto exit_csi2_unregister; | 1749 | goto exit_free_clk; |
1925 | |||
1926 | if (csi2) { | ||
1927 | err = v4l2_device_register_subdev(&pcdev->ici.v4l2_dev, | ||
1928 | pcdev->csi2_sd); | ||
1929 | dev_dbg(&pdev->dev, "%s(): ret(register_subdev) = %d\n", | ||
1930 | __func__, err); | ||
1931 | if (err < 0) | ||
1932 | goto exit_host_unregister; | ||
1933 | /* v4l2_device_register_subdev() took a reference too */ | ||
1934 | module_put(pcdev->csi2_sd->owner); | ||
1935 | } | ||
1936 | 1750 | ||
1937 | return 0; | 1751 | return 0; |
1938 | 1752 | ||
1939 | exit_host_unregister: | ||
1940 | soc_camera_host_unregister(&pcdev->ici); | ||
1941 | exit_csi2_unregister: | ||
1942 | if (csi2) { | ||
1943 | module_put(pcdev->csi2_pdev->dev.driver->owner); | ||
1944 | exit_pdev_unregister: | ||
1945 | platform_device_del(pcdev->csi2_pdev); | ||
1946 | exit_pdev_put: | ||
1947 | pcdev->csi2_pdev->resource = NULL; | ||
1948 | platform_device_put(pcdev->csi2_pdev); | ||
1949 | } | ||
1950 | exit_free_clk: | 1753 | exit_free_clk: |
1951 | pm_runtime_disable(&pdev->dev); | 1754 | pm_runtime_disable(&pdev->dev); |
1952 | exit_release_mem: | 1755 | exit_release_mem: |
@@ -1958,21 +1761,11 @@ exit_release_mem: | |||
1958 | static int sh_mobile_ceu_remove(struct platform_device *pdev) | 1761 | static int sh_mobile_ceu_remove(struct platform_device *pdev) |
1959 | { | 1762 | { |
1960 | struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev); | 1763 | struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev); |
1961 | struct sh_mobile_ceu_dev *pcdev = container_of(soc_host, | ||
1962 | struct sh_mobile_ceu_dev, ici); | ||
1963 | struct platform_device *csi2_pdev = pcdev->csi2_pdev; | ||
1964 | 1764 | ||
1965 | soc_camera_host_unregister(soc_host); | 1765 | soc_camera_host_unregister(soc_host); |
1966 | pm_runtime_disable(&pdev->dev); | 1766 | pm_runtime_disable(&pdev->dev); |
1967 | if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) | 1767 | if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) |
1968 | dma_release_declared_memory(&pdev->dev); | 1768 | dma_release_declared_memory(&pdev->dev); |
1969 | if (csi2_pdev && csi2_pdev->dev.driver) { | ||
1970 | struct module *csi2_drv = csi2_pdev->dev.driver->owner; | ||
1971 | platform_device_del(csi2_pdev); | ||
1972 | csi2_pdev->resource = NULL; | ||
1973 | platform_device_put(csi2_pdev); | ||
1974 | module_put(csi2_drv); | ||
1975 | } | ||
1976 | 1769 | ||
1977 | return 0; | 1770 | return 0; |
1978 | } | 1771 | } |
@@ -2012,8 +1805,6 @@ static struct platform_driver sh_mobile_ceu_driver = { | |||
2012 | 1805 | ||
2013 | static int __init sh_mobile_ceu_init(void) | 1806 | static int __init sh_mobile_ceu_init(void) |
2014 | { | 1807 | { |
2015 | /* Whatever return code */ | ||
2016 | request_module("sh_mobile_csi2"); | ||
2017 | return platform_driver_register(&sh_mobile_ceu_driver); | 1808 | return platform_driver_register(&sh_mobile_ceu_driver); |
2018 | } | 1809 | } |
2019 | 1810 | ||
diff --git a/drivers/media/platform/soc_camera/sh_mobile_csi2.c b/drivers/media/platform/soc_camera/sh_mobile_csi2.c deleted file mode 100644 index 09b18365a4b1..000000000000 --- a/drivers/media/platform/soc_camera/sh_mobile_csi2.c +++ /dev/null | |||
@@ -1,400 +0,0 @@ | |||
1 | /* | ||
2 | * Driver for the SH-Mobile MIPI CSI-2 unit | ||
3 | * | ||
4 | * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/delay.h> | ||
12 | #include <linux/err.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/pm_runtime.h> | ||
17 | #include <linux/slab.h> | ||
18 | #include <linux/videodev2.h> | ||
19 | #include <linux/module.h> | ||
20 | |||
21 | #include <media/drv-intf/sh_mobile_ceu.h> | ||
22 | #include <media/drv-intf/sh_mobile_csi2.h> | ||
23 | #include <media/soc_camera.h> | ||
24 | #include <media/drv-intf/soc_mediabus.h> | ||
25 | #include <media/v4l2-common.h> | ||
26 | #include <media/v4l2-dev.h> | ||
27 | #include <media/v4l2-device.h> | ||
28 | #include <media/v4l2-mediabus.h> | ||
29 | #include <media/v4l2-subdev.h> | ||
30 | |||
31 | #define SH_CSI2_TREF 0x00 | ||
32 | #define SH_CSI2_SRST 0x04 | ||
33 | #define SH_CSI2_PHYCNT 0x08 | ||
34 | #define SH_CSI2_CHKSUM 0x0C | ||
35 | #define SH_CSI2_VCDT 0x10 | ||
36 | |||
37 | struct sh_csi2 { | ||
38 | struct v4l2_subdev subdev; | ||
39 | unsigned int irq; | ||
40 | unsigned long mipi_flags; | ||
41 | void __iomem *base; | ||
42 | struct platform_device *pdev; | ||
43 | struct sh_csi2_client_config *client; | ||
44 | }; | ||
45 | |||
46 | static void sh_csi2_hwinit(struct sh_csi2 *priv); | ||
47 | |||
48 | static int sh_csi2_set_fmt(struct v4l2_subdev *sd, | ||
49 | struct v4l2_subdev_pad_config *cfg, | ||
50 | struct v4l2_subdev_format *format) | ||
51 | { | ||
52 | struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev); | ||
53 | struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data; | ||
54 | struct v4l2_mbus_framefmt *mf = &format->format; | ||
55 | u32 tmp = (priv->client->channel & 3) << 8; | ||
56 | |||
57 | if (format->pad) | ||
58 | return -EINVAL; | ||
59 | |||
60 | if (mf->width > 8188) | ||
61 | mf->width = 8188; | ||
62 | else if (mf->width & 1) | ||
63 | mf->width &= ~1; | ||
64 | |||
65 | switch (pdata->type) { | ||
66 | case SH_CSI2C: | ||
67 | switch (mf->code) { | ||
68 | case MEDIA_BUS_FMT_UYVY8_2X8: /* YUV422 */ | ||
69 | case MEDIA_BUS_FMT_YUYV8_1_5X8: /* YUV420 */ | ||
70 | case MEDIA_BUS_FMT_Y8_1X8: /* RAW8 */ | ||
71 | case MEDIA_BUS_FMT_SBGGR8_1X8: | ||
72 | case MEDIA_BUS_FMT_SGRBG8_1X8: | ||
73 | break; | ||
74 | default: | ||
75 | /* All MIPI CSI-2 devices must support one of primary formats */ | ||
76 | mf->code = MEDIA_BUS_FMT_YUYV8_2X8; | ||
77 | } | ||
78 | break; | ||
79 | case SH_CSI2I: | ||
80 | switch (mf->code) { | ||
81 | case MEDIA_BUS_FMT_Y8_1X8: /* RAW8 */ | ||
82 | case MEDIA_BUS_FMT_SBGGR8_1X8: | ||
83 | case MEDIA_BUS_FMT_SGRBG8_1X8: | ||
84 | case MEDIA_BUS_FMT_SBGGR10_1X10: /* RAW10 */ | ||
85 | case MEDIA_BUS_FMT_SBGGR12_1X12: /* RAW12 */ | ||
86 | break; | ||
87 | default: | ||
88 | /* All MIPI CSI-2 devices must support one of primary formats */ | ||
89 | mf->code = MEDIA_BUS_FMT_SBGGR8_1X8; | ||
90 | } | ||
91 | break; | ||
92 | } | ||
93 | |||
94 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) { | ||
95 | cfg->try_fmt = *mf; | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | if (mf->width > 8188 || mf->width & 1) | ||
100 | return -EINVAL; | ||
101 | |||
102 | switch (mf->code) { | ||
103 | case MEDIA_BUS_FMT_UYVY8_2X8: | ||
104 | tmp |= 0x1e; /* YUV422 8 bit */ | ||
105 | break; | ||
106 | case MEDIA_BUS_FMT_YUYV8_1_5X8: | ||
107 | tmp |= 0x18; /* YUV420 8 bit */ | ||
108 | break; | ||
109 | case MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE: | ||
110 | tmp |= 0x21; /* RGB555 */ | ||
111 | break; | ||
112 | case MEDIA_BUS_FMT_RGB565_2X8_BE: | ||
113 | tmp |= 0x22; /* RGB565 */ | ||
114 | break; | ||
115 | case MEDIA_BUS_FMT_Y8_1X8: | ||
116 | case MEDIA_BUS_FMT_SBGGR8_1X8: | ||
117 | case MEDIA_BUS_FMT_SGRBG8_1X8: | ||
118 | tmp |= 0x2a; /* RAW8 */ | ||
119 | break; | ||
120 | default: | ||
121 | return -EINVAL; | ||
122 | } | ||
123 | |||
124 | iowrite32(tmp, priv->base + SH_CSI2_VCDT); | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int sh_csi2_g_mbus_config(struct v4l2_subdev *sd, | ||
130 | struct v4l2_mbus_config *cfg) | ||
131 | { | ||
132 | struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev); | ||
133 | |||
134 | if (!priv->mipi_flags) { | ||
135 | struct soc_camera_device *icd = v4l2_get_subdev_hostdata(sd); | ||
136 | struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd); | ||
137 | struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data; | ||
138 | unsigned long common_flags, csi2_flags; | ||
139 | struct v4l2_mbus_config client_cfg = {.type = V4L2_MBUS_CSI2,}; | ||
140 | int ret; | ||
141 | |||
142 | /* Check if we can support this camera */ | ||
143 | csi2_flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK | | ||
144 | V4L2_MBUS_CSI2_1_LANE; | ||
145 | |||
146 | switch (pdata->type) { | ||
147 | case SH_CSI2C: | ||
148 | if (priv->client->lanes != 1) | ||
149 | csi2_flags |= V4L2_MBUS_CSI2_2_LANE; | ||
150 | break; | ||
151 | case SH_CSI2I: | ||
152 | switch (priv->client->lanes) { | ||
153 | default: | ||
154 | csi2_flags |= V4L2_MBUS_CSI2_4_LANE; | ||
155 | case 3: | ||
156 | csi2_flags |= V4L2_MBUS_CSI2_3_LANE; | ||
157 | case 2: | ||
158 | csi2_flags |= V4L2_MBUS_CSI2_2_LANE; | ||
159 | } | ||
160 | } | ||
161 | |||
162 | ret = v4l2_subdev_call(client_sd, video, g_mbus_config, &client_cfg); | ||
163 | if (ret == -ENOIOCTLCMD) | ||
164 | common_flags = csi2_flags; | ||
165 | else if (!ret) | ||
166 | common_flags = soc_mbus_config_compatible(&client_cfg, | ||
167 | csi2_flags); | ||
168 | else | ||
169 | common_flags = 0; | ||
170 | |||
171 | if (!common_flags) | ||
172 | return -EINVAL; | ||
173 | |||
174 | /* All good: camera MIPI configuration supported */ | ||
175 | priv->mipi_flags = common_flags; | ||
176 | } | ||
177 | |||
178 | if (cfg) { | ||
179 | cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | | ||
180 | V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH | | ||
181 | V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH; | ||
182 | cfg->type = V4L2_MBUS_PARALLEL; | ||
183 | } | ||
184 | |||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | static int sh_csi2_s_mbus_config(struct v4l2_subdev *sd, | ||
189 | const struct v4l2_mbus_config *cfg) | ||
190 | { | ||
191 | struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev); | ||
192 | struct soc_camera_device *icd = v4l2_get_subdev_hostdata(sd); | ||
193 | struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd); | ||
194 | struct v4l2_mbus_config client_cfg = {.type = V4L2_MBUS_CSI2,}; | ||
195 | int ret = sh_csi2_g_mbus_config(sd, NULL); | ||
196 | |||
197 | if (ret < 0) | ||
198 | return ret; | ||
199 | |||
200 | pm_runtime_get_sync(&priv->pdev->dev); | ||
201 | |||
202 | sh_csi2_hwinit(priv); | ||
203 | |||
204 | client_cfg.flags = priv->mipi_flags; | ||
205 | |||
206 | return v4l2_subdev_call(client_sd, video, s_mbus_config, &client_cfg); | ||
207 | } | ||
208 | |||
209 | static struct v4l2_subdev_video_ops sh_csi2_subdev_video_ops = { | ||
210 | .g_mbus_config = sh_csi2_g_mbus_config, | ||
211 | .s_mbus_config = sh_csi2_s_mbus_config, | ||
212 | }; | ||
213 | |||
214 | static struct v4l2_subdev_pad_ops sh_csi2_subdev_pad_ops = { | ||
215 | .set_fmt = sh_csi2_set_fmt, | ||
216 | }; | ||
217 | |||
218 | static void sh_csi2_hwinit(struct sh_csi2 *priv) | ||
219 | { | ||
220 | struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data; | ||
221 | __u32 tmp = 0x10; /* Enable MIPI CSI clock lane */ | ||
222 | |||
223 | /* Reflect registers immediately */ | ||
224 | iowrite32(0x00000001, priv->base + SH_CSI2_TREF); | ||
225 | /* reset CSI2 harware */ | ||
226 | iowrite32(0x00000001, priv->base + SH_CSI2_SRST); | ||
227 | udelay(5); | ||
228 | iowrite32(0x00000000, priv->base + SH_CSI2_SRST); | ||
229 | |||
230 | switch (pdata->type) { | ||
231 | case SH_CSI2C: | ||
232 | if (priv->client->lanes == 1) | ||
233 | tmp |= 1; | ||
234 | else | ||
235 | /* Default - both lanes */ | ||
236 | tmp |= 3; | ||
237 | break; | ||
238 | case SH_CSI2I: | ||
239 | if (!priv->client->lanes || priv->client->lanes > 4) | ||
240 | /* Default - all 4 lanes */ | ||
241 | tmp |= 0xf; | ||
242 | else | ||
243 | tmp |= (1 << priv->client->lanes) - 1; | ||
244 | } | ||
245 | |||
246 | if (priv->client->phy == SH_CSI2_PHY_MAIN) | ||
247 | tmp |= 0x8000; | ||
248 | |||
249 | iowrite32(tmp, priv->base + SH_CSI2_PHYCNT); | ||
250 | |||
251 | tmp = 0; | ||
252 | if (pdata->flags & SH_CSI2_ECC) | ||
253 | tmp |= 2; | ||
254 | if (pdata->flags & SH_CSI2_CRC) | ||
255 | tmp |= 1; | ||
256 | iowrite32(tmp, priv->base + SH_CSI2_CHKSUM); | ||
257 | } | ||
258 | |||
259 | static int sh_csi2_client_connect(struct sh_csi2 *priv) | ||
260 | { | ||
261 | struct device *dev = v4l2_get_subdevdata(&priv->subdev); | ||
262 | struct sh_csi2_pdata *pdata = dev->platform_data; | ||
263 | struct soc_camera_device *icd = v4l2_get_subdev_hostdata(&priv->subdev); | ||
264 | int i; | ||
265 | |||
266 | if (priv->client) | ||
267 | return -EBUSY; | ||
268 | |||
269 | for (i = 0; i < pdata->num_clients; i++) | ||
270 | if ((pdata->clients[i].pdev && | ||
271 | &pdata->clients[i].pdev->dev == icd->pdev) || | ||
272 | (icd->control && | ||
273 | strcmp(pdata->clients[i].name, dev_name(icd->control)))) | ||
274 | break; | ||
275 | |||
276 | dev_dbg(dev, "%s(%p): found #%d\n", __func__, dev, i); | ||
277 | |||
278 | if (i == pdata->num_clients) | ||
279 | return -ENODEV; | ||
280 | |||
281 | priv->client = pdata->clients + i; | ||
282 | |||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | static void sh_csi2_client_disconnect(struct sh_csi2 *priv) | ||
287 | { | ||
288 | if (!priv->client) | ||
289 | return; | ||
290 | |||
291 | priv->client = NULL; | ||
292 | |||
293 | pm_runtime_put(v4l2_get_subdevdata(&priv->subdev)); | ||
294 | } | ||
295 | |||
296 | static int sh_csi2_s_power(struct v4l2_subdev *sd, int on) | ||
297 | { | ||
298 | struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev); | ||
299 | |||
300 | if (on) | ||
301 | return sh_csi2_client_connect(priv); | ||
302 | |||
303 | sh_csi2_client_disconnect(priv); | ||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | static struct v4l2_subdev_core_ops sh_csi2_subdev_core_ops = { | ||
308 | .s_power = sh_csi2_s_power, | ||
309 | }; | ||
310 | |||
311 | static struct v4l2_subdev_ops sh_csi2_subdev_ops = { | ||
312 | .core = &sh_csi2_subdev_core_ops, | ||
313 | .video = &sh_csi2_subdev_video_ops, | ||
314 | .pad = &sh_csi2_subdev_pad_ops, | ||
315 | }; | ||
316 | |||
317 | static int sh_csi2_probe(struct platform_device *pdev) | ||
318 | { | ||
319 | struct resource *res; | ||
320 | unsigned int irq; | ||
321 | int ret; | ||
322 | struct sh_csi2 *priv; | ||
323 | /* Platform data specify the PHY, lanes, ECC, CRC */ | ||
324 | struct sh_csi2_pdata *pdata = pdev->dev.platform_data; | ||
325 | |||
326 | if (!pdata) | ||
327 | return -EINVAL; | ||
328 | |||
329 | priv = devm_kzalloc(&pdev->dev, sizeof(struct sh_csi2), GFP_KERNEL); | ||
330 | if (!priv) | ||
331 | return -ENOMEM; | ||
332 | |||
333 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
334 | /* Interrupt unused so far */ | ||
335 | irq = platform_get_irq(pdev, 0); | ||
336 | |||
337 | if (!res || (int)irq <= 0) { | ||
338 | dev_err(&pdev->dev, "Not enough CSI2 platform resources.\n"); | ||
339 | return -ENODEV; | ||
340 | } | ||
341 | |||
342 | /* TODO: Add support for CSI2I. Careful: different register layout! */ | ||
343 | if (pdata->type != SH_CSI2C) { | ||
344 | dev_err(&pdev->dev, "Only CSI2C supported ATM.\n"); | ||
345 | return -EINVAL; | ||
346 | } | ||
347 | |||
348 | priv->irq = irq; | ||
349 | |||
350 | priv->base = devm_ioremap_resource(&pdev->dev, res); | ||
351 | if (IS_ERR(priv->base)) | ||
352 | return PTR_ERR(priv->base); | ||
353 | |||
354 | priv->pdev = pdev; | ||
355 | priv->subdev.owner = THIS_MODULE; | ||
356 | priv->subdev.dev = &pdev->dev; | ||
357 | platform_set_drvdata(pdev, &priv->subdev); | ||
358 | |||
359 | v4l2_subdev_init(&priv->subdev, &sh_csi2_subdev_ops); | ||
360 | v4l2_set_subdevdata(&priv->subdev, &pdev->dev); | ||
361 | |||
362 | snprintf(priv->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s.mipi-csi", | ||
363 | dev_name(&pdev->dev)); | ||
364 | |||
365 | ret = v4l2_async_register_subdev(&priv->subdev); | ||
366 | if (ret < 0) | ||
367 | return ret; | ||
368 | |||
369 | pm_runtime_enable(&pdev->dev); | ||
370 | |||
371 | dev_dbg(&pdev->dev, "CSI2 probed.\n"); | ||
372 | |||
373 | return 0; | ||
374 | } | ||
375 | |||
376 | static int sh_csi2_remove(struct platform_device *pdev) | ||
377 | { | ||
378 | struct v4l2_subdev *subdev = platform_get_drvdata(pdev); | ||
379 | struct sh_csi2 *priv = container_of(subdev, struct sh_csi2, subdev); | ||
380 | |||
381 | v4l2_async_unregister_subdev(&priv->subdev); | ||
382 | pm_runtime_disable(&pdev->dev); | ||
383 | |||
384 | return 0; | ||
385 | } | ||
386 | |||
387 | static struct platform_driver __refdata sh_csi2_pdrv = { | ||
388 | .remove = sh_csi2_remove, | ||
389 | .probe = sh_csi2_probe, | ||
390 | .driver = { | ||
391 | .name = "sh-mobile-csi2", | ||
392 | }, | ||
393 | }; | ||
394 | |||
395 | module_platform_driver(sh_csi2_pdrv); | ||
396 | |||
397 | MODULE_DESCRIPTION("SH-Mobile MIPI CSI-2 driver"); | ||
398 | MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>"); | ||
399 | MODULE_LICENSE("GPL v2"); | ||
400 | MODULE_ALIAS("platform:sh-mobile-csi2"); | ||
diff --git a/include/media/drv-intf/sh_mobile_ceu.h b/include/media/drv-intf/sh_mobile_ceu.h index 7f57056c22ba..2f43f7d9e28d 100644 --- a/include/media/drv-intf/sh_mobile_ceu.h +++ b/include/media/drv-intf/sh_mobile_ceu.h | |||
@@ -21,7 +21,6 @@ struct sh_mobile_ceu_info { | |||
21 | unsigned long flags; | 21 | unsigned long flags; |
22 | int max_width; | 22 | int max_width; |
23 | int max_height; | 23 | int max_height; |
24 | struct sh_mobile_ceu_companion *csi2; | ||
25 | struct v4l2_async_subdev **asd; /* Flat array, arranged in groups */ | 24 | struct v4l2_async_subdev **asd; /* Flat array, arranged in groups */ |
26 | unsigned int *asd_sizes; /* 0-terminated array pf asd group sizes */ | 25 | unsigned int *asd_sizes; /* 0-terminated array pf asd group sizes */ |
27 | }; | 26 | }; |
diff --git a/include/media/drv-intf/sh_mobile_csi2.h b/include/media/drv-intf/sh_mobile_csi2.h deleted file mode 100644 index 14030db51f13..000000000000 --- a/include/media/drv-intf/sh_mobile_csi2.h +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | /* | ||
2 | * Driver header for the SH-Mobile MIPI CSI-2 unit | ||
3 | * | ||
4 | * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef SH_MIPI_CSI | ||
12 | #define SH_MIPI_CSI | ||
13 | |||
14 | #include <linux/list.h> | ||
15 | |||
16 | enum sh_csi2_phy { | ||
17 | SH_CSI2_PHY_MAIN, | ||
18 | SH_CSI2_PHY_SUB, | ||
19 | }; | ||
20 | |||
21 | enum sh_csi2_type { | ||
22 | SH_CSI2C, | ||
23 | SH_CSI2I, | ||
24 | }; | ||
25 | |||
26 | #define SH_CSI2_CRC (1 << 0) | ||
27 | #define SH_CSI2_ECC (1 << 1) | ||
28 | |||
29 | struct platform_device; | ||
30 | |||
31 | struct sh_csi2_client_config { | ||
32 | enum sh_csi2_phy phy; | ||
33 | unsigned char lanes; /* bitmask[3:0] */ | ||
34 | unsigned char channel; /* 0..3 */ | ||
35 | struct platform_device *pdev; /* client platform device */ | ||
36 | const char *name; /* async matching: client name */ | ||
37 | }; | ||
38 | |||
39 | struct v4l2_device; | ||
40 | |||
41 | struct sh_csi2_pdata { | ||
42 | enum sh_csi2_type type; | ||
43 | unsigned int flags; | ||
44 | struct sh_csi2_client_config *clients; | ||
45 | int num_clients; | ||
46 | }; | ||
47 | |||
48 | #endif | ||