1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * Copyright (c) 2011-2018 Magewell Electronics Co., Ltd. (Nanjing)
4  * All rights reserved.
5  * Author: Yong Deng <yong.deng@magewell.com>
6  */
7 
8 #ifndef __SUN6I_CSI_H__
9 #define __SUN6I_CSI_H__
10 
11 #include <media/v4l2-device.h>
12 #include <media/v4l2-fwnode.h>
13 #include <media/videobuf2-v4l2.h>
14 
15 #include "sun6i_video.h"
16 
17 #define SUN6I_CSI_NAME		"sun6i-csi"
18 #define SUN6I_CSI_DESCRIPTION	"Allwinner A31 CSI Device"
19 
20 struct sun6i_csi_buffer {
21 	struct vb2_v4l2_buffer		v4l2_buffer;
22 	struct list_head		list;
23 
24 	dma_addr_t			dma_addr;
25 	bool				queued_to_csi;
26 };
27 
28 /**
29  * struct sun6i_csi_config - configs for sun6i csi
30  * @pixelformat: v4l2 pixel format (V4L2_PIX_FMT_*)
31  * @code:	media bus format code (MEDIA_BUS_FMT_*)
32  * @field:	used interlacing type (enum v4l2_field)
33  * @width:	frame width
34  * @height:	frame height
35  */
36 struct sun6i_csi_config {
37 	u32		pixelformat;
38 	u32		code;
39 	u32		field;
40 	u32		width;
41 	u32		height;
42 };
43 
44 struct sun6i_csi_v4l2 {
45 	struct v4l2_device		v4l2_dev;
46 	struct media_device		media_dev;
47 
48 	struct v4l2_async_notifier	notifier;
49 	/* video port settings */
50 	struct v4l2_fwnode_endpoint	v4l2_ep;
51 };
52 
53 struct sun6i_csi_device {
54 	struct device			*dev;
55 
56 	struct sun6i_csi_config		config;
57 	struct sun6i_csi_v4l2		v4l2;
58 	struct sun6i_video		video;
59 
60 	struct regmap			*regmap;
61 	struct clk			*clock_mod;
62 	struct clk			*clock_ram;
63 	struct reset_control		*reset;
64 
65 	int				planar_offset[3];
66 };
67 
68 struct sun6i_csi_variant {
69 	unsigned long	clock_mod_rate;
70 };
71 
72 /**
73  * sun6i_csi_is_format_supported() - check if the format supported by csi
74  * @csi_dev:	pointer to the csi device
75  * @pixformat:	v4l2 pixel format (V4L2_PIX_FMT_*)
76  * @mbus_code:	media bus format code (MEDIA_BUS_FMT_*)
77  *
78  * Return: true if format is supported, false otherwise.
79  */
80 bool sun6i_csi_is_format_supported(struct sun6i_csi_device *csi_dev,
81 				   u32 pixformat, u32 mbus_code);
82 
83 /**
84  * sun6i_csi_set_power() - power on/off the csi
85  * @csi_dev:	pointer to the csi device
86  * @enable:	on/off
87  *
88  * Return: 0 if successful, error code otherwise.
89  */
90 int sun6i_csi_set_power(struct sun6i_csi_device *csi_dev, bool enable);
91 
92 /**
93  * sun6i_csi_update_config() - update the csi register settings
94  * @csi_dev:	pointer to the csi device
95  * @config:	see struct sun6i_csi_config
96  *
97  * Return: 0 if successful, error code otherwise.
98  */
99 int sun6i_csi_update_config(struct sun6i_csi_device *csi_dev,
100 			    struct sun6i_csi_config *config);
101 
102 /**
103  * sun6i_csi_update_buf_addr() - update the csi frame buffer address
104  * @csi_dev:	pointer to the csi device
105  * @addr:	frame buffer's physical address
106  */
107 void sun6i_csi_update_buf_addr(struct sun6i_csi_device *csi_dev,
108 			       dma_addr_t addr);
109 
110 /**
111  * sun6i_csi_set_stream() - start/stop csi streaming
112  * @csi_dev:	pointer to the csi device
113  * @enable:	start/stop
114  */
115 void sun6i_csi_set_stream(struct sun6i_csi_device *csi_dev, bool enable);
116 
117 /* get bpp form v4l2 pixformat */
118 static inline int sun6i_csi_get_bpp(unsigned int pixformat)
119 {
120 	switch (pixformat) {
121 	case V4L2_PIX_FMT_SBGGR8:
122 	case V4L2_PIX_FMT_SGBRG8:
123 	case V4L2_PIX_FMT_SGRBG8:
124 	case V4L2_PIX_FMT_SRGGB8:
125 	case V4L2_PIX_FMT_JPEG:
126 		return 8;
127 	case V4L2_PIX_FMT_SBGGR10:
128 	case V4L2_PIX_FMT_SGBRG10:
129 	case V4L2_PIX_FMT_SGRBG10:
130 	case V4L2_PIX_FMT_SRGGB10:
131 		return 10;
132 	case V4L2_PIX_FMT_SBGGR12:
133 	case V4L2_PIX_FMT_SGBRG12:
134 	case V4L2_PIX_FMT_SGRBG12:
135 	case V4L2_PIX_FMT_SRGGB12:
136 	case V4L2_PIX_FMT_NV12_16L16:
137 	case V4L2_PIX_FMT_NV12:
138 	case V4L2_PIX_FMT_NV21:
139 	case V4L2_PIX_FMT_YUV420:
140 	case V4L2_PIX_FMT_YVU420:
141 		return 12;
142 	case V4L2_PIX_FMT_YUYV:
143 	case V4L2_PIX_FMT_YVYU:
144 	case V4L2_PIX_FMT_UYVY:
145 	case V4L2_PIX_FMT_VYUY:
146 	case V4L2_PIX_FMT_NV16:
147 	case V4L2_PIX_FMT_NV61:
148 	case V4L2_PIX_FMT_YUV422P:
149 	case V4L2_PIX_FMT_RGB565:
150 	case V4L2_PIX_FMT_RGB565X:
151 		return 16;
152 	case V4L2_PIX_FMT_RGB24:
153 	case V4L2_PIX_FMT_BGR24:
154 		return 24;
155 	case V4L2_PIX_FMT_RGB32:
156 	case V4L2_PIX_FMT_BGR32:
157 		return 32;
158 	default:
159 		WARN(1, "Unsupported pixformat: 0x%x\n", pixformat);
160 		break;
161 	}
162 
163 	return 0;
164 }
165 
166 #endif /* __SUN6I_CSI_H__ */
167