1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Support for GalaxyCore GC0310 VGA camera sensor.
4  *
5  * Copyright (c) 2013 Intel Corporation. All Rights Reserved.
6  * Copyright (c) 2023 Hans de Goede <hdegoede@redhat.com>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License version
10  * 2 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  */
18 
19 #include <linux/module.h>
20 #include <linux/types.h>
21 #include <linux/kernel.h>
22 #include <linux/mm.h>
23 #include <linux/string.h>
24 #include <linux/errno.h>
25 #include <linux/init.h>
26 #include <linux/kmod.h>
27 #include <linux/device.h>
28 #include <linux/delay.h>
29 #include <linux/slab.h>
30 #include <linux/gpio/consumer.h>
31 #include <linux/gpio/machine.h>
32 #include <linux/i2c.h>
33 #include <linux/moduleparam.h>
34 #include <linux/pm_runtime.h>
35 #include <media/v4l2-device.h>
36 #include <linux/io.h>
37 #include "../include/linux/atomisp_gmin_platform.h"
38 
39 #include "gc0310.h"
40 
41 /*
42  * gc0310_write_reg_array - Initializes a list of GC0310 registers
43  * @client: i2c driver client structure
44  * @reglist: list of registers to be written
45  * @count: number of register, value pairs in the list
46  */
47 static int gc0310_write_reg_array(struct i2c_client *client,
48 				  const struct gc0310_reg *reglist, int count)
49 {
50 	int i, err;
51 
52 	for (i = 0; i < count; i++) {
53 		err = i2c_smbus_write_byte_data(client, reglist[i].reg, reglist[i].val);
54 		if (err) {
55 			dev_err(&client->dev, "write error: wrote 0x%x to offset 0x%x error %d",
56 				reglist[i].val, reglist[i].reg, err);
57 			return err;
58 		}
59 	}
60 
61 	return 0;
62 }
63 
64 static int gc0310_exposure_set(struct gc0310_device *dev, u32 exp)
65 {
66 	struct i2c_client *client = v4l2_get_subdevdata(&dev->sd);
67 
68 	return i2c_smbus_write_word_swapped(client, GC0310_AEC_PK_EXPO_H, exp);
69 }
70 
71 static int gc0310_gain_set(struct gc0310_device *dev, u32 gain)
72 {
73 	struct i2c_client *client = v4l2_get_subdevdata(&dev->sd);
74 	u8 again, dgain;
75 	int ret;
76 
77 	/* Taken from original driver, this never sets dgain lower then 32? */
78 
79 	/* Change 0 - 95 to 32 - 127 */
80 	gain += 32;
81 
82 	if (gain < 64) {
83 		again = 0x0; /* sqrt(2) */
84 		dgain = gain;
85 	} else {
86 		again = 0x2; /* 2 * sqrt(2) */
87 		dgain = gain / 2;
88 	}
89 
90 	ret = i2c_smbus_write_byte_data(client, GC0310_AGC_ADJ, again);
91 	if (ret)
92 		return ret;
93 
94 	return i2c_smbus_write_byte_data(client, GC0310_DGC_ADJ, dgain);
95 }
96 
97 static int gc0310_s_ctrl(struct v4l2_ctrl *ctrl)
98 {
99 	struct gc0310_device *dev =
100 		container_of(ctrl->handler, struct gc0310_device, ctrls.handler);
101 	int ret;
102 
103 	/* Only apply changes to the controls if the device is powered up */
104 	if (!pm_runtime_get_if_in_use(dev->sd.dev))
105 		return 0;
106 
107 	switch (ctrl->id) {
108 	case V4L2_CID_EXPOSURE:
109 		ret = gc0310_exposure_set(dev, ctrl->val);
110 		break;
111 	case V4L2_CID_GAIN:
112 		ret = gc0310_gain_set(dev, ctrl->val);
113 		break;
114 	default:
115 		ret = -EINVAL;
116 		break;
117 	}
118 
119 	pm_runtime_put(dev->sd.dev);
120 	return ret;
121 }
122 
123 static const struct v4l2_ctrl_ops ctrl_ops = {
124 	.s_ctrl = gc0310_s_ctrl,
125 };
126 
127 static struct v4l2_mbus_framefmt *
128 gc0310_get_pad_format(struct gc0310_device *dev,
129 		      struct v4l2_subdev_state *state,
130 		      unsigned int pad, enum v4l2_subdev_format_whence which)
131 {
132 	if (which == V4L2_SUBDEV_FORMAT_TRY)
133 		return v4l2_subdev_get_try_format(&dev->sd, state, pad);
134 
135 	return &dev->mode.fmt;
136 }
137 
138 /* The GC0310 currently only supports 1 fixed fmt */
139 static void gc0310_fill_format(struct v4l2_mbus_framefmt *fmt)
140 {
141 	memset(fmt, 0, sizeof(*fmt));
142 	fmt->width = GC0310_NATIVE_WIDTH;
143 	fmt->height = GC0310_NATIVE_HEIGHT;
144 	fmt->field = V4L2_FIELD_NONE;
145 	fmt->code = MEDIA_BUS_FMT_SGRBG8_1X8;
146 }
147 
148 static int gc0310_set_fmt(struct v4l2_subdev *sd,
149 			  struct v4l2_subdev_state *sd_state,
150 			  struct v4l2_subdev_format *format)
151 {
152 	struct gc0310_device *dev = to_gc0310_sensor(sd);
153 	struct v4l2_mbus_framefmt *fmt;
154 
155 	fmt = gc0310_get_pad_format(dev, sd_state, format->pad, format->which);
156 	gc0310_fill_format(fmt);
157 
158 	format->format = *fmt;
159 	return 0;
160 }
161 
162 static int gc0310_get_fmt(struct v4l2_subdev *sd,
163 			  struct v4l2_subdev_state *sd_state,
164 			  struct v4l2_subdev_format *format)
165 {
166 	struct gc0310_device *dev = to_gc0310_sensor(sd);
167 	struct v4l2_mbus_framefmt *fmt;
168 
169 	fmt = gc0310_get_pad_format(dev, sd_state, format->pad, format->which);
170 	format->format = *fmt;
171 	return 0;
172 }
173 
174 static int gc0310_detect(struct i2c_client *client)
175 {
176 	struct i2c_adapter *adapter = client->adapter;
177 	int ret;
178 
179 	if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
180 		return -ENODEV;
181 
182 	ret = i2c_smbus_read_word_swapped(client, GC0310_SC_CMMN_CHIP_ID_H);
183 	if (ret < 0) {
184 		dev_err(&client->dev, "read sensor_id failed: %d\n", ret);
185 		return -ENODEV;
186 	}
187 
188 	dev_dbg(&client->dev, "sensor ID = 0x%x\n", ret);
189 
190 	if (ret != GC0310_ID) {
191 		dev_err(&client->dev, "sensor ID error, read id = 0x%x, target id = 0x%x\n",
192 			ret, GC0310_ID);
193 		return -ENODEV;
194 	}
195 
196 	dev_dbg(&client->dev, "detect gc0310 success\n");
197 
198 	return 0;
199 }
200 
201 static int gc0310_s_stream(struct v4l2_subdev *sd, int enable)
202 {
203 	struct gc0310_device *dev = to_gc0310_sensor(sd);
204 	struct i2c_client *client = v4l2_get_subdevdata(sd);
205 	int ret = 0;
206 
207 	dev_dbg(&client->dev, "%s S enable=%d\n", __func__, enable);
208 	mutex_lock(&dev->input_lock);
209 
210 	if (dev->is_streaming == enable) {
211 		dev_warn(&client->dev, "stream already %s\n", enable ? "started" : "stopped");
212 		goto error_unlock;
213 	}
214 
215 	if (enable) {
216 		ret = pm_runtime_get_sync(&client->dev);
217 		if (ret < 0)
218 			goto error_power_down;
219 
220 		msleep(100);
221 
222 		ret = gc0310_write_reg_array(client, gc0310_reset_register,
223 					     ARRAY_SIZE(gc0310_reset_register));
224 		if (ret)
225 			goto error_power_down;
226 
227 		ret = gc0310_write_reg_array(client, gc0310_VGA_30fps,
228 					     ARRAY_SIZE(gc0310_VGA_30fps));
229 		if (ret)
230 			goto error_power_down;
231 
232 		/* restore value of all ctrls */
233 		ret = __v4l2_ctrl_handler_setup(&dev->ctrls.handler);
234 		if (ret)
235 			goto error_power_down;
236 
237 		/* enable per frame MIPI and sensor ctrl reset  */
238 		ret = i2c_smbus_write_byte_data(client, 0xFE, 0x30);
239 		if (ret)
240 			goto error_power_down;
241 	}
242 
243 	ret = i2c_smbus_write_byte_data(client, GC0310_RESET_RELATED, GC0310_REGISTER_PAGE_3);
244 	if (ret)
245 		goto error_power_down;
246 
247 	ret = i2c_smbus_write_byte_data(client, GC0310_SW_STREAM,
248 					enable ? GC0310_START_STREAMING : GC0310_STOP_STREAMING);
249 	if (ret)
250 		goto error_power_down;
251 
252 	ret = i2c_smbus_write_byte_data(client, GC0310_RESET_RELATED, GC0310_REGISTER_PAGE_0);
253 	if (ret)
254 		goto error_power_down;
255 
256 	if (!enable)
257 		pm_runtime_put(&client->dev);
258 
259 	dev->is_streaming = enable;
260 	mutex_unlock(&dev->input_lock);
261 	return 0;
262 
263 error_power_down:
264 	pm_runtime_put(&client->dev);
265 	dev->is_streaming = false;
266 error_unlock:
267 	mutex_unlock(&dev->input_lock);
268 	return ret;
269 }
270 
271 static int gc0310_s_config(struct v4l2_subdev *sd)
272 {
273 	struct i2c_client *client = v4l2_get_subdevdata(sd);
274 	int ret;
275 
276 	ret = pm_runtime_get_sync(&client->dev);
277 	if (ret >= 0)
278 		ret = gc0310_detect(client);
279 
280 	pm_runtime_put(&client->dev);
281 	return ret;
282 }
283 
284 static int gc0310_g_frame_interval(struct v4l2_subdev *sd,
285 				   struct v4l2_subdev_frame_interval *interval)
286 {
287 	interval->interval.numerator = 1;
288 	interval->interval.denominator = GC0310_FPS;
289 
290 	return 0;
291 }
292 
293 static int gc0310_enum_mbus_code(struct v4l2_subdev *sd,
294 				 struct v4l2_subdev_state *sd_state,
295 				 struct v4l2_subdev_mbus_code_enum *code)
296 {
297 	/* We support only a single format */
298 	if (code->index)
299 		return -EINVAL;
300 
301 	code->code = MEDIA_BUS_FMT_SGRBG8_1X8;
302 	return 0;
303 }
304 
305 static int gc0310_enum_frame_size(struct v4l2_subdev *sd,
306 				  struct v4l2_subdev_state *sd_state,
307 				  struct v4l2_subdev_frame_size_enum *fse)
308 {
309 	/* We support only a single resolution */
310 	if (fse->index)
311 		return -EINVAL;
312 
313 	fse->min_width = GC0310_NATIVE_WIDTH;
314 	fse->max_width = GC0310_NATIVE_WIDTH;
315 	fse->min_height = GC0310_NATIVE_HEIGHT;
316 	fse->max_height = GC0310_NATIVE_HEIGHT;
317 
318 	return 0;
319 }
320 
321 static int gc0310_g_skip_frames(struct v4l2_subdev *sd, u32 *frames)
322 {
323 	*frames = GC0310_SKIP_FRAMES;
324 	return 0;
325 }
326 
327 static const struct v4l2_subdev_sensor_ops gc0310_sensor_ops = {
328 	.g_skip_frames	= gc0310_g_skip_frames,
329 };
330 
331 static const struct v4l2_subdev_video_ops gc0310_video_ops = {
332 	.s_stream = gc0310_s_stream,
333 	.g_frame_interval = gc0310_g_frame_interval,
334 };
335 
336 static const struct v4l2_subdev_pad_ops gc0310_pad_ops = {
337 	.enum_mbus_code = gc0310_enum_mbus_code,
338 	.enum_frame_size = gc0310_enum_frame_size,
339 	.get_fmt = gc0310_get_fmt,
340 	.set_fmt = gc0310_set_fmt,
341 };
342 
343 static const struct v4l2_subdev_ops gc0310_ops = {
344 	.video = &gc0310_video_ops,
345 	.pad = &gc0310_pad_ops,
346 	.sensor = &gc0310_sensor_ops,
347 };
348 
349 static int gc0310_init_controls(struct gc0310_device *dev)
350 {
351 	struct v4l2_ctrl_handler *hdl = &dev->ctrls.handler;
352 
353 	v4l2_ctrl_handler_init(hdl, 2);
354 
355 	/* Use the same lock for controls as for everything else */
356 	hdl->lock = &dev->input_lock;
357 	dev->sd.ctrl_handler = hdl;
358 
359 	dev->ctrls.exposure =
360 		v4l2_ctrl_new_std(hdl, &ctrl_ops, V4L2_CID_EXPOSURE, 0, 4095, 1, 1023);
361 
362 	/* 32 steps at base gain 1 + 64 half steps at base gain 2 */
363 	dev->ctrls.gain =
364 		v4l2_ctrl_new_std(hdl, &ctrl_ops, V4L2_CID_GAIN, 0, 95, 1, 31);
365 
366 	return hdl->error;
367 }
368 
369 static void gc0310_remove(struct i2c_client *client)
370 {
371 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
372 	struct gc0310_device *dev = to_gc0310_sensor(sd);
373 
374 	dev_dbg(&client->dev, "gc0310_remove...\n");
375 
376 	atomisp_unregister_subdev(sd);
377 	v4l2_device_unregister_subdev(sd);
378 	media_entity_cleanup(&dev->sd.entity);
379 	v4l2_ctrl_handler_free(&dev->ctrls.handler);
380 	mutex_destroy(&dev->input_lock);
381 	pm_runtime_disable(&client->dev);
382 }
383 
384 static int gc0310_probe(struct i2c_client *client)
385 {
386 	struct gc0310_device *dev;
387 	int ret;
388 
389 	dev = devm_kzalloc(&client->dev, sizeof(*dev), GFP_KERNEL);
390 	if (!dev)
391 		return -ENOMEM;
392 
393 	ret = v4l2_get_acpi_sensor_info(&client->dev, NULL);
394 	if (ret)
395 		return ret;
396 
397 	dev->reset = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
398 	if (IS_ERR(dev->reset))
399 		return dev_err_probe(&client->dev, PTR_ERR(dev->reset),
400 				     "getting reset GPIO\n");
401 
402 	dev->powerdown = devm_gpiod_get(&client->dev, "powerdown", GPIOD_OUT_HIGH);
403 	if (IS_ERR(dev->powerdown))
404 		return dev_err_probe(&client->dev, PTR_ERR(dev->powerdown),
405 				     "getting powerdown GPIO\n");
406 
407 	mutex_init(&dev->input_lock);
408 	v4l2_i2c_subdev_init(&dev->sd, client, &gc0310_ops);
409 	gc0310_fill_format(&dev->mode.fmt);
410 
411 	pm_runtime_set_suspended(&client->dev);
412 	pm_runtime_enable(&client->dev);
413 	pm_runtime_set_autosuspend_delay(&client->dev, 1000);
414 	pm_runtime_use_autosuspend(&client->dev);
415 
416 	ret = gc0310_s_config(&dev->sd);
417 	if (ret) {
418 		gc0310_remove(client);
419 		return ret;
420 	}
421 
422 	dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
423 	dev->pad.flags = MEDIA_PAD_FL_SOURCE;
424 	dev->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
425 
426 	ret = gc0310_init_controls(dev);
427 	if (ret) {
428 		gc0310_remove(client);
429 		return ret;
430 	}
431 
432 	ret = media_entity_pads_init(&dev->sd.entity, 1, &dev->pad);
433 	if (ret) {
434 		gc0310_remove(client);
435 		return ret;
436 	}
437 
438 	ret = atomisp_register_sensor_no_gmin(&dev->sd, 1, ATOMISP_INPUT_FORMAT_RAW_8,
439 					      atomisp_bayer_order_grbg);
440 	if (ret) {
441 		gc0310_remove(client);
442 		return ret;
443 	}
444 
445 	return 0;
446 }
447 
448 static int gc0310_suspend(struct device *dev)
449 {
450 	struct v4l2_subdev *sd = dev_get_drvdata(dev);
451 	struct gc0310_device *gc0310_dev = to_gc0310_sensor(sd);
452 
453 	gpiod_set_value_cansleep(gc0310_dev->powerdown, 1);
454 	gpiod_set_value_cansleep(gc0310_dev->reset, 1);
455 	return 0;
456 }
457 
458 static int gc0310_resume(struct device *dev)
459 {
460 	struct v4l2_subdev *sd = dev_get_drvdata(dev);
461 	struct gc0310_device *gc0310_dev = to_gc0310_sensor(sd);
462 
463 	usleep_range(10000, 15000);
464 	gpiod_set_value_cansleep(gc0310_dev->reset, 0);
465 	usleep_range(10000, 15000);
466 	gpiod_set_value_cansleep(gc0310_dev->powerdown, 0);
467 
468 	return 0;
469 }
470 
471 static DEFINE_RUNTIME_DEV_PM_OPS(gc0310_pm_ops, gc0310_suspend, gc0310_resume, NULL);
472 
473 static const struct acpi_device_id gc0310_acpi_match[] = {
474 	{"INT0310"},
475 	{},
476 };
477 MODULE_DEVICE_TABLE(acpi, gc0310_acpi_match);
478 
479 static struct i2c_driver gc0310_driver = {
480 	.driver = {
481 		.name = "gc0310",
482 		.pm = pm_sleep_ptr(&gc0310_pm_ops),
483 		.acpi_match_table = gc0310_acpi_match,
484 	},
485 	.probe_new = gc0310_probe,
486 	.remove = gc0310_remove,
487 };
488 module_i2c_driver(gc0310_driver);
489 
490 MODULE_AUTHOR("Lai, Angie <angie.lai@intel.com>");
491 MODULE_DESCRIPTION("A low-level driver for GalaxyCore GC0310 sensors");
492 MODULE_LICENSE("GPL");
493