1/*
2 * OmniVision OV9740 Camera Driver
3 *
4 * Copyright (C) 2011 NVIDIA Corporation
5 *
6 * Based on ov9640 camera driver.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/i2c.h>
16#include <linux/slab.h>
17#include <linux/v4l2-mediabus.h>
18
19#include <media/soc_camera.h>
20#include <media/v4l2-clk.h>
21#include <media/v4l2-ctrls.h>
22
23#define to_ov9740(sd)		container_of(sd, struct ov9740_priv, subdev)
24
25/* General Status Registers */
26#define OV9740_MODEL_ID_HI		0x0000
27#define OV9740_MODEL_ID_LO		0x0001
28#define OV9740_REVISION_NUMBER		0x0002
29#define OV9740_MANUFACTURER_ID		0x0003
30#define OV9740_SMIA_VERSION		0x0004
31
32/* General Setup Registers */
33#define OV9740_MODE_SELECT		0x0100
34#define OV9740_IMAGE_ORT		0x0101
35#define OV9740_SOFTWARE_RESET		0x0103
36#define OV9740_GRP_PARAM_HOLD		0x0104
37#define OV9740_MSK_CORRUP_FM		0x0105
38
39/* Timing Setting */
40#define OV9740_FRM_LENGTH_LN_HI		0x0340 /* VTS */
41#define OV9740_FRM_LENGTH_LN_LO		0x0341 /* VTS */
42#define OV9740_LN_LENGTH_PCK_HI		0x0342 /* HTS */
43#define OV9740_LN_LENGTH_PCK_LO		0x0343 /* HTS */
44#define OV9740_X_ADDR_START_HI		0x0344
45#define OV9740_X_ADDR_START_LO		0x0345
46#define OV9740_Y_ADDR_START_HI		0x0346
47#define OV9740_Y_ADDR_START_LO		0x0347
48#define OV9740_X_ADDR_END_HI		0x0348
49#define OV9740_X_ADDR_END_LO		0x0349
50#define OV9740_Y_ADDR_END_HI		0x034a
51#define OV9740_Y_ADDR_END_LO		0x034b
52#define OV9740_X_OUTPUT_SIZE_HI		0x034c
53#define OV9740_X_OUTPUT_SIZE_LO		0x034d
54#define OV9740_Y_OUTPUT_SIZE_HI		0x034e
55#define OV9740_Y_OUTPUT_SIZE_LO		0x034f
56
57/* IO Control Registers */
58#define OV9740_IO_CREL00		0x3002
59#define OV9740_IO_CREL01		0x3004
60#define OV9740_IO_CREL02		0x3005
61#define OV9740_IO_OUTPUT_SEL01		0x3026
62#define OV9740_IO_OUTPUT_SEL02		0x3027
63
64/* AWB Registers */
65#define OV9740_AWB_MANUAL_CTRL		0x3406
66
67/* Analog Control Registers */
68#define OV9740_ANALOG_CTRL01		0x3601
69#define OV9740_ANALOG_CTRL02		0x3602
70#define OV9740_ANALOG_CTRL03		0x3603
71#define OV9740_ANALOG_CTRL04		0x3604
72#define OV9740_ANALOG_CTRL10		0x3610
73#define OV9740_ANALOG_CTRL12		0x3612
74#define OV9740_ANALOG_CTRL15		0x3615
75#define OV9740_ANALOG_CTRL20		0x3620
76#define OV9740_ANALOG_CTRL21		0x3621
77#define OV9740_ANALOG_CTRL22		0x3622
78#define OV9740_ANALOG_CTRL30		0x3630
79#define OV9740_ANALOG_CTRL31		0x3631
80#define OV9740_ANALOG_CTRL32		0x3632
81#define OV9740_ANALOG_CTRL33		0x3633
82
83/* Sensor Control */
84#define OV9740_SENSOR_CTRL03		0x3703
85#define OV9740_SENSOR_CTRL04		0x3704
86#define OV9740_SENSOR_CTRL05		0x3705
87#define OV9740_SENSOR_CTRL07		0x3707
88
89/* Timing Control */
90#define OV9740_TIMING_CTRL17		0x3817
91#define OV9740_TIMING_CTRL19		0x3819
92#define OV9740_TIMING_CTRL33		0x3833
93#define OV9740_TIMING_CTRL35		0x3835
94
95/* Banding Filter */
96#define OV9740_AEC_MAXEXPO_60_H		0x3a02
97#define OV9740_AEC_MAXEXPO_60_L		0x3a03
98#define OV9740_AEC_B50_STEP_HI		0x3a08
99#define OV9740_AEC_B50_STEP_LO		0x3a09
100#define OV9740_AEC_B60_STEP_HI		0x3a0a
101#define OV9740_AEC_B60_STEP_LO		0x3a0b
102#define OV9740_AEC_CTRL0D		0x3a0d
103#define OV9740_AEC_CTRL0E		0x3a0e
104#define OV9740_AEC_MAXEXPO_50_H		0x3a14
105#define OV9740_AEC_MAXEXPO_50_L		0x3a15
106
107/* AEC/AGC Control */
108#define OV9740_AEC_ENABLE		0x3503
109#define OV9740_GAIN_CEILING_01		0x3a18
110#define OV9740_GAIN_CEILING_02		0x3a19
111#define OV9740_AEC_HI_THRESHOLD		0x3a11
112#define OV9740_AEC_3A1A			0x3a1a
113#define OV9740_AEC_CTRL1B_WPT2		0x3a1b
114#define OV9740_AEC_CTRL0F_WPT		0x3a0f
115#define OV9740_AEC_CTRL10_BPT		0x3a10
116#define OV9740_AEC_CTRL1E_BPT2		0x3a1e
117#define OV9740_AEC_LO_THRESHOLD		0x3a1f
118
119/* BLC Control */
120#define OV9740_BLC_AUTO_ENABLE		0x4002
121#define OV9740_BLC_MODE			0x4005
122
123/* VFIFO */
124#define OV9740_VFIFO_READ_START_HI	0x4608
125#define OV9740_VFIFO_READ_START_LO	0x4609
126
127/* DVP Control */
128#define OV9740_DVP_VSYNC_CTRL02		0x4702
129#define OV9740_DVP_VSYNC_MODE		0x4704
130#define OV9740_DVP_VSYNC_CTRL06		0x4706
131
132/* PLL Setting */
133#define OV9740_PLL_MODE_CTRL01		0x3104
134#define OV9740_PRE_PLL_CLK_DIV		0x0305
135#define OV9740_PLL_MULTIPLIER		0x0307
136#define OV9740_VT_SYS_CLK_DIV		0x0303
137#define OV9740_VT_PIX_CLK_DIV		0x0301
138#define OV9740_PLL_CTRL3010		0x3010
139#define OV9740_VFIFO_CTRL00		0x460e
140
141/* ISP Control */
142#define OV9740_ISP_CTRL00		0x5000
143#define OV9740_ISP_CTRL01		0x5001
144#define OV9740_ISP_CTRL03		0x5003
145#define OV9740_ISP_CTRL05		0x5005
146#define OV9740_ISP_CTRL12		0x5012
147#define OV9740_ISP_CTRL19		0x5019
148#define OV9740_ISP_CTRL1A		0x501a
149#define OV9740_ISP_CTRL1E		0x501e
150#define OV9740_ISP_CTRL1F		0x501f
151#define OV9740_ISP_CTRL20		0x5020
152#define OV9740_ISP_CTRL21		0x5021
153
154/* AWB */
155#define OV9740_AWB_CTRL00		0x5180
156#define OV9740_AWB_CTRL01		0x5181
157#define OV9740_AWB_CTRL02		0x5182
158#define OV9740_AWB_CTRL03		0x5183
159#define OV9740_AWB_ADV_CTRL01		0x5184
160#define OV9740_AWB_ADV_CTRL02		0x5185
161#define OV9740_AWB_ADV_CTRL03		0x5186
162#define OV9740_AWB_ADV_CTRL04		0x5187
163#define OV9740_AWB_ADV_CTRL05		0x5188
164#define OV9740_AWB_ADV_CTRL06		0x5189
165#define OV9740_AWB_ADV_CTRL07		0x518a
166#define OV9740_AWB_ADV_CTRL08		0x518b
167#define OV9740_AWB_ADV_CTRL09		0x518c
168#define OV9740_AWB_ADV_CTRL10		0x518d
169#define OV9740_AWB_ADV_CTRL11		0x518e
170#define OV9740_AWB_CTRL0F		0x518f
171#define OV9740_AWB_CTRL10		0x5190
172#define OV9740_AWB_CTRL11		0x5191
173#define OV9740_AWB_CTRL12		0x5192
174#define OV9740_AWB_CTRL13		0x5193
175#define OV9740_AWB_CTRL14		0x5194
176
177/* MIPI Control */
178#define OV9740_MIPI_CTRL00		0x4800
179#define OV9740_MIPI_3837		0x3837
180#define OV9740_MIPI_CTRL01		0x4801
181#define OV9740_MIPI_CTRL03		0x4803
182#define OV9740_MIPI_CTRL05		0x4805
183#define OV9740_VFIFO_RD_CTRL		0x4601
184#define OV9740_MIPI_CTRL_3012		0x3012
185#define OV9740_SC_CMMM_MIPI_CTR		0x3014
186
187#define OV9740_MAX_WIDTH		1280
188#define OV9740_MAX_HEIGHT		720
189
190/* Misc. structures */
191struct ov9740_reg {
192	u16				reg;
193	u8				val;
194};
195
196struct ov9740_priv {
197	struct v4l2_subdev		subdev;
198	struct v4l2_ctrl_handler	hdl;
199	struct v4l2_clk			*clk;
200
201	u16				model;
202	u8				revision;
203	u8				manid;
204	u8				smiaver;
205
206	bool				flag_vflip;
207	bool				flag_hflip;
208
209	/* For suspend/resume. */
210	struct v4l2_mbus_framefmt	current_mf;
211	bool				current_enable;
212};
213
214static const struct ov9740_reg ov9740_defaults[] = {
215	/* Software Reset */
216	{ OV9740_SOFTWARE_RESET,	0x01 },
217
218	/* Banding Filter */
219	{ OV9740_AEC_B50_STEP_HI,	0x00 },
220	{ OV9740_AEC_B50_STEP_LO,	0xe8 },
221	{ OV9740_AEC_CTRL0E,		0x03 },
222	{ OV9740_AEC_MAXEXPO_50_H,	0x15 },
223	{ OV9740_AEC_MAXEXPO_50_L,	0xc6 },
224	{ OV9740_AEC_B60_STEP_HI,	0x00 },
225	{ OV9740_AEC_B60_STEP_LO,	0xc0 },
226	{ OV9740_AEC_CTRL0D,		0x04 },
227	{ OV9740_AEC_MAXEXPO_60_H,	0x18 },
228	{ OV9740_AEC_MAXEXPO_60_L,	0x20 },
229
230	/* LC */
231	{ 0x5842, 0x02 }, { 0x5843, 0x5e }, { 0x5844, 0x04 }, { 0x5845, 0x32 },
232	{ 0x5846, 0x03 }, { 0x5847, 0x29 }, { 0x5848, 0x02 }, { 0x5849, 0xcc },
233
234	/* Un-documented OV9740 registers */
235	{ 0x5800, 0x29 }, { 0x5801, 0x25 }, { 0x5802, 0x20 }, { 0x5803, 0x21 },
236	{ 0x5804, 0x26 }, { 0x5805, 0x2e }, { 0x5806, 0x11 }, { 0x5807, 0x0c },
237	{ 0x5808, 0x09 }, { 0x5809, 0x0a }, { 0x580a, 0x0e }, { 0x580b, 0x16 },
238	{ 0x580c, 0x06 }, { 0x580d, 0x02 }, { 0x580e, 0x00 }, { 0x580f, 0x00 },
239	{ 0x5810, 0x04 }, { 0x5811, 0x0a }, { 0x5812, 0x05 }, { 0x5813, 0x02 },
240	{ 0x5814, 0x00 }, { 0x5815, 0x00 }, { 0x5816, 0x03 }, { 0x5817, 0x09 },
241	{ 0x5818, 0x0f }, { 0x5819, 0x0a }, { 0x581a, 0x07 }, { 0x581b, 0x08 },
242	{ 0x581c, 0x0b }, { 0x581d, 0x14 }, { 0x581e, 0x28 }, { 0x581f, 0x23 },
243	{ 0x5820, 0x1d }, { 0x5821, 0x1e }, { 0x5822, 0x24 }, { 0x5823, 0x2a },
244	{ 0x5824, 0x4f }, { 0x5825, 0x6f }, { 0x5826, 0x5f }, { 0x5827, 0x7f },
245	{ 0x5828, 0x9f }, { 0x5829, 0x5f }, { 0x582a, 0x8f }, { 0x582b, 0x9e },
246	{ 0x582c, 0x8f }, { 0x582d, 0x9f }, { 0x582e, 0x4f }, { 0x582f, 0x87 },
247	{ 0x5830, 0x86 }, { 0x5831, 0x97 }, { 0x5832, 0xae }, { 0x5833, 0x3f },
248	{ 0x5834, 0x8e }, { 0x5835, 0x7c }, { 0x5836, 0x7e }, { 0x5837, 0xaf },
249	{ 0x5838, 0x8f }, { 0x5839, 0x8f }, { 0x583a, 0x9f }, { 0x583b, 0x7f },
250	{ 0x583c, 0x5f },
251
252	/* Y Gamma */
253	{ 0x5480, 0x07 }, { 0x5481, 0x18 }, { 0x5482, 0x2c }, { 0x5483, 0x4e },
254	{ 0x5484, 0x5e }, { 0x5485, 0x6b }, { 0x5486, 0x77 }, { 0x5487, 0x82 },
255	{ 0x5488, 0x8c }, { 0x5489, 0x95 }, { 0x548a, 0xa4 }, { 0x548b, 0xb1 },
256	{ 0x548c, 0xc6 }, { 0x548d, 0xd8 }, { 0x548e, 0xe9 },
257
258	/* UV Gamma */
259	{ 0x5490, 0x0f }, { 0x5491, 0xff }, { 0x5492, 0x0d }, { 0x5493, 0x05 },
260	{ 0x5494, 0x07 }, { 0x5495, 0x1a }, { 0x5496, 0x04 }, { 0x5497, 0x01 },
261	{ 0x5498, 0x03 }, { 0x5499, 0x53 }, { 0x549a, 0x02 }, { 0x549b, 0xeb },
262	{ 0x549c, 0x02 }, { 0x549d, 0xa0 }, { 0x549e, 0x02 }, { 0x549f, 0x67 },
263	{ 0x54a0, 0x02 }, { 0x54a1, 0x3b }, { 0x54a2, 0x02 }, { 0x54a3, 0x18 },
264	{ 0x54a4, 0x01 }, { 0x54a5, 0xe7 }, { 0x54a6, 0x01 }, { 0x54a7, 0xc3 },
265	{ 0x54a8, 0x01 }, { 0x54a9, 0x94 }, { 0x54aa, 0x01 }, { 0x54ab, 0x72 },
266	{ 0x54ac, 0x01 }, { 0x54ad, 0x57 },
267
268	/* AWB */
269	{ OV9740_AWB_CTRL00,		0xf0 },
270	{ OV9740_AWB_CTRL01,		0x00 },
271	{ OV9740_AWB_CTRL02,		0x41 },
272	{ OV9740_AWB_CTRL03,		0x42 },
273	{ OV9740_AWB_ADV_CTRL01,	0x8a },
274	{ OV9740_AWB_ADV_CTRL02,	0x61 },
275	{ OV9740_AWB_ADV_CTRL03,	0xce },
276	{ OV9740_AWB_ADV_CTRL04,	0xa8 },
277	{ OV9740_AWB_ADV_CTRL05,	0x17 },
278	{ OV9740_AWB_ADV_CTRL06,	0x1f },
279	{ OV9740_AWB_ADV_CTRL07,	0x27 },
280	{ OV9740_AWB_ADV_CTRL08,	0x41 },
281	{ OV9740_AWB_ADV_CTRL09,	0x34 },
282	{ OV9740_AWB_ADV_CTRL10,	0xf0 },
283	{ OV9740_AWB_ADV_CTRL11,	0x10 },
284	{ OV9740_AWB_CTRL0F,		0xff },
285	{ OV9740_AWB_CTRL10,		0x00 },
286	{ OV9740_AWB_CTRL11,		0xff },
287	{ OV9740_AWB_CTRL12,		0x00 },
288	{ OV9740_AWB_CTRL13,		0xff },
289	{ OV9740_AWB_CTRL14,		0x00 },
290
291	/* CIP */
292	{ 0x530d, 0x12 },
293
294	/* CMX */
295	{ 0x5380, 0x01 }, { 0x5381, 0x00 }, { 0x5382, 0x00 }, { 0x5383, 0x17 },
296	{ 0x5384, 0x00 }, { 0x5385, 0x01 }, { 0x5386, 0x00 }, { 0x5387, 0x00 },
297	{ 0x5388, 0x00 }, { 0x5389, 0xe0 }, { 0x538a, 0x00 }, { 0x538b, 0x20 },
298	{ 0x538c, 0x00 }, { 0x538d, 0x00 }, { 0x538e, 0x00 }, { 0x538f, 0x16 },
299	{ 0x5390, 0x00 }, { 0x5391, 0x9c }, { 0x5392, 0x00 }, { 0x5393, 0xa0 },
300	{ 0x5394, 0x18 },
301
302	/* 50/60 Detection */
303	{ 0x3c0a, 0x9c }, { 0x3c0b, 0x3f },
304
305	/* Output Select */
306	{ OV9740_IO_OUTPUT_SEL01,	0x00 },
307	{ OV9740_IO_OUTPUT_SEL02,	0x00 },
308	{ OV9740_IO_CREL00,		0x00 },
309	{ OV9740_IO_CREL01,		0x00 },
310	{ OV9740_IO_CREL02,		0x00 },
311
312	/* AWB Control */
313	{ OV9740_AWB_MANUAL_CTRL,	0x00 },
314
315	/* Analog Control */
316	{ OV9740_ANALOG_CTRL03,		0xaa },
317	{ OV9740_ANALOG_CTRL32,		0x2f },
318	{ OV9740_ANALOG_CTRL20,		0x66 },
319	{ OV9740_ANALOG_CTRL21,		0xc0 },
320	{ OV9740_ANALOG_CTRL31,		0x52 },
321	{ OV9740_ANALOG_CTRL33,		0x50 },
322	{ OV9740_ANALOG_CTRL30,		0xca },
323	{ OV9740_ANALOG_CTRL04,		0x0c },
324	{ OV9740_ANALOG_CTRL01,		0x40 },
325	{ OV9740_ANALOG_CTRL02,		0x16 },
326	{ OV9740_ANALOG_CTRL10,		0xa1 },
327	{ OV9740_ANALOG_CTRL12,		0x24 },
328	{ OV9740_ANALOG_CTRL22,		0x9f },
329	{ OV9740_ANALOG_CTRL15,		0xf0 },
330
331	/* Sensor Control */
332	{ OV9740_SENSOR_CTRL03,		0x42 },
333	{ OV9740_SENSOR_CTRL04,		0x10 },
334	{ OV9740_SENSOR_CTRL05,		0x45 },
335	{ OV9740_SENSOR_CTRL07,		0x14 },
336
337	/* Timing Control */
338	{ OV9740_TIMING_CTRL33,		0x04 },
339	{ OV9740_TIMING_CTRL35,		0x02 },
340	{ OV9740_TIMING_CTRL19,		0x6e },
341	{ OV9740_TIMING_CTRL17,		0x94 },
342
343	/* AEC/AGC Control */
344	{ OV9740_AEC_ENABLE,		0x10 },
345	{ OV9740_GAIN_CEILING_01,	0x00 },
346	{ OV9740_GAIN_CEILING_02,	0x7f },
347	{ OV9740_AEC_HI_THRESHOLD,	0xa0 },
348	{ OV9740_AEC_3A1A,		0x05 },
349	{ OV9740_AEC_CTRL1B_WPT2,	0x50 },
350	{ OV9740_AEC_CTRL0F_WPT,	0x50 },
351	{ OV9740_AEC_CTRL10_BPT,	0x4c },
352	{ OV9740_AEC_CTRL1E_BPT2,	0x4c },
353	{ OV9740_AEC_LO_THRESHOLD,	0x26 },
354
355	/* BLC Control */
356	{ OV9740_BLC_AUTO_ENABLE,	0x45 },
357	{ OV9740_BLC_MODE,		0x18 },
358
359	/* DVP Control */
360	{ OV9740_DVP_VSYNC_CTRL02,	0x04 },
361	{ OV9740_DVP_VSYNC_MODE,	0x00 },
362	{ OV9740_DVP_VSYNC_CTRL06,	0x08 },
363
364	/* PLL Setting */
365	{ OV9740_PLL_MODE_CTRL01,	0x20 },
366	{ OV9740_PRE_PLL_CLK_DIV,	0x03 },
367	{ OV9740_PLL_MULTIPLIER,	0x4c },
368	{ OV9740_VT_SYS_CLK_DIV,	0x01 },
369	{ OV9740_VT_PIX_CLK_DIV,	0x08 },
370	{ OV9740_PLL_CTRL3010,		0x01 },
371	{ OV9740_VFIFO_CTRL00,		0x82 },
372
373	/* Timing Setting */
374	/* VTS */
375	{ OV9740_FRM_LENGTH_LN_HI,	0x03 },
376	{ OV9740_FRM_LENGTH_LN_LO,	0x07 },
377	/* HTS */
378	{ OV9740_LN_LENGTH_PCK_HI,	0x06 },
379	{ OV9740_LN_LENGTH_PCK_LO,	0x62 },
380
381	/* MIPI Control */
382	{ OV9740_MIPI_CTRL00,		0x44 }, /* 0x64 for discontinuous clk */
383	{ OV9740_MIPI_3837,		0x01 },
384	{ OV9740_MIPI_CTRL01,		0x0f },
385	{ OV9740_MIPI_CTRL03,		0x05 },
386	{ OV9740_MIPI_CTRL05,		0x10 },
387	{ OV9740_VFIFO_RD_CTRL,		0x16 },
388	{ OV9740_MIPI_CTRL_3012,	0x70 },
389	{ OV9740_SC_CMMM_MIPI_CTR,	0x01 },
390
391	/* YUYV order */
392	{ OV9740_ISP_CTRL19,		0x02 },
393};
394
395static u32 ov9740_codes[] = {
396	MEDIA_BUS_FMT_YUYV8_2X8,
397};
398
399/* read a register */
400static int ov9740_reg_read(struct i2c_client *client, u16 reg, u8 *val)
401{
402	int ret;
403	struct i2c_msg msg[] = {
404		{
405			.addr	= client->addr,
406			.flags	= 0,
407			.len	= 2,
408			.buf	= (u8 *)&reg,
409		},
410		{
411			.addr	= client->addr,
412			.flags	= I2C_M_RD,
413			.len	= 1,
414			.buf	= val,
415		},
416	};
417
418	reg = swab16(reg);
419
420	ret = i2c_transfer(client->adapter, msg, 2);
421	if (ret < 0) {
422		dev_err(&client->dev, "Failed reading register 0x%04x!\n", reg);
423		return ret;
424	}
425
426	return 0;
427}
428
429/* write a register */
430static int ov9740_reg_write(struct i2c_client *client, u16 reg, u8 val)
431{
432	struct i2c_msg msg;
433	struct {
434		u16 reg;
435		u8 val;
436	} __packed buf;
437	int ret;
438
439	reg = swab16(reg);
440
441	buf.reg = reg;
442	buf.val = val;
443
444	msg.addr	= client->addr;
445	msg.flags	= 0;
446	msg.len		= 3;
447	msg.buf		= (u8 *)&buf;
448
449	ret = i2c_transfer(client->adapter, &msg, 1);
450	if (ret < 0) {
451		dev_err(&client->dev, "Failed writing register 0x%04x!\n", reg);
452		return ret;
453	}
454
455	return 0;
456}
457
458
459/* Read a register, alter its bits, write it back */
460static int ov9740_reg_rmw(struct i2c_client *client, u16 reg, u8 set, u8 unset)
461{
462	u8 val;
463	int ret;
464
465	ret = ov9740_reg_read(client, reg, &val);
466	if (ret < 0) {
467		dev_err(&client->dev,
468			"[Read]-Modify-Write of register 0x%04x failed!\n",
469			reg);
470		return ret;
471	}
472
473	val |= set;
474	val &= ~unset;
475
476	ret = ov9740_reg_write(client, reg, val);
477	if (ret < 0) {
478		dev_err(&client->dev,
479			"Read-Modify-[Write] of register 0x%04x failed!\n",
480			reg);
481		return ret;
482	}
483
484	return 0;
485}
486
487static int ov9740_reg_write_array(struct i2c_client *client,
488				  const struct ov9740_reg *regarray,
489				  int regarraylen)
490{
491	int i;
492	int ret;
493
494	for (i = 0; i < regarraylen; i++) {
495		ret = ov9740_reg_write(client,
496				       regarray[i].reg, regarray[i].val);
497		if (ret < 0)
498			return ret;
499	}
500
501	return 0;
502}
503
504/* Start/Stop streaming from the device */
505static int ov9740_s_stream(struct v4l2_subdev *sd, int enable)
506{
507	struct i2c_client *client = v4l2_get_subdevdata(sd);
508	struct ov9740_priv *priv = to_ov9740(sd);
509	int ret;
510
511	/* Program orientation register. */
512	if (priv->flag_vflip)
513		ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0x2, 0);
514	else
515		ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0, 0x2);
516	if (ret < 0)
517		return ret;
518
519	if (priv->flag_hflip)
520		ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0x1, 0);
521	else
522		ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0, 0x1);
523	if (ret < 0)
524		return ret;
525
526	if (enable) {
527		dev_dbg(&client->dev, "Enabling Streaming\n");
528		/* Start Streaming */
529		ret = ov9740_reg_write(client, OV9740_MODE_SELECT, 0x01);
530
531	} else {
532		dev_dbg(&client->dev, "Disabling Streaming\n");
533		/* Software Reset */
534		ret = ov9740_reg_write(client, OV9740_SOFTWARE_RESET, 0x01);
535		if (!ret)
536			/* Setting Streaming to Standby */
537			ret = ov9740_reg_write(client, OV9740_MODE_SELECT,
538					       0x00);
539	}
540
541	priv->current_enable = enable;
542
543	return ret;
544}
545
546/* select nearest higher resolution for capture */
547static void ov9740_res_roundup(u32 *width, u32 *height)
548{
549	/* Width must be a multiple of 4 pixels. */
550	*width = ALIGN(*width, 4);
551
552	/* Max resolution is 1280x720 (720p). */
553	if (*width > OV9740_MAX_WIDTH)
554		*width = OV9740_MAX_WIDTH;
555
556	if (*height > OV9740_MAX_HEIGHT)
557		*height = OV9740_MAX_HEIGHT;
558}
559
560/* Setup registers according to resolution and color encoding */
561static int ov9740_set_res(struct i2c_client *client, u32 width, u32 height)
562{
563	u32 x_start;
564	u32 y_start;
565	u32 x_end;
566	u32 y_end;
567	bool scaling = false;
568	u32 scale_input_x;
569	u32 scale_input_y;
570	int ret;
571
572	if ((width != OV9740_MAX_WIDTH) || (height != OV9740_MAX_HEIGHT))
573		scaling = true;
574
575	/*
576	 * Try to use as much of the sensor area as possible when supporting
577	 * smaller resolutions.  Depending on the aspect ratio of the
578	 * chosen resolution, we can either use the full width of the sensor,
579	 * or the full height of the sensor (or both if the aspect ratio is
580	 * the same as 1280x720.
581	 */
582	if ((OV9740_MAX_WIDTH * height) > (OV9740_MAX_HEIGHT * width)) {
583		scale_input_x = (OV9740_MAX_HEIGHT * width) / height;
584		scale_input_y = OV9740_MAX_HEIGHT;
585	} else {
586		scale_input_x = OV9740_MAX_WIDTH;
587		scale_input_y = (OV9740_MAX_WIDTH * height) / width;
588	}
589
590	/* These describe the area of the sensor to use. */
591	x_start = (OV9740_MAX_WIDTH - scale_input_x) / 2;
592	y_start = (OV9740_MAX_HEIGHT - scale_input_y) / 2;
593	x_end = x_start + scale_input_x - 1;
594	y_end = y_start + scale_input_y - 1;
595
596	ret = ov9740_reg_write(client, OV9740_X_ADDR_START_HI, x_start >> 8);
597	if (ret)
598		goto done;
599	ret = ov9740_reg_write(client, OV9740_X_ADDR_START_LO, x_start & 0xff);
600	if (ret)
601		goto done;
602	ret = ov9740_reg_write(client, OV9740_Y_ADDR_START_HI, y_start >> 8);
603	if (ret)
604		goto done;
605	ret = ov9740_reg_write(client, OV9740_Y_ADDR_START_LO, y_start & 0xff);
606	if (ret)
607		goto done;
608
609	ret = ov9740_reg_write(client, OV9740_X_ADDR_END_HI, x_end >> 8);
610	if (ret)
611		goto done;
612	ret = ov9740_reg_write(client, OV9740_X_ADDR_END_LO, x_end & 0xff);
613	if (ret)
614		goto done;
615	ret = ov9740_reg_write(client, OV9740_Y_ADDR_END_HI, y_end >> 8);
616	if (ret)
617		goto done;
618	ret = ov9740_reg_write(client, OV9740_Y_ADDR_END_LO, y_end & 0xff);
619	if (ret)
620		goto done;
621
622	ret = ov9740_reg_write(client, OV9740_X_OUTPUT_SIZE_HI, width >> 8);
623	if (ret)
624		goto done;
625	ret = ov9740_reg_write(client, OV9740_X_OUTPUT_SIZE_LO, width & 0xff);
626	if (ret)
627		goto done;
628	ret = ov9740_reg_write(client, OV9740_Y_OUTPUT_SIZE_HI, height >> 8);
629	if (ret)
630		goto done;
631	ret = ov9740_reg_write(client, OV9740_Y_OUTPUT_SIZE_LO, height & 0xff);
632	if (ret)
633		goto done;
634
635	ret = ov9740_reg_write(client, OV9740_ISP_CTRL1E, scale_input_x >> 8);
636	if (ret)
637		goto done;
638	ret = ov9740_reg_write(client, OV9740_ISP_CTRL1F, scale_input_x & 0xff);
639	if (ret)
640		goto done;
641	ret = ov9740_reg_write(client, OV9740_ISP_CTRL20, scale_input_y >> 8);
642	if (ret)
643		goto done;
644	ret = ov9740_reg_write(client, OV9740_ISP_CTRL21, scale_input_y & 0xff);
645	if (ret)
646		goto done;
647
648	ret = ov9740_reg_write(client, OV9740_VFIFO_READ_START_HI,
649			       (scale_input_x - width) >> 8);
650	if (ret)
651		goto done;
652	ret = ov9740_reg_write(client, OV9740_VFIFO_READ_START_LO,
653			       (scale_input_x - width) & 0xff);
654	if (ret)
655		goto done;
656
657	ret = ov9740_reg_write(client, OV9740_ISP_CTRL00, 0xff);
658	if (ret)
659		goto done;
660	ret = ov9740_reg_write(client, OV9740_ISP_CTRL01, 0xef |
661							  (scaling << 4));
662	if (ret)
663		goto done;
664	ret = ov9740_reg_write(client, OV9740_ISP_CTRL03, 0xff);
665
666done:
667	return ret;
668}
669
670/* set the format we will capture in */
671static int ov9740_s_fmt(struct v4l2_subdev *sd,
672			struct v4l2_mbus_framefmt *mf)
673{
674	struct i2c_client *client = v4l2_get_subdevdata(sd);
675	struct ov9740_priv *priv = to_ov9740(sd);
676	enum v4l2_colorspace cspace;
677	u32 code = mf->code;
678	int ret;
679
680	ov9740_res_roundup(&mf->width, &mf->height);
681
682	switch (code) {
683	case MEDIA_BUS_FMT_YUYV8_2X8:
684		cspace = V4L2_COLORSPACE_SRGB;
685		break;
686	default:
687		return -EINVAL;
688	}
689
690	ret = ov9740_reg_write_array(client, ov9740_defaults,
691				     ARRAY_SIZE(ov9740_defaults));
692	if (ret < 0)
693		return ret;
694
695	ret = ov9740_set_res(client, mf->width, mf->height);
696	if (ret < 0)
697		return ret;
698
699	mf->code	= code;
700	mf->colorspace	= cspace;
701
702	memcpy(&priv->current_mf, mf, sizeof(struct v4l2_mbus_framefmt));
703
704	return ret;
705}
706
707static int ov9740_try_fmt(struct v4l2_subdev *sd,
708			  struct v4l2_mbus_framefmt *mf)
709{
710	ov9740_res_roundup(&mf->width, &mf->height);
711
712	mf->field = V4L2_FIELD_NONE;
713	mf->code = MEDIA_BUS_FMT_YUYV8_2X8;
714	mf->colorspace = V4L2_COLORSPACE_SRGB;
715
716	return 0;
717}
718
719static int ov9740_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
720			   u32 *code)
721{
722	if (index >= ARRAY_SIZE(ov9740_codes))
723		return -EINVAL;
724
725	*code = ov9740_codes[index];
726
727	return 0;
728}
729
730static int ov9740_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
731{
732	a->bounds.left		= 0;
733	a->bounds.top		= 0;
734	a->bounds.width		= OV9740_MAX_WIDTH;
735	a->bounds.height	= OV9740_MAX_HEIGHT;
736	a->defrect		= a->bounds;
737	a->type			= V4L2_BUF_TYPE_VIDEO_CAPTURE;
738	a->pixelaspect.numerator	= 1;
739	a->pixelaspect.denominator	= 1;
740
741	return 0;
742}
743
744static int ov9740_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
745{
746	a->c.left		= 0;
747	a->c.top		= 0;
748	a->c.width		= OV9740_MAX_WIDTH;
749	a->c.height		= OV9740_MAX_HEIGHT;
750	a->type			= V4L2_BUF_TYPE_VIDEO_CAPTURE;
751
752	return 0;
753}
754
755/* Set status of additional camera capabilities */
756static int ov9740_s_ctrl(struct v4l2_ctrl *ctrl)
757{
758	struct ov9740_priv *priv =
759		container_of(ctrl->handler, struct ov9740_priv, hdl);
760
761	switch (ctrl->id) {
762	case V4L2_CID_VFLIP:
763		priv->flag_vflip = ctrl->val;
764		break;
765	case V4L2_CID_HFLIP:
766		priv->flag_hflip = ctrl->val;
767		break;
768	default:
769		return -EINVAL;
770	}
771
772	return 0;
773}
774
775static int ov9740_s_power(struct v4l2_subdev *sd, int on)
776{
777	struct i2c_client *client = v4l2_get_subdevdata(sd);
778	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
779	struct ov9740_priv *priv = to_ov9740(sd);
780	int ret;
781
782	if (on) {
783		ret = soc_camera_power_on(&client->dev, ssdd, priv->clk);
784		if (ret < 0)
785			return ret;
786
787		if (priv->current_enable) {
788			ov9740_s_fmt(sd, &priv->current_mf);
789			ov9740_s_stream(sd, 1);
790		}
791	} else {
792		if (priv->current_enable) {
793			ov9740_s_stream(sd, 0);
794			priv->current_enable = true;
795		}
796
797		soc_camera_power_off(&client->dev, ssdd, priv->clk);
798	}
799
800	return 0;
801}
802
803#ifdef CONFIG_VIDEO_ADV_DEBUG
804static int ov9740_get_register(struct v4l2_subdev *sd,
805			       struct v4l2_dbg_register *reg)
806{
807	struct i2c_client *client = v4l2_get_subdevdata(sd);
808	int ret;
809	u8 val;
810
811	if (reg->reg & ~0xffff)
812		return -EINVAL;
813
814	reg->size = 2;
815
816	ret = ov9740_reg_read(client, reg->reg, &val);
817	if (ret)
818		return ret;
819
820	reg->val = (__u64)val;
821
822	return ret;
823}
824
825static int ov9740_set_register(struct v4l2_subdev *sd,
826			       const struct v4l2_dbg_register *reg)
827{
828	struct i2c_client *client = v4l2_get_subdevdata(sd);
829
830	if (reg->reg & ~0xffff || reg->val & ~0xff)
831		return -EINVAL;
832
833	return ov9740_reg_write(client, reg->reg, reg->val);
834}
835#endif
836
837static int ov9740_video_probe(struct i2c_client *client)
838{
839	struct v4l2_subdev *sd = i2c_get_clientdata(client);
840	struct ov9740_priv *priv = to_ov9740(sd);
841	u8 modelhi, modello;
842	int ret;
843
844	ret = ov9740_s_power(&priv->subdev, 1);
845	if (ret < 0)
846		return ret;
847
848	/*
849	 * check and show product ID and manufacturer ID
850	 */
851	ret = ov9740_reg_read(client, OV9740_MODEL_ID_HI, &modelhi);
852	if (ret < 0)
853		goto done;
854
855	ret = ov9740_reg_read(client, OV9740_MODEL_ID_LO, &modello);
856	if (ret < 0)
857		goto done;
858
859	priv->model = (modelhi << 8) | modello;
860
861	ret = ov9740_reg_read(client, OV9740_REVISION_NUMBER, &priv->revision);
862	if (ret < 0)
863		goto done;
864
865	ret = ov9740_reg_read(client, OV9740_MANUFACTURER_ID, &priv->manid);
866	if (ret < 0)
867		goto done;
868
869	ret = ov9740_reg_read(client, OV9740_SMIA_VERSION, &priv->smiaver);
870	if (ret < 0)
871		goto done;
872
873	if (priv->model != 0x9740) {
874		ret = -ENODEV;
875		goto done;
876	}
877
878	dev_info(&client->dev, "ov9740 Model ID 0x%04x, Revision 0x%02x, "
879		 "Manufacturer 0x%02x, SMIA Version 0x%02x\n",
880		 priv->model, priv->revision, priv->manid, priv->smiaver);
881
882	ret = v4l2_ctrl_handler_setup(&priv->hdl);
883
884done:
885	ov9740_s_power(&priv->subdev, 0);
886	return ret;
887}
888
889/* Request bus settings on camera side */
890static int ov9740_g_mbus_config(struct v4l2_subdev *sd,
891				struct v4l2_mbus_config *cfg)
892{
893	struct i2c_client *client = v4l2_get_subdevdata(sd);
894	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
895
896	cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
897		V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
898		V4L2_MBUS_DATA_ACTIVE_HIGH;
899	cfg->type = V4L2_MBUS_PARALLEL;
900	cfg->flags = soc_camera_apply_board_flags(ssdd, cfg);
901
902	return 0;
903}
904
905static struct v4l2_subdev_video_ops ov9740_video_ops = {
906	.s_stream	= ov9740_s_stream,
907	.s_mbus_fmt	= ov9740_s_fmt,
908	.try_mbus_fmt	= ov9740_try_fmt,
909	.enum_mbus_fmt	= ov9740_enum_fmt,
910	.cropcap	= ov9740_cropcap,
911	.g_crop		= ov9740_g_crop,
912	.g_mbus_config	= ov9740_g_mbus_config,
913};
914
915static struct v4l2_subdev_core_ops ov9740_core_ops = {
916	.s_power		= ov9740_s_power,
917#ifdef CONFIG_VIDEO_ADV_DEBUG
918	.g_register		= ov9740_get_register,
919	.s_register		= ov9740_set_register,
920#endif
921};
922
923static struct v4l2_subdev_ops ov9740_subdev_ops = {
924	.core			= &ov9740_core_ops,
925	.video			= &ov9740_video_ops,
926};
927
928static const struct v4l2_ctrl_ops ov9740_ctrl_ops = {
929	.s_ctrl = ov9740_s_ctrl,
930};
931
932/*
933 * i2c_driver function
934 */
935static int ov9740_probe(struct i2c_client *client,
936			const struct i2c_device_id *did)
937{
938	struct ov9740_priv *priv;
939	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
940	int ret;
941
942	if (!ssdd) {
943		dev_err(&client->dev, "Missing platform_data for driver\n");
944		return -EINVAL;
945	}
946
947	priv = devm_kzalloc(&client->dev, sizeof(struct ov9740_priv), GFP_KERNEL);
948	if (!priv) {
949		dev_err(&client->dev, "Failed to allocate private data!\n");
950		return -ENOMEM;
951	}
952
953	v4l2_i2c_subdev_init(&priv->subdev, client, &ov9740_subdev_ops);
954	v4l2_ctrl_handler_init(&priv->hdl, 13);
955	v4l2_ctrl_new_std(&priv->hdl, &ov9740_ctrl_ops,
956			V4L2_CID_VFLIP, 0, 1, 1, 0);
957	v4l2_ctrl_new_std(&priv->hdl, &ov9740_ctrl_ops,
958			V4L2_CID_HFLIP, 0, 1, 1, 0);
959	priv->subdev.ctrl_handler = &priv->hdl;
960	if (priv->hdl.error)
961		return priv->hdl.error;
962
963	priv->clk = v4l2_clk_get(&client->dev, "mclk");
964	if (IS_ERR(priv->clk)) {
965		ret = PTR_ERR(priv->clk);
966		goto eclkget;
967	}
968
969	ret = ov9740_video_probe(client);
970	if (ret < 0) {
971		v4l2_clk_put(priv->clk);
972eclkget:
973		v4l2_ctrl_handler_free(&priv->hdl);
974	}
975
976	return ret;
977}
978
979static int ov9740_remove(struct i2c_client *client)
980{
981	struct ov9740_priv *priv = i2c_get_clientdata(client);
982
983	v4l2_clk_put(priv->clk);
984	v4l2_device_unregister_subdev(&priv->subdev);
985	v4l2_ctrl_handler_free(&priv->hdl);
986	return 0;
987}
988
989static const struct i2c_device_id ov9740_id[] = {
990	{ "ov9740", 0 },
991	{ }
992};
993MODULE_DEVICE_TABLE(i2c, ov9740_id);
994
995static struct i2c_driver ov9740_i2c_driver = {
996	.driver = {
997		.name = "ov9740",
998	},
999	.probe    = ov9740_probe,
1000	.remove   = ov9740_remove,
1001	.id_table = ov9740_id,
1002};
1003
1004module_i2c_driver(ov9740_i2c_driver);
1005
1006MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV9740");
1007MODULE_AUTHOR("Andrew Chew <achew@nvidia.com>");
1008MODULE_LICENSE("GPL v2");
1009