drivers/staging/media/atomisp/i2c/atomisp-gc2235.c

Source file repositories/reference/linux-study-clean/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c

File Facts

System
Linux kernel
Corpus path
drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
Extension
.c
Size
19791 bytes
Lines
878
Domain
Driver Families
Bucket
drivers/staging
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (next->type & GC2235_TOK_MASK) {
		case GC2235_TOK_DELAY:
			err = __gc2235_flush_reg_array(client, &ctrl);
			if (err)
				return err;
			msleep(next->val);
			break;
		default:
			/*
			 * If next address is not consecutive, data needs to be
			 * flushed before proceed.
			 */
			if (!__gc2235_write_reg_is_consecutive(client, &ctrl,
							       next)) {
				err = __gc2235_flush_reg_array(client, &ctrl);
				if (err)
					return err;
			}
			err = __gc2235_buf_reg_array(client, &ctrl, next);
			if (err) {
				dev_err(&client->dev, "%s: write error, aborted\n",
					__func__);
				return err;
			}
			break;
		}
	}

	return __gc2235_flush_reg_array(client, &ctrl);
}

static long __gc2235_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
				  int gain, int digitgain)

{
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	u16 coarse_integration = (u16)coarse_itg;
	int ret = 0;
	u16 expo_coarse_h, expo_coarse_l, gain_val = 0xF0, gain_val2 = 0xF0;

	expo_coarse_h = coarse_integration >> 8;
	expo_coarse_l = coarse_integration & 0xff;

	ret = gc2235_write_reg(client, GC2235_8BIT,
			       GC2235_EXPOSURE_H, expo_coarse_h);
	ret = gc2235_write_reg(client, GC2235_8BIT,
			       GC2235_EXPOSURE_L, expo_coarse_l);

	if (gain <= 0x58) {
		gain_val = 0x40;
		gain_val2 = 0x58;
	} else if (gain < 256) {
		gain_val = 0x40;
		gain_val2 = gain;
	} else {
		gain_val2 = 64 * gain / 256;
		gain_val = 0xff;
	}

	ret = gc2235_write_reg(client, GC2235_8BIT,
			       GC2235_GLOBAL_GAIN, (u8)gain_val);
	ret = gc2235_write_reg(client, GC2235_8BIT,
			       GC2235_PRE_GAIN, (u8)gain_val2);

	return ret;
}

static int gc2235_set_exposure(struct v4l2_subdev *sd, int exposure,
			       int gain, int digitgain)
{
	struct gc2235_device *dev = to_gc2235_sensor(sd);
	int ret;

	mutex_lock(&dev->input_lock);
	ret = __gc2235_set_exposure(sd, exposure, gain, digitgain);
	mutex_unlock(&dev->input_lock);

	return ret;
}

static long gc2235_s_exposure(struct v4l2_subdev *sd,
			      struct atomisp_exposure *exposure)
{
	int exp = exposure->integration_time[0];
	int gain = exposure->gain[0];
	int digitgain = exposure->gain[1];

	/* we should not accept the invalid value below. */
	if (gain == 0) {
		struct i2c_client *client = v4l2_get_subdevdata(sd);

Annotation

Implementation Notes