1+ // SPDX-License-Identifier: GPL-2.0
12/*
23 * Renesas - AP-325RXA
34 * (Compatible with Algo System ., LTD. - AP-320A)
45 *
56 * Copyright (C) 2008 Renesas Solutions Corp.
67 * Author : Yusuke Goda <goda.yuske@renesas.com>
7- *
8- * This file is subject to the terms and conditions of the GNU General Public
9- * License. See the file "COPYING" in the main directory of this archive
10- * for more details.
118 */
129
13- #include <linux/init.h>
10+ #include <asm/clock.h>
11+ #include <asm/io.h>
12+ #include <asm/suspend.h>
13+
14+ #include <cpu/sh7723.h>
15+
16+ #include <linux/clkdev.h>
17+ #include <linux/delay.h>
1418#include <linux/device.h>
19+ #include <linux/gpio.h>
20+ #include <linux/gpio/machine.h>
21+ #include <linux/i2c.h>
22+ #include <linux/init.h>
1523#include <linux/interrupt.h>
16- #include <linux/platform_device.h>
24+ #include <linux/memblock.h>
25+ #include <linux/mfd/tmio.h>
1726#include <linux/mmc/host.h>
1827#include <linux/mtd/physmap.h>
1928#include <linux/mtd/sh_flctl.h>
20- #include <linux/mfd/tmio.h>
21- #include <linux/delay.h>
22- #include <linux/i2c.h>
29+ #include <linux/platform_device.h>
2330#include <linux/regulator/fixed.h>
2431#include <linux/regulator/machine.h>
32+ #include <linux/sh_intc.h>
2533#include <linux/smsc911x.h>
26- #include <linux/gpio.h>
2734#include <linux/videodev2.h>
28- #include <linux/sh_intc.h>
35+
36+ #include <media/drv-intf/renesas-ceu.h>
2937#include <media/i2c/ov772x.h>
30- #include <media/soc_camera.h>
31- #include <linux/platform_data/media/soc_camera_platform.h>
32- #include <media/drv-intf/sh_mobile_ceu.h>
38+
3339#include <video/sh_mobile_lcdc.h>
34- #include <asm/io.h>
35- #include <asm/clock.h>
36- #include <asm/suspend.h>
37- #include <cpu/sh7723.h>
40+
41+ #define CEU_BUFFER_MEMORY_SIZE (4 << 20)
42+ static phys_addr_t ceu_dma_membase ;
3843
3944/* Dummy supplies, where voltage doesn't matter */
4045static struct regulator_consumer_supply dummy_supplies [] = {
@@ -253,150 +258,25 @@ static struct platform_device lcdc_device = {
253258 },
254259};
255260
256- static void camera_power (int val )
257- {
258- gpio_set_value (GPIO_PTZ5 , val ); /* RST_CAM/RSTB */
259- mdelay (10 );
260- }
261-
262- #ifdef CONFIG_I2C
263- /* support for the old ncm03j camera */
264- static unsigned char camera_ncm03j_magic [] =
265- {
266- 0x87 , 0x00 , 0x88 , 0x08 , 0x89 , 0x01 , 0x8A , 0xE8 ,
267- 0x1D , 0x00 , 0x1E , 0x8A , 0x21 , 0x00 , 0x33 , 0x36 ,
268- 0x36 , 0x60 , 0x37 , 0x08 , 0x3B , 0x31 , 0x44 , 0x0F ,
269- 0x46 , 0xF0 , 0x4B , 0x28 , 0x4C , 0x21 , 0x4D , 0x55 ,
270- 0x4E , 0x1B , 0x4F , 0xC7 , 0x50 , 0xFC , 0x51 , 0x12 ,
271- 0x58 , 0x02 , 0x66 , 0xC0 , 0x67 , 0x46 , 0x6B , 0xA0 ,
272- 0x6C , 0x34 , 0x7E , 0x25 , 0x7F , 0x25 , 0x8D , 0x0F ,
273- 0x92 , 0x40 , 0x93 , 0x04 , 0x94 , 0x26 , 0x95 , 0x0A ,
274- 0x99 , 0x03 , 0x9A , 0xF0 , 0x9B , 0x14 , 0x9D , 0x7A ,
275- 0xC5 , 0x02 , 0xD6 , 0x07 , 0x59 , 0x00 , 0x5A , 0x1A ,
276- 0x5B , 0x2A , 0x5C , 0x37 , 0x5D , 0x42 , 0x5E , 0x56 ,
277- 0xC8 , 0x00 , 0xC9 , 0x1A , 0xCA , 0x2A , 0xCB , 0x37 ,
278- 0xCC , 0x42 , 0xCD , 0x56 , 0xCE , 0x00 , 0xCF , 0x1A ,
279- 0xD0 , 0x2A , 0xD1 , 0x37 , 0xD2 , 0x42 , 0xD3 , 0x56 ,
280- 0x5F , 0x68 , 0x60 , 0x87 , 0x61 , 0xA3 , 0x62 , 0xBC ,
281- 0x63 , 0xD4 , 0x64 , 0xEA , 0xD6 , 0x0F ,
282- };
283-
284- static int camera_probe (void )
285- {
286- struct i2c_adapter * a = i2c_get_adapter (0 );
287- struct i2c_msg msg ;
288- int ret ;
289-
290- if (!a )
291- return - ENODEV ;
292-
293- camera_power (1 );
294- msg .addr = 0x6e ;
295- msg .buf = camera_ncm03j_magic ;
296- msg .len = 2 ;
297- msg .flags = 0 ;
298- ret = i2c_transfer (a , & msg , 1 );
299- camera_power (0 );
300-
301- return ret ;
302- }
303-
304- static int camera_set_capture (struct soc_camera_platform_info * info ,
305- int enable )
306- {
307- struct i2c_adapter * a = i2c_get_adapter (0 );
308- struct i2c_msg msg ;
309- int ret = 0 ;
310- int i ;
311-
312- camera_power (0 );
313- if (!enable )
314- return 0 ; /* no disable for now */
315-
316- camera_power (1 );
317- for (i = 0 ; i < ARRAY_SIZE (camera_ncm03j_magic ); i += 2 ) {
318- u_int8_t buf [8 ];
319-
320- msg .addr = 0x6e ;
321- msg .buf = buf ;
322- msg .len = 2 ;
323- msg .flags = 0 ;
324-
325- buf [0 ] = camera_ncm03j_magic [i ];
326- buf [1 ] = camera_ncm03j_magic [i + 1 ];
327-
328- ret = (ret < 0 ) ? ret : i2c_transfer (a , & msg , 1 );
329- }
330-
331- return ret ;
332- }
333-
334- static int ap325rxa_camera_add (struct soc_camera_device * icd );
335- static void ap325rxa_camera_del (struct soc_camera_device * icd );
336-
337- static struct soc_camera_platform_info camera_info = {
338- .format_name = "UYVY" ,
339- .format_depth = 16 ,
340- .format = {
341- .code = MEDIA_BUS_FMT_UYVY8_2X8 ,
342- .colorspace = V4L2_COLORSPACE_SMPTE170M ,
343- .field = V4L2_FIELD_NONE ,
344- .width = 640 ,
345- .height = 480 ,
261+ /* Powerdown/reset gpios for CEU image sensors */
262+ static struct gpiod_lookup_table ov7725_gpios = {
263+ .dev_id = "0-0021" ,
264+ .table = {
265+ GPIO_LOOKUP ("sh7723_pfc" , GPIO_PTZ5 , "reset" , GPIO_ACTIVE_LOW ),
346266 },
347- .mbus_param = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
348- V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
349- V4L2_MBUS_DATA_ACTIVE_HIGH ,
350- .mbus_type = V4L2_MBUS_PARALLEL ,
351- .set_capture = camera_set_capture ,
352- };
353-
354- static struct soc_camera_link camera_link = {
355- .bus_id = 0 ,
356- .add_device = ap325rxa_camera_add ,
357- .del_device = ap325rxa_camera_del ,
358- .module_name = "soc_camera_platform" ,
359- .priv = & camera_info ,
360267};
361268
362- static struct platform_device * camera_device ;
363-
364- static void ap325rxa_camera_release (struct device * dev )
365- {
366- soc_camera_platform_release (& camera_device );
367- }
368-
369- static int ap325rxa_camera_add (struct soc_camera_device * icd )
370- {
371- int ret = soc_camera_platform_add (icd , & camera_device , & camera_link ,
372- ap325rxa_camera_release , 0 );
373- if (ret < 0 )
374- return ret ;
375-
376- ret = camera_probe ();
377- if (ret < 0 )
378- soc_camera_platform_del (icd , camera_device , & camera_link );
379-
380- return ret ;
381- }
382-
383- static void ap325rxa_camera_del (struct soc_camera_device * icd )
384- {
385- soc_camera_platform_del (icd , camera_device , & camera_link );
386- }
387- #endif /* CONFIG_I2C */
388-
389- static int ov7725_power (struct device * dev , int mode )
390- {
391- camera_power (0 );
392- if (mode )
393- camera_power (1 );
394-
395- return 0 ;
396- }
397-
398- static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
399- .flags = SH_CEU_FLAG_USE_8BIT_BUS ,
269+ static struct ceu_platform_data ceu0_pdata = {
270+ .num_subdevs = 1 ,
271+ .subdevs = {
272+ { /* [0] = ov7725 */
273+ .flags = 0 ,
274+ .bus_width = 8 ,
275+ .bus_shift = 0 ,
276+ .i2c_adapter_id = 0 ,
277+ .i2c_address = 0x21 ,
278+ },
279+ },
400280};
401281
402282static struct resource ceu_resources [] = {
@@ -410,18 +290,15 @@ static struct resource ceu_resources[] = {
410290 .start = evt2irq (0x880 ),
411291 .flags = IORESOURCE_IRQ ,
412292 },
413- [2 ] = {
414- /* place holder for contiguous memory */
415- },
416293};
417294
418- static struct platform_device ceu_device = {
419- .name = "sh_mobile_ceu " ,
420- .id = 0 , /* "ceu0 " clock */
295+ static struct platform_device ap325rxa_ceu_device = {
296+ .name = "renesas-ceu " ,
297+ .id = 0 , /* "ceu.0 " clock */
421298 .num_resources = ARRAY_SIZE (ceu_resources ),
422299 .resource = ceu_resources ,
423300 .dev = {
424- .platform_data = & sh_mobile_ceu_info ,
301+ .platform_data = & ceu0_pdata ,
425302 },
426303};
427304
@@ -488,57 +365,28 @@ static struct platform_device sdhi1_cn7_device = {
488365 },
489366};
490367
491- static struct i2c_board_info __initdata ap325rxa_i2c_devices [] = {
492- {
493- I2C_BOARD_INFO ("pcf8563" , 0x51 ),
494- },
495- };
496-
497- static struct i2c_board_info ap325rxa_i2c_camera [] = {
498- {
499- I2C_BOARD_INFO ("ov772x" , 0x21 ),
500- },
501- };
502-
503368static struct ov772x_camera_info ov7725_info = {
504369 .flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP ,
505370 .edgectrl = OV772X_AUTO_EDGECTRL (0xf , 0 ),
506371};
507372
508- static struct soc_camera_link ov7725_link = {
509- .bus_id = 0 ,
510- .power = ov7725_power ,
511- .board_info = & ap325rxa_i2c_camera [0 ],
512- .i2c_adapter_id = 0 ,
513- .priv = & ov7725_info ,
514- };
515-
516- static struct platform_device ap325rxa_camera [] = {
373+ static struct i2c_board_info ap325rxa_i2c_devices [] __initdata = {
517374 {
518- .name = "soc-camera-pdrv" ,
519- .id = 0 ,
520- .dev = {
521- .platform_data = & ov7725_link ,
522- },
523- }, {
524- .name = "soc-camera-pdrv" ,
525- .id = 1 ,
526- .dev = {
527- .platform_data = & camera_link ,
528- },
375+ I2C_BOARD_INFO ("pcf8563" , 0x51 ),
376+ },
377+ {
378+ I2C_BOARD_INFO ("ov772x" , 0x21 ),
379+ .platform_data = & ov7725_info ,
529380 },
530381};
531382
532383static struct platform_device * ap325rxa_devices [] __initdata = {
533384 & smsc9118_device ,
534385 & ap325rxa_nor_flash_device ,
535386 & lcdc_device ,
536- & ceu_device ,
537387 & nand_flash_device ,
538388 & sdhi0_cn3_device ,
539389 & sdhi1_cn7_device ,
540- & ap325rxa_camera [0 ],
541- & ap325rxa_camera [1 ],
542390};
543391
544392extern char ap325rxa_sdram_enter_start ;
@@ -649,8 +497,6 @@ static int __init ap325rxa_devices_setup(void)
649497 __raw_writew (0xFFFF , PORT_DRVCRA );
650498 __raw_writew (0xFFFF , PORT_DRVCRB );
651499
652- platform_resource_setup_memory (& ceu_device , "ceu" , 4 << 20 );
653-
654500 /* SDHI0 - CN3 - SD CARD */
655501 gpio_request (GPIO_FN_SDHI0CD_PTD , NULL );
656502 gpio_request (GPIO_FN_SDHI0WP_PTD , NULL );
@@ -670,9 +516,25 @@ static int __init ap325rxa_devices_setup(void)
670516 gpio_request (GPIO_FN_SDHI1CMD , NULL );
671517 gpio_request (GPIO_FN_SDHI1CLK , NULL );
672518
519+ /* Add a clock alias for ov7725 xclk source. */
520+ clk_add_alias (NULL , "0-0021" , "video_clk" , NULL );
521+
522+ /* Register RSTB gpio for ov7725 camera sensor. */
523+ gpiod_add_lookup_table (& ov7725_gpios );
524+
673525 i2c_register_board_info (0 , ap325rxa_i2c_devices ,
674526 ARRAY_SIZE (ap325rxa_i2c_devices ));
675527
528+ /* Initialize CEU platform device separately to map memory first */
529+ device_initialize (& ap325rxa_ceu_device .dev );
530+ arch_setup_pdev_archdata (& ap325rxa_ceu_device );
531+ dma_declare_coherent_memory (& ap325rxa_ceu_device .dev ,
532+ ceu_dma_membase , ceu_dma_membase ,
533+ ceu_dma_membase + CEU_BUFFER_MEMORY_SIZE - 1 ,
534+ DMA_MEMORY_EXCLUSIVE );
535+
536+ platform_device_add (& ap325rxa_ceu_device );
537+
676538 return platform_add_devices (ap325rxa_devices ,
677539 ARRAY_SIZE (ap325rxa_devices ));
678540}
@@ -689,7 +551,21 @@ static int ap325rxa_mode_pins(void)
689551 return MODE_PIN5 | MODE_PIN8 ;
690552}
691553
554+ /* Reserve a portion of memory for CEU buffers */
555+ static void __init ap325rxa_mv_mem_reserve (void )
556+ {
557+ phys_addr_t phys ;
558+ phys_addr_t size = CEU_BUFFER_MEMORY_SIZE ;
559+
560+ phys = memblock_alloc_base (size , PAGE_SIZE , MEMBLOCK_ALLOC_ANYWHERE );
561+ memblock_free (phys , size );
562+ memblock_remove (phys , size );
563+
564+ ceu_dma_membase = phys ;
565+ }
566+
692567static struct sh_machine_vector mv_ap325rxa __initmv = {
693568 .mv_name = "AP-325RXA" ,
694569 .mv_mode_pins = ap325rxa_mode_pins ,
570+ .mv_mem_reserve = ap325rxa_mv_mem_reserve ,
695571};
0 commit comments