1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2005-2006 Micronas USA Inc.
4 */
5
6#include <linux/module.h>
7#include <linux/delay.h>
8#include <linux/sched.h>
9#include <linux/spinlock.h>
10#include <linux/unistd.h>
11#include <linux/time.h>
12#include <linux/mm.h>
13#include <linux/vmalloc.h>
14#include <linux/device.h>
15#include <linux/i2c.h>
16#include <linux/firmware.h>
17#include <linux/mutex.h>
18#include <linux/uaccess.h>
19#include <linux/slab.h>
20#include <linux/videodev2.h>
21#include <media/tuner.h>
22#include <media/v4l2-common.h>
23#include <media/v4l2-event.h>
24
25#include "go7007-priv.h"
26
27/*
28 * Wait for an interrupt to be delivered from the GO7007SB and return
29 * the associated value and data.
30 *
31 * Must be called with the hw_lock held.
32 */
33int go7007_read_interrupt(struct go7007 *go, u16 *value, u16 *data)
34{
35	go->interrupt_available = 0;
36	go->hpi_ops->read_interrupt(go);
37	if (wait_event_timeout(go->interrupt_waitq,
38				go->interrupt_available, 5*HZ) < 0) {
39		v4l2_err(&go->v4l2_dev, "timeout waiting for read interrupt\n");
40		return -1;
41	}
42	if (!go->interrupt_available)
43		return -1;
44	go->interrupt_available = 0;
45	*value = go->interrupt_value & 0xfffe;
46	*data = go->interrupt_data;
47	return 0;
48}
49EXPORT_SYMBOL(go7007_read_interrupt);
50
51/*
52 * Read a register/address on the GO7007SB.
53 *
54 * Must be called with the hw_lock held.
55 */
56int go7007_read_addr(struct go7007 *go, u16 addr, u16 *data)
57{
58	int count = 100;
59	u16 value;
60
61	if (go7007_write_interrupt(go, 0x0010, addr) < 0)
62		return -EIO;
63	while (count-- > 0) {
64		if (go7007_read_interrupt(go, &value, data) == 0 &&
65				value == 0xa000)
66			return 0;
67	}
68	return -EIO;
69}
70EXPORT_SYMBOL(go7007_read_addr);
71
72/*
73 * Send the boot firmware to the encoder, which just wakes it up and lets
74 * us talk to the GPIO pins and on-board I2C adapter.
75 *
76 * Must be called with the hw_lock held.
77 */
78static int go7007_load_encoder(struct go7007 *go)
79{
80	const struct firmware *fw_entry;
81	char fw_name[] = "go7007/go7007fw.bin";
82	void *bounce;
83	int fw_len;
84	u16 intr_val, intr_data;
85
86	if (go->boot_fw == NULL) {
87		if (request_firmware(&fw_entry, fw_name, go->dev)) {
88			v4l2_err(go, "unable to load firmware from file \"%s\"\n", fw_name);
89			return -1;
90		}
91		if (fw_entry->size < 16 || memcmp(fw_entry->data, "WISGO7007FW", 11)) {
92			v4l2_err(go, "file \"%s\" does not appear to be go7007 firmware\n", fw_name);
93			release_firmware(fw_entry);
94			return -1;
95		}
96		fw_len = fw_entry->size - 16;
97		bounce = kmemdup(fw_entry->data + 16, fw_len, GFP_KERNEL);
98		if (bounce == NULL) {
99			v4l2_err(go, "unable to allocate %d bytes for firmware transfer\n", fw_len);
100			release_firmware(fw_entry);
101			return -1;
102		}
103		release_firmware(fw_entry);
104		go->boot_fw_len = fw_len;
105		go->boot_fw = bounce;
106	}
107	if (go7007_interface_reset(go) < 0 ||
108	    go7007_send_firmware(go, go->boot_fw, go->boot_fw_len) < 0 ||
109	    go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
110			(intr_val & ~0x1) != 0x5a5a) {
111		v4l2_err(go, "error transferring firmware\n");
112		kfree(go->boot_fw);
113		go->boot_fw = NULL;
114		return -1;
115	}
116	return 0;
117}
118
119MODULE_FIRMWARE("go7007/go7007fw.bin");
120
121/*
122 * Boot the encoder and register the I2C adapter if requested.  Do the
123 * minimum initialization necessary, since the board-specific code may
124 * still need to probe the board ID.
125 *
126 * Must NOT be called with the hw_lock held.
127 */
128int go7007_boot_encoder(struct go7007 *go, int init_i2c)
129{
130	int ret;
131
132	mutex_lock(&go->hw_lock);
133	ret = go7007_load_encoder(go);
134	mutex_unlock(&go->hw_lock);
135	if (ret < 0)
136		return -1;
137	if (!init_i2c)
138		return 0;
139	if (go7007_i2c_init(go) < 0)
140		return -1;
141	go->i2c_adapter_online = 1;
142	return 0;
143}
144EXPORT_SYMBOL(go7007_boot_encoder);
145
146/*
147 * Configure any hardware-related registers in the GO7007, such as GPIO
148 * pins and bus parameters, which are board-specific.  This assumes
149 * the boot firmware has already been downloaded.
150 *
151 * Must be called with the hw_lock held.
152 */
153static int go7007_init_encoder(struct go7007 *go)
154{
155	if (go->board_info->audio_flags & GO7007_AUDIO_I2S_MASTER) {
156		go7007_write_addr(go, 0x1000, 0x0811);
157		go7007_write_addr(go, 0x1000, 0x0c11);
158	}
159	switch (go->board_id) {
160	case GO7007_BOARDID_MATRIX_REV:
161		/* Set GPIO pin 0 to be an output (audio clock control) */
162		go7007_write_addr(go, 0x3c82, 0x0001);
163		go7007_write_addr(go, 0x3c80, 0x00fe);
164		break;
165	case GO7007_BOARDID_ADLINK_MPG24:
166		/* set GPIO5 to be an output, currently low */
167		go7007_write_addr(go, 0x3c82, 0x0000);
168		go7007_write_addr(go, 0x3c80, 0x00df);
169		break;
170	case GO7007_BOARDID_ADS_USBAV_709:
171		/* GPIO pin 0: audio clock control */
172		/*      pin 2: TW9906 reset */
173		/*      pin 3: capture LED */
174		go7007_write_addr(go, 0x3c82, 0x000d);
175		go7007_write_addr(go, 0x3c80, 0x00f2);
176		break;
177	}
178	return 0;
179}
180
181/*
182 * Send the boot firmware to the GO7007 and configure the registers.  This
183 * is the only way to stop the encoder once it has started streaming video.
184 *
185 * Must be called with the hw_lock held.
186 */
187int go7007_reset_encoder(struct go7007 *go)
188{
189	if (go7007_load_encoder(go) < 0)
190		return -1;
191	return go7007_init_encoder(go);
192}
193
194/*
195 * Attempt to instantiate an I2C client by ID, probably loading a module.
196 */
197static int init_i2c_module(struct i2c_adapter *adapter, const struct go_i2c *const i2c)
198{
199	struct go7007 *go = i2c_get_adapdata(adapter);
200	struct v4l2_device *v4l2_dev = &go->v4l2_dev;
201	struct v4l2_subdev *sd;
202	struct i2c_board_info info;
203
204	memset(&info, 0, sizeof(info));
205	strscpy(info.type, i2c->type, sizeof(info.type));
206	info.addr = i2c->addr;
207	info.flags = i2c->flags;
208
209	sd = v4l2_i2c_new_subdev_board(v4l2_dev, adapter, &info, NULL);
210	if (sd) {
211		if (i2c->is_video)
212			go->sd_video = sd;
213		if (i2c->is_audio)
214			go->sd_audio = sd;
215		return 0;
216	}
217
218	pr_info("go7007: probing for module i2c:%s failed\n", i2c->type);
219	return -EINVAL;
220}
221
222/*
223 * Detach and unregister the encoder.  The go7007 struct won't be freed
224 * until v4l2 finishes releasing its resources and all associated fds are
225 * closed by applications.
226 */
227static void go7007_remove(struct v4l2_device *v4l2_dev)
228{
229	struct go7007 *go = container_of(v4l2_dev, struct go7007, v4l2_dev);
230
231	v4l2_device_unregister(v4l2_dev);
232	if (go->hpi_ops->release)
233		go->hpi_ops->release(go);
234	if (go->i2c_adapter_online) {
235		i2c_del_adapter(&go->i2c_adapter);
236		go->i2c_adapter_online = 0;
237	}
238
239	kfree(go->boot_fw);
240	go7007_v4l2_remove(go);
241	kfree(go);
242}
243
244/*
245 * Finalize the GO7007 hardware setup, register the on-board I2C adapter
246 * (if used on this board), load the I2C client driver for the sensor
247 * (SAA7115 or whatever) and other devices, and register the ALSA and V4L2
248 * interfaces.
249 *
250 * Must NOT be called with the hw_lock held.
251 */
252int go7007_register_encoder(struct go7007 *go, unsigned num_i2c_devs)
253{
254	int i, ret;
255
256	dev_info(go->dev, "go7007: registering new %s\n", go->name);
257
258	go->v4l2_dev.release = go7007_remove;
259	ret = v4l2_device_register(go->dev, &go->v4l2_dev);
260	if (ret < 0)
261		return ret;
262
263	mutex_lock(&go->hw_lock);
264	ret = go7007_init_encoder(go);
265	mutex_unlock(&go->hw_lock);
266	if (ret < 0)
267		return ret;
268
269	ret = go7007_v4l2_ctrl_init(go);
270	if (ret < 0)
271		return ret;
272
273	if (!go->i2c_adapter_online &&
274			go->board_info->flags & GO7007_BOARD_USE_ONBOARD_I2C) {
275		ret = go7007_i2c_init(go);
276		if (ret < 0)
277			return ret;
278		go->i2c_adapter_online = 1;
279	}
280	if (go->i2c_adapter_online) {
281		if (go->board_id == GO7007_BOARDID_ADS_USBAV_709) {
282			/* Reset the TW9906 */
283			go7007_write_addr(go, 0x3c82, 0x0009);
284			msleep(50);
285			go7007_write_addr(go, 0x3c82, 0x000d);
286		}
287		for (i = 0; i < num_i2c_devs; ++i)
288			init_i2c_module(&go->i2c_adapter, &go->board_info->i2c_devs[i]);
289
290		if (go->tuner_type >= 0) {
291			struct tuner_setup setup = {
292				.addr = ADDR_UNSET,
293				.type = go->tuner_type,
294				.mode_mask = T_ANALOG_TV,
295			};
296
297			v4l2_device_call_all(&go->v4l2_dev, 0, tuner,
298				s_type_addr, &setup);
299		}
300		if (go->board_id == GO7007_BOARDID_ADLINK_MPG24)
301			v4l2_subdev_call(go->sd_video, video, s_routing,
302					0, 0, go->channel_number + 1);
303	}
304
305	ret = go7007_v4l2_init(go);
306	if (ret < 0)
307		return ret;
308
309	if (go->board_info->flags & GO7007_BOARD_HAS_AUDIO) {
310		go->audio_enabled = 1;
311		go7007_snd_init(go);
312	}
313	return 0;
314}
315EXPORT_SYMBOL(go7007_register_encoder);
316
317/*
318 * Send the encode firmware to the encoder, which will cause it
319 * to immediately start delivering the video and audio streams.
320 *
321 * Must be called with the hw_lock held.
322 */
323int go7007_start_encoder(struct go7007 *go)
324{
325	u8 *fw;
326	int fw_len, rv = 0, i, x, y;
327	u16 intr_val, intr_data;
328
329	go->modet_enable = 0;
330	for (i = 0; i < 4; i++)
331		go->modet[i].enable = 0;
332
333	switch (v4l2_ctrl_g_ctrl(go->modet_mode)) {
334	case V4L2_DETECT_MD_MODE_GLOBAL:
335		memset(go->modet_map, 0, sizeof(go->modet_map));
336		go->modet[0].enable = 1;
337		go->modet_enable = 1;
338		break;
339	case V4L2_DETECT_MD_MODE_REGION_GRID:
340		for (y = 0; y < go->height / 16; y++) {
341			for (x = 0; x < go->width / 16; x++) {
342				int idx = y * go->width / 16 + x;
343
344				go->modet[go->modet_map[idx]].enable = 1;
345			}
346		}
347		go->modet_enable = 1;
348		break;
349	}
350
351	if (go->dvd_mode)
352		go->modet_enable = 0;
353
354	if (go7007_construct_fw_image(go, &fw, &fw_len) < 0)
355		return -1;
356
357	if (go7007_send_firmware(go, fw, fw_len) < 0 ||
358			go7007_read_interrupt(go, &intr_val, &intr_data) < 0) {
359		v4l2_err(&go->v4l2_dev, "error transferring firmware\n");
360		rv = -1;
361		goto start_error;
362	}
363
364	go->state = STATE_DATA;
365	go->parse_length = 0;
366	go->seen_frame = 0;
367	if (go7007_stream_start(go) < 0) {
368		v4l2_err(&go->v4l2_dev, "error starting stream transfer\n");
369		rv = -1;
370		goto start_error;
371	}
372
373start_error:
374	kfree(fw);
375	return rv;
376}
377
378/*
379 * Store a byte in the current video buffer, if there is one.
380 */
381static inline void store_byte(struct go7007_buffer *vb, u8 byte)
382{
383	if (vb && vb->vb.vb2_buf.planes[0].bytesused < GO7007_BUF_SIZE) {
384		u8 *ptr = vb2_plane_vaddr(&vb->vb.vb2_buf, 0);
385
386		ptr[vb->vb.vb2_buf.planes[0].bytesused++] = byte;
387	}
388}
389
390static void go7007_set_motion_regions(struct go7007 *go, struct go7007_buffer *vb,
391		u32 motion_regions)
392{
393	if (motion_regions != go->modet_event_status) {
394		struct v4l2_event ev = {
395			.type = V4L2_EVENT_MOTION_DET,
396			.u.motion_det = {
397				.flags = V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ,
398				.frame_sequence = vb->vb.sequence,
399				.region_mask = motion_regions,
400			},
401		};
402
403		v4l2_event_queue(&go->vdev, &ev);
404		go->modet_event_status = motion_regions;
405	}
406}
407
408/*
409 * Determine regions with motion and send a motion detection event
410 * in case of changes.
411 */
412static void go7007_motion_regions(struct go7007 *go, struct go7007_buffer *vb)
413{
414	u32 *bytesused = &vb->vb.vb2_buf.planes[0].bytesused;
415	unsigned motion[4] = { 0, 0, 0, 0 };
416	u32 motion_regions = 0;
417	unsigned stride = (go->width + 7) >> 3;
418	unsigned x, y;
419	int i;
420
421	for (i = 0; i < 216; ++i)
422		store_byte(vb, go->active_map[i]);
423	for (y = 0; y < go->height / 16; y++) {
424		for (x = 0; x < go->width / 16; x++) {
425			if (!(go->active_map[y * stride + (x >> 3)] & (1 << (x & 7))))
426				continue;
427			motion[go->modet_map[y * (go->width / 16) + x]]++;
428		}
429	}
430	motion_regions = ((motion[0] > 0) << 0) |
431			 ((motion[1] > 0) << 1) |
432			 ((motion[2] > 0) << 2) |
433			 ((motion[3] > 0) << 3);
434	*bytesused -= 216;
435	go7007_set_motion_regions(go, vb, motion_regions);
436}
437
438/*
439 * Deliver the last video buffer and get a new one to start writing to.
440 */
441static struct go7007_buffer *frame_boundary(struct go7007 *go, struct go7007_buffer *vb)
442{
443	u32 *bytesused;
444	struct go7007_buffer *vb_tmp = NULL;
445	unsigned long flags;
446
447	if (vb == NULL) {
448		spin_lock_irqsave(&go->spinlock, flags);
449		if (!list_empty(&go->vidq_active))
450			vb = go->active_buf =
451				list_first_entry(&go->vidq_active, struct go7007_buffer, list);
452		spin_unlock_irqrestore(&go->spinlock, flags);
453		go->next_seq++;
454		return vb;
455	}
456	bytesused = &vb->vb.vb2_buf.planes[0].bytesused;
457
458	vb->vb.sequence = go->next_seq++;
459	if (vb->modet_active && *bytesused + 216 < GO7007_BUF_SIZE)
460		go7007_motion_regions(go, vb);
461	else
462		go7007_set_motion_regions(go, vb, 0);
463
464	vb->vb.vb2_buf.timestamp = ktime_get_ns();
465	vb_tmp = vb;
466	spin_lock_irqsave(&go->spinlock, flags);
467	list_del(&vb->list);
468	if (list_empty(&go->vidq_active))
469		vb = NULL;
470	else
471		vb = list_first_entry(&go->vidq_active,
472				struct go7007_buffer, list);
473	go->active_buf = vb;
474	spin_unlock_irqrestore(&go->spinlock, flags);
475	vb2_buffer_done(&vb_tmp->vb.vb2_buf, VB2_BUF_STATE_DONE);
476	return vb;
477}
478
479static void write_bitmap_word(struct go7007 *go)
480{
481	int x, y, i, stride = ((go->width >> 4) + 7) >> 3;
482
483	for (i = 0; i < 16; ++i) {
484		y = (((go->parse_length - 1) << 3) + i) / (go->width >> 4);
485		x = (((go->parse_length - 1) << 3) + i) % (go->width >> 4);
486		if (stride * y + (x >> 3) < sizeof(go->active_map))
487			go->active_map[stride * y + (x >> 3)] |=
488					(go->modet_word & 1) << (x & 0x7);
489		go->modet_word >>= 1;
490	}
491}
492
493/*
494 * Parse a chunk of the video stream into frames.  The frames are not
495 * delimited by the hardware, so we have to parse the frame boundaries
496 * based on the type of video stream we're receiving.
497 */
498void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
499{
500	struct go7007_buffer *vb = go->active_buf;
501	int i, seq_start_code = -1, gop_start_code = -1, frame_start_code = -1;
502
503	switch (go->format) {
504	case V4L2_PIX_FMT_MPEG4:
505		seq_start_code = 0xB0;
506		gop_start_code = 0xB3;
507		frame_start_code = 0xB6;
508		break;
509	case V4L2_PIX_FMT_MPEG1:
510	case V4L2_PIX_FMT_MPEG2:
511		seq_start_code = 0xB3;
512		gop_start_code = 0xB8;
513		frame_start_code = 0x00;
514		break;
515	}
516
517	for (i = 0; i < length; ++i) {
518		if (vb && vb->vb.vb2_buf.planes[0].bytesused >=
519				GO7007_BUF_SIZE - 3) {
520			v4l2_info(&go->v4l2_dev, "dropping oversized frame\n");
521			vb2_set_plane_payload(&vb->vb.vb2_buf, 0, 0);
522			vb->frame_offset = 0;
523			vb->modet_active = 0;
524			vb = go->active_buf = NULL;
525		}
526
527		switch (go->state) {
528		case STATE_DATA:
529			switch (buf[i]) {
530			case 0x00:
531				go->state = STATE_00;
532				break;
533			case 0xFF:
534				go->state = STATE_FF;
535				break;
536			default:
537				store_byte(vb, buf[i]);
538				break;
539			}
540			break;
541		case STATE_00:
542			switch (buf[i]) {
543			case 0x00:
544				go->state = STATE_00_00;
545				break;
546			case 0xFF:
547				store_byte(vb, 0x00);
548				go->state = STATE_FF;
549				break;
550			default:
551				store_byte(vb, 0x00);
552				store_byte(vb, buf[i]);
553				go->state = STATE_DATA;
554				break;
555			}
556			break;
557		case STATE_00_00:
558			switch (buf[i]) {
559			case 0x00:
560				store_byte(vb, 0x00);
561				/* go->state remains STATE_00_00 */
562				break;
563			case 0x01:
564				go->state = STATE_00_00_01;
565				break;
566			case 0xFF:
567				store_byte(vb, 0x00);
568				store_byte(vb, 0x00);
569				go->state = STATE_FF;
570				break;
571			default:
572				store_byte(vb, 0x00);
573				store_byte(vb, 0x00);
574				store_byte(vb, buf[i]);
575				go->state = STATE_DATA;
576				break;
577			}
578			break;
579		case STATE_00_00_01:
580			if (buf[i] == 0xF8 && go->modet_enable == 0) {
581				/* MODET start code, but MODET not enabled */
582				store_byte(vb, 0x00);
583				store_byte(vb, 0x00);
584				store_byte(vb, 0x01);
585				store_byte(vb, 0xF8);
586				go->state = STATE_DATA;
587				break;
588			}
589			/* If this is the start of a new MPEG frame,
590			 * get a new buffer */
591			if ((go->format == V4L2_PIX_FMT_MPEG1 ||
592			     go->format == V4L2_PIX_FMT_MPEG2 ||
593			     go->format == V4L2_PIX_FMT_MPEG4) &&
594			    (buf[i] == seq_start_code ||
595			     buf[i] == gop_start_code ||
596			     buf[i] == frame_start_code)) {
597				if (vb == NULL || go->seen_frame)
598					vb = frame_boundary(go, vb);
599				go->seen_frame = buf[i] == frame_start_code;
600				if (vb && go->seen_frame)
601					vb->frame_offset =
602					vb->vb.vb2_buf.planes[0].bytesused;
603			}
604			/* Handle any special chunk types, or just write the
605			 * start code to the (potentially new) buffer */
606			switch (buf[i]) {
607			case 0xF5: /* timestamp */
608				go->parse_length = 12;
609				go->state = STATE_UNPARSED;
610				break;
611			case 0xF6: /* vbi */
612				go->state = STATE_VBI_LEN_A;
613				break;
614			case 0xF8: /* MD map */
615				go->parse_length = 0;
616				memset(go->active_map, 0,
617						sizeof(go->active_map));
618				go->state = STATE_MODET_MAP;
619				break;
620			case 0xFF: /* Potential JPEG start code */
621				store_byte(vb, 0x00);
622				store_byte(vb, 0x00);
623				store_byte(vb, 0x01);
624				go->state = STATE_FF;
625				break;
626			default:
627				store_byte(vb, 0x00);
628				store_byte(vb, 0x00);
629				store_byte(vb, 0x01);
630				store_byte(vb, buf[i]);
631				go->state = STATE_DATA;
632				break;
633			}
634			break;
635		case STATE_FF:
636			switch (buf[i]) {
637			case 0x00:
638				store_byte(vb, 0xFF);
639				go->state = STATE_00;
640				break;
641			case 0xFF:
642				store_byte(vb, 0xFF);
643				/* go->state remains STATE_FF */
644				break;
645			case 0xD8:
646				if (go->format == V4L2_PIX_FMT_MJPEG)
647					vb = frame_boundary(go, vb);
648				fallthrough;
649			default:
650				store_byte(vb, 0xFF);
651				store_byte(vb, buf[i]);
652				go->state = STATE_DATA;
653				break;
654			}
655			break;
656		case STATE_VBI_LEN_A:
657			go->parse_length = buf[i] << 8;
658			go->state = STATE_VBI_LEN_B;
659			break;
660		case STATE_VBI_LEN_B:
661			go->parse_length |= buf[i];
662			if (go->parse_length > 0)
663				go->state = STATE_UNPARSED;
664			else
665				go->state = STATE_DATA;
666			break;
667		case STATE_MODET_MAP:
668			if (go->parse_length < 204) {
669				if (go->parse_length & 1) {
670					go->modet_word |= buf[i];
671					write_bitmap_word(go);
672				} else
673					go->modet_word = buf[i] << 8;
674			} else if (go->parse_length == 207 && vb) {
675				vb->modet_active = buf[i];
676			}
677			if (++go->parse_length == 208)
678				go->state = STATE_DATA;
679			break;
680		case STATE_UNPARSED:
681			if (--go->parse_length == 0)
682				go->state = STATE_DATA;
683			break;
684		}
685	}
686}
687EXPORT_SYMBOL(go7007_parse_video_stream);
688
689/*
690 * Allocate a new go7007 struct.  Used by the hardware-specific probe.
691 */
692struct go7007 *go7007_alloc(const struct go7007_board_info *board,
693						struct device *dev)
694{
695	struct go7007 *go;
696
697	go = kzalloc(sizeof(struct go7007), GFP_KERNEL);
698	if (go == NULL)
699		return NULL;
700	go->dev = dev;
701	go->board_info = board;
702	go->tuner_type = -1;
703	mutex_init(&go->hw_lock);
704	init_waitqueue_head(&go->frame_waitq);
705	spin_lock_init(&go->spinlock);
706	go->status = STATUS_INIT;
707	init_waitqueue_head(&go->interrupt_waitq);
708	go7007_update_board(go);
709	go->format = V4L2_PIX_FMT_MJPEG;
710	go->bitrate = 1500000;
711	go->fps_scale = 1;
712	go->aspect_ratio = GO7007_RATIO_1_1;
713
714	return go;
715}
716EXPORT_SYMBOL(go7007_alloc);
717
718void go7007_update_board(struct go7007 *go)
719{
720	const struct go7007_board_info *board = go->board_info;
721
722	if (board->sensor_flags & GO7007_SENSOR_TV) {
723		go->standard = GO7007_STD_NTSC;
724		go->std = V4L2_STD_NTSC_M;
725		go->width = 720;
726		go->height = 480;
727		go->sensor_framerate = 30000;
728	} else {
729		go->standard = GO7007_STD_OTHER;
730		go->width = board->sensor_width;
731		go->height = board->sensor_height;
732		go->sensor_framerate = board->sensor_framerate;
733	}
734	go->encoder_v_offset = board->sensor_v_offset;
735	go->encoder_h_offset = board->sensor_h_offset;
736}
737EXPORT_SYMBOL(go7007_update_board);
738
739MODULE_LICENSE("GPL v2");
740