diff options
Diffstat (limited to 'drivers/media/video/davinci/vpfe_capture.c')
-rw-r--r-- | drivers/media/video/davinci/vpfe_capture.c | 131 |
1 files changed, 13 insertions, 118 deletions
diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c index de22bc9faf21..885cd54499cf 100644 --- a/drivers/media/video/davinci/vpfe_capture.c +++ b/drivers/media/video/davinci/vpfe_capture.c | |||
@@ -107,9 +107,6 @@ struct ccdc_config { | |||
107 | int vpfe_probed; | 107 | int vpfe_probed; |
108 | /* name of ccdc device */ | 108 | /* name of ccdc device */ |
109 | char name[32]; | 109 | char name[32]; |
110 | /* for storing mem maps for CCDC */ | ||
111 | int ccdc_addr_size; | ||
112 | void *__iomem ccdc_addr; | ||
113 | }; | 110 | }; |
114 | 111 | ||
115 | /* data structures */ | 112 | /* data structures */ |
@@ -229,7 +226,6 @@ int vpfe_register_ccdc_device(struct ccdc_hw_device *dev) | |||
229 | BUG_ON(!dev->hw_ops.set_image_window); | 226 | BUG_ON(!dev->hw_ops.set_image_window); |
230 | BUG_ON(!dev->hw_ops.get_image_window); | 227 | BUG_ON(!dev->hw_ops.get_image_window); |
231 | BUG_ON(!dev->hw_ops.get_line_length); | 228 | BUG_ON(!dev->hw_ops.get_line_length); |
232 | BUG_ON(!dev->hw_ops.setfbaddr); | ||
233 | BUG_ON(!dev->hw_ops.getfid); | 229 | BUG_ON(!dev->hw_ops.getfid); |
234 | 230 | ||
235 | mutex_lock(&ccdc_lock); | 231 | mutex_lock(&ccdc_lock); |
@@ -240,25 +236,23 @@ int vpfe_register_ccdc_device(struct ccdc_hw_device *dev) | |||
240 | * walk through it during vpfe probe | 236 | * walk through it during vpfe probe |
241 | */ | 237 | */ |
242 | printk(KERN_ERR "vpfe capture not initialized\n"); | 238 | printk(KERN_ERR "vpfe capture not initialized\n"); |
243 | ret = -1; | 239 | ret = -EFAULT; |
244 | goto unlock; | 240 | goto unlock; |
245 | } | 241 | } |
246 | 242 | ||
247 | if (strcmp(dev->name, ccdc_cfg->name)) { | 243 | if (strcmp(dev->name, ccdc_cfg->name)) { |
248 | /* ignore this ccdc */ | 244 | /* ignore this ccdc */ |
249 | ret = -1; | 245 | ret = -EINVAL; |
250 | goto unlock; | 246 | goto unlock; |
251 | } | 247 | } |
252 | 248 | ||
253 | if (ccdc_dev) { | 249 | if (ccdc_dev) { |
254 | printk(KERN_ERR "ccdc already registered\n"); | 250 | printk(KERN_ERR "ccdc already registered\n"); |
255 | ret = -1; | 251 | ret = -EINVAL; |
256 | goto unlock; | 252 | goto unlock; |
257 | } | 253 | } |
258 | 254 | ||
259 | ccdc_dev = dev; | 255 | ccdc_dev = dev; |
260 | dev->hw_ops.set_ccdc_base(ccdc_cfg->ccdc_addr, | ||
261 | ccdc_cfg->ccdc_addr_size); | ||
262 | unlock: | 256 | unlock: |
263 | mutex_unlock(&ccdc_lock); | 257 | mutex_unlock(&ccdc_lock); |
264 | return ret; | 258 | return ret; |
@@ -1786,61 +1780,6 @@ static struct vpfe_device *vpfe_initialize(void) | |||
1786 | return vpfe_dev; | 1780 | return vpfe_dev; |
1787 | } | 1781 | } |
1788 | 1782 | ||
1789 | static void vpfe_disable_clock(struct vpfe_device *vpfe_dev) | ||
1790 | { | ||
1791 | struct vpfe_config *vpfe_cfg = vpfe_dev->cfg; | ||
1792 | |||
1793 | clk_disable(vpfe_cfg->vpssclk); | ||
1794 | clk_put(vpfe_cfg->vpssclk); | ||
1795 | clk_disable(vpfe_cfg->slaveclk); | ||
1796 | clk_put(vpfe_cfg->slaveclk); | ||
1797 | v4l2_info(vpfe_dev->pdev->driver, | ||
1798 | "vpfe vpss master & slave clocks disabled\n"); | ||
1799 | } | ||
1800 | |||
1801 | static int vpfe_enable_clock(struct vpfe_device *vpfe_dev) | ||
1802 | { | ||
1803 | struct vpfe_config *vpfe_cfg = vpfe_dev->cfg; | ||
1804 | int ret = -ENOENT; | ||
1805 | |||
1806 | vpfe_cfg->vpssclk = clk_get(vpfe_dev->pdev, "vpss_master"); | ||
1807 | if (NULL == vpfe_cfg->vpssclk) { | ||
1808 | v4l2_err(vpfe_dev->pdev->driver, "No clock defined for" | ||
1809 | "vpss_master\n"); | ||
1810 | return ret; | ||
1811 | } | ||
1812 | |||
1813 | if (clk_enable(vpfe_cfg->vpssclk)) { | ||
1814 | v4l2_err(vpfe_dev->pdev->driver, | ||
1815 | "vpfe vpss master clock not enabled\n"); | ||
1816 | goto out; | ||
1817 | } | ||
1818 | v4l2_info(vpfe_dev->pdev->driver, | ||
1819 | "vpfe vpss master clock enabled\n"); | ||
1820 | |||
1821 | vpfe_cfg->slaveclk = clk_get(vpfe_dev->pdev, "vpss_slave"); | ||
1822 | if (NULL == vpfe_cfg->slaveclk) { | ||
1823 | v4l2_err(vpfe_dev->pdev->driver, | ||
1824 | "No clock defined for vpss slave\n"); | ||
1825 | goto out; | ||
1826 | } | ||
1827 | |||
1828 | if (clk_enable(vpfe_cfg->slaveclk)) { | ||
1829 | v4l2_err(vpfe_dev->pdev->driver, | ||
1830 | "vpfe vpss slave clock not enabled\n"); | ||
1831 | goto out; | ||
1832 | } | ||
1833 | v4l2_info(vpfe_dev->pdev->driver, "vpfe vpss slave clock enabled\n"); | ||
1834 | return 0; | ||
1835 | out: | ||
1836 | if (vpfe_cfg->vpssclk) | ||
1837 | clk_put(vpfe_cfg->vpssclk); | ||
1838 | if (vpfe_cfg->slaveclk) | ||
1839 | clk_put(vpfe_cfg->slaveclk); | ||
1840 | |||
1841 | return -1; | ||
1842 | } | ||
1843 | |||
1844 | /* | 1783 | /* |
1845 | * vpfe_probe : This function creates device entries by register | 1784 | * vpfe_probe : This function creates device entries by register |
1846 | * itself to the V4L2 driver and initializes fields of each | 1785 | * itself to the V4L2 driver and initializes fields of each |
@@ -1870,7 +1809,7 @@ static __init int vpfe_probe(struct platform_device *pdev) | |||
1870 | 1809 | ||
1871 | if (NULL == pdev->dev.platform_data) { | 1810 | if (NULL == pdev->dev.platform_data) { |
1872 | v4l2_err(pdev->dev.driver, "Unable to get vpfe config\n"); | 1811 | v4l2_err(pdev->dev.driver, "Unable to get vpfe config\n"); |
1873 | ret = -ENOENT; | 1812 | ret = -ENODEV; |
1874 | goto probe_free_dev_mem; | 1813 | goto probe_free_dev_mem; |
1875 | } | 1814 | } |
1876 | 1815 | ||
@@ -1884,18 +1823,13 @@ static __init int vpfe_probe(struct platform_device *pdev) | |||
1884 | goto probe_free_dev_mem; | 1823 | goto probe_free_dev_mem; |
1885 | } | 1824 | } |
1886 | 1825 | ||
1887 | /* enable vpss clocks */ | ||
1888 | ret = vpfe_enable_clock(vpfe_dev); | ||
1889 | if (ret) | ||
1890 | goto probe_free_dev_mem; | ||
1891 | |||
1892 | mutex_lock(&ccdc_lock); | 1826 | mutex_lock(&ccdc_lock); |
1893 | /* Allocate memory for ccdc configuration */ | 1827 | /* Allocate memory for ccdc configuration */ |
1894 | ccdc_cfg = kmalloc(sizeof(struct ccdc_config), GFP_KERNEL); | 1828 | ccdc_cfg = kmalloc(sizeof(struct ccdc_config), GFP_KERNEL); |
1895 | if (NULL == ccdc_cfg) { | 1829 | if (NULL == ccdc_cfg) { |
1896 | v4l2_err(pdev->dev.driver, | 1830 | v4l2_err(pdev->dev.driver, |
1897 | "Memory allocation failed for ccdc_cfg\n"); | 1831 | "Memory allocation failed for ccdc_cfg\n"); |
1898 | goto probe_disable_clock; | 1832 | goto probe_free_dev_mem; |
1899 | } | 1833 | } |
1900 | 1834 | ||
1901 | strncpy(ccdc_cfg->name, vpfe_cfg->ccdc, 32); | 1835 | strncpy(ccdc_cfg->name, vpfe_cfg->ccdc, 32); |
@@ -1904,61 +1838,34 @@ static __init int vpfe_probe(struct platform_device *pdev) | |||
1904 | if (!res1) { | 1838 | if (!res1) { |
1905 | v4l2_err(pdev->dev.driver, | 1839 | v4l2_err(pdev->dev.driver, |
1906 | "Unable to get interrupt for VINT0\n"); | 1840 | "Unable to get interrupt for VINT0\n"); |
1907 | ret = -ENOENT; | 1841 | ret = -ENODEV; |
1908 | goto probe_disable_clock; | 1842 | goto probe_free_ccdc_cfg_mem; |
1909 | } | 1843 | } |
1910 | vpfe_dev->ccdc_irq0 = res1->start; | 1844 | vpfe_dev->ccdc_irq0 = res1->start; |
1911 | 1845 | ||
1912 | /* Get VINT1 irq resource */ | 1846 | /* Get VINT1 irq resource */ |
1913 | res1 = platform_get_resource(pdev, | 1847 | res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 1); |
1914 | IORESOURCE_IRQ, 1); | ||
1915 | if (!res1) { | 1848 | if (!res1) { |
1916 | v4l2_err(pdev->dev.driver, | 1849 | v4l2_err(pdev->dev.driver, |
1917 | "Unable to get interrupt for VINT1\n"); | 1850 | "Unable to get interrupt for VINT1\n"); |
1918 | ret = -ENOENT; | 1851 | ret = -ENODEV; |
1919 | goto probe_disable_clock; | 1852 | goto probe_free_ccdc_cfg_mem; |
1920 | } | 1853 | } |
1921 | vpfe_dev->ccdc_irq1 = res1->start; | 1854 | vpfe_dev->ccdc_irq1 = res1->start; |
1922 | 1855 | ||
1923 | /* Get address base of CCDC */ | ||
1924 | res1 = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1925 | if (!res1) { | ||
1926 | v4l2_err(pdev->dev.driver, | ||
1927 | "Unable to get register address map\n"); | ||
1928 | ret = -ENOENT; | ||
1929 | goto probe_disable_clock; | ||
1930 | } | ||
1931 | |||
1932 | ccdc_cfg->ccdc_addr_size = res1->end - res1->start + 1; | ||
1933 | if (!request_mem_region(res1->start, ccdc_cfg->ccdc_addr_size, | ||
1934 | pdev->dev.driver->name)) { | ||
1935 | v4l2_err(pdev->dev.driver, | ||
1936 | "Failed request_mem_region for ccdc base\n"); | ||
1937 | ret = -ENXIO; | ||
1938 | goto probe_disable_clock; | ||
1939 | } | ||
1940 | ccdc_cfg->ccdc_addr = ioremap_nocache(res1->start, | ||
1941 | ccdc_cfg->ccdc_addr_size); | ||
1942 | if (!ccdc_cfg->ccdc_addr) { | ||
1943 | v4l2_err(pdev->dev.driver, "Unable to ioremap ccdc addr\n"); | ||
1944 | ret = -ENXIO; | ||
1945 | goto probe_out_release_mem1; | ||
1946 | } | ||
1947 | |||
1948 | ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, IRQF_DISABLED, | 1856 | ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, IRQF_DISABLED, |
1949 | "vpfe_capture0", vpfe_dev); | 1857 | "vpfe_capture0", vpfe_dev); |
1950 | 1858 | ||
1951 | if (0 != ret) { | 1859 | if (0 != ret) { |
1952 | v4l2_err(pdev->dev.driver, "Unable to request interrupt\n"); | 1860 | v4l2_err(pdev->dev.driver, "Unable to request interrupt\n"); |
1953 | goto probe_out_unmap1; | 1861 | goto probe_free_ccdc_cfg_mem; |
1954 | } | 1862 | } |
1955 | 1863 | ||
1956 | /* Allocate memory for video device */ | 1864 | /* Allocate memory for video device */ |
1957 | vfd = video_device_alloc(); | 1865 | vfd = video_device_alloc(); |
1958 | if (NULL == vfd) { | 1866 | if (NULL == vfd) { |
1959 | ret = -ENOMEM; | 1867 | ret = -ENOMEM; |
1960 | v4l2_err(pdev->dev.driver, | 1868 | v4l2_err(pdev->dev.driver, "Unable to alloc video device\n"); |
1961 | "Unable to alloc video device\n"); | ||
1962 | goto probe_out_release_irq; | 1869 | goto probe_out_release_irq; |
1963 | } | 1870 | } |
1964 | 1871 | ||
@@ -2073,12 +1980,7 @@ probe_out_video_release: | |||
2073 | video_device_release(vpfe_dev->video_dev); | 1980 | video_device_release(vpfe_dev->video_dev); |
2074 | probe_out_release_irq: | 1981 | probe_out_release_irq: |
2075 | free_irq(vpfe_dev->ccdc_irq0, vpfe_dev); | 1982 | free_irq(vpfe_dev->ccdc_irq0, vpfe_dev); |
2076 | probe_out_unmap1: | 1983 | probe_free_ccdc_cfg_mem: |
2077 | iounmap(ccdc_cfg->ccdc_addr); | ||
2078 | probe_out_release_mem1: | ||
2079 | release_mem_region(res1->start, res1->end - res1->start + 1); | ||
2080 | probe_disable_clock: | ||
2081 | vpfe_disable_clock(vpfe_dev); | ||
2082 | mutex_unlock(&ccdc_lock); | 1984 | mutex_unlock(&ccdc_lock); |
2083 | kfree(ccdc_cfg); | 1985 | kfree(ccdc_cfg); |
2084 | probe_free_dev_mem: | 1986 | probe_free_dev_mem: |
@@ -2092,7 +1994,6 @@ probe_free_dev_mem: | |||
2092 | static int __devexit vpfe_remove(struct platform_device *pdev) | 1994 | static int __devexit vpfe_remove(struct platform_device *pdev) |
2093 | { | 1995 | { |
2094 | struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev); | 1996 | struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev); |
2095 | struct resource *res; | ||
2096 | 1997 | ||
2097 | v4l2_info(pdev->dev.driver, "vpfe_remove\n"); | 1998 | v4l2_info(pdev->dev.driver, "vpfe_remove\n"); |
2098 | 1999 | ||
@@ -2100,12 +2001,6 @@ static int __devexit vpfe_remove(struct platform_device *pdev) | |||
2100 | kfree(vpfe_dev->sd); | 2001 | kfree(vpfe_dev->sd); |
2101 | v4l2_device_unregister(&vpfe_dev->v4l2_dev); | 2002 | v4l2_device_unregister(&vpfe_dev->v4l2_dev); |
2102 | video_unregister_device(vpfe_dev->video_dev); | 2003 | video_unregister_device(vpfe_dev->video_dev); |
2103 | mutex_lock(&ccdc_lock); | ||
2104 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
2105 | release_mem_region(res->start, res->end - res->start + 1); | ||
2106 | iounmap(ccdc_cfg->ccdc_addr); | ||
2107 | mutex_unlock(&ccdc_lock); | ||
2108 | vpfe_disable_clock(vpfe_dev); | ||
2109 | kfree(vpfe_dev); | 2004 | kfree(vpfe_dev); |
2110 | kfree(ccdc_cfg); | 2005 | kfree(ccdc_cfg); |
2111 | return 0; | 2006 | return 0; |