summaryrefslogtreecommitdiff
path: root/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h
blob: e301d80362cfc0d587a4dc37821314b0ae723b9c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/* SPDX-License-Identifier: GPL-2.0+ */
/*
 * Copyright (c) 2011-2018 Magewell Electronics Co., Ltd. (Nanjing)
 * All rights reserved.
 * Author: Yong Deng <yong.deng@magewell.com>
 */

#ifndef __SUN6I_CSI_H__
#define __SUN6I_CSI_H__

#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>

#include "sun6i_video.h"

#define SUN6I_CSI_NAME		"sun6i-csi"
#define SUN6I_CSI_DESCRIPTION	"Allwinner A31 CSI Device"

/**
 * struct sun6i_csi_config - configs for sun6i csi
 * @pixelformat: v4l2 pixel format (V4L2_PIX_FMT_*)
 * @code:	media bus format code (MEDIA_BUS_FMT_*)
 * @field:	used interlacing type (enum v4l2_field)
 * @width:	frame width
 * @height:	frame height
 */
struct sun6i_csi_config {
	u32		pixelformat;
	u32		code;
	u32		field;
	u32		width;
	u32		height;
};

struct sun6i_csi_v4l2 {
	struct v4l2_device		v4l2_dev;
	struct v4l2_ctrl_handler	ctrl_handler;
	struct media_device		media_dev;

	struct v4l2_async_notifier	notifier;
	/* video port settings */
	struct v4l2_fwnode_endpoint	v4l2_ep;
};

struct sun6i_csi_device {
	struct device			*dev;

	struct sun6i_csi_config		config;
	struct sun6i_csi_v4l2		v4l2;
	struct sun6i_video		video;

	struct regmap			*regmap;
	struct clk			*clock_mod;
	struct clk			*clock_ram;
	struct reset_control		*reset;

	int				planar_offset[3];
};

struct sun6i_csi_variant {
	unsigned long	clock_mod_rate;
};

/**
 * sun6i_csi_is_format_supported() - check if the format supported by csi
 * @csi_dev:	pointer to the csi device
 * @pixformat:	v4l2 pixel format (V4L2_PIX_FMT_*)
 * @mbus_code:	media bus format code (MEDIA_BUS_FMT_*)
 *
 * Return: true if format is supported, false otherwise.
 */
bool sun6i_csi_is_format_supported(struct sun6i_csi_device *csi_dev,
				   u32 pixformat, u32 mbus_code);

/**
 * sun6i_csi_set_power() - power on/off the csi
 * @csi_dev:	pointer to the csi device
 * @enable:	on/off
 *
 * Return: 0 if successful, error code otherwise.
 */
int sun6i_csi_set_power(struct sun6i_csi_device *csi_dev, bool enable);

/**
 * sun6i_csi_update_config() - update the csi register settings
 * @csi_dev:	pointer to the csi device
 * @config:	see struct sun6i_csi_config
 *
 * Return: 0 if successful, error code otherwise.
 */
int sun6i_csi_update_config(struct sun6i_csi_device *csi_dev,
			    struct sun6i_csi_config *config);

/**
 * sun6i_csi_update_buf_addr() - update the csi frame buffer address
 * @csi_dev:	pointer to the csi device
 * @addr:	frame buffer's physical address
 */
void sun6i_csi_update_buf_addr(struct sun6i_csi_device *csi_dev,
			       dma_addr_t addr);

/**
 * sun6i_csi_set_stream() - start/stop csi streaming
 * @csi_dev:	pointer to the csi device
 * @enable:	start/stop
 */
void sun6i_csi_set_stream(struct sun6i_csi_device *csi_dev, bool enable);

/* get bpp form v4l2 pixformat */
static inline int sun6i_csi_get_bpp(unsigned int pixformat)
{
	switch (pixformat) {
	case V4L2_PIX_FMT_SBGGR8:
	case V4L2_PIX_FMT_SGBRG8:
	case V4L2_PIX_FMT_SGRBG8:
	case V4L2_PIX_FMT_SRGGB8:
	case V4L2_PIX_FMT_JPEG:
		return 8;
	case V4L2_PIX_FMT_SBGGR10:
	case V4L2_PIX_FMT_SGBRG10:
	case V4L2_PIX_FMT_SGRBG10:
	case V4L2_PIX_FMT_SRGGB10:
		return 10;
	case V4L2_PIX_FMT_SBGGR12:
	case V4L2_PIX_FMT_SGBRG12:
	case V4L2_PIX_FMT_SGRBG12:
	case V4L2_PIX_FMT_SRGGB12:
	case V4L2_PIX_FMT_NV12_16L16:
	case V4L2_PIX_FMT_NV12:
	case V4L2_PIX_FMT_NV21:
	case V4L2_PIX_FMT_YUV420:
	case V4L2_PIX_FMT_YVU420:
		return 12;
	case V4L2_PIX_FMT_YUYV:
	case V4L2_PIX_FMT_YVYU:
	case V4L2_PIX_FMT_UYVY:
	case V4L2_PIX_FMT_VYUY:
	case V4L2_PIX_FMT_NV16:
	case V4L2_PIX_FMT_NV61:
	case V4L2_PIX_FMT_YUV422P:
	case V4L2_PIX_FMT_RGB565:
	case V4L2_PIX_FMT_RGB565X:
		return 16;
	case V4L2_PIX_FMT_RGB24:
	case V4L2_PIX_FMT_BGR24:
		return 24;
	case V4L2_PIX_FMT_RGB32:
	case V4L2_PIX_FMT_BGR32:
		return 32;
	default:
		WARN(1, "Unsupported pixformat: 0x%x\n", pixformat);
		break;
	}

	return 0;
}

#endif /* __SUN6I_CSI_H__ */