Exemplo n.º 1
0
static void fsa9485_reg_init(struct fsa9485_usbsw *usbsw)
{
	struct i2c_client *client = usbsw->client;
	unsigned int ctrl = CON_MASK;
	int ret;

	pr_info("fsa9485_reg_init is called\n");

	usbsw->dev_id = i2c_smbus_read_byte_data(client, FSA9485_REG_DEVID);
	local_usbsw->dev_id = usbsw->dev_id;
	if (usbsw->dev_id < 0)
		dev_err(&client->dev, "%s: err %d\n", __func__, usbsw->dev_id);

	dev_info(&client->dev, " fsa9485_reg_init dev ID: 0x%x\n",
			usbsw->dev_id);

	/* mask interrupts (unmask attach/detach only) */
	ret = i2c_smbus_write_byte_data(client, FSA9485_REG_INT1_MASK, 0x5c);

	if (is_ti_muic()) {
		ret = i2c_smbus_write_byte_data(client,
				FSA9485_REG_INT2_MASK, INT_MASK2);
		if (ret < 0)
			dev_err(&client->dev, "%s: err %d\n", __func__, ret);
	} else {
		ret = i2c_smbus_write_byte_data(client,
				FSA9485_REG_INT2_MASK, 0x18);
		if (ret < 0)
			dev_err(&client->dev, "%s: err %d\n", __func__, ret);
	}

	if (ret < 0)
		dev_err(&client->dev, "%s: err %d\n", __func__, ret);

	/* mask all car kit interrupts */
	ret = i2c_smbus_write_word_data(client,
					FSA9485_REG_CK_INTMASK1, 0x07ff);
	if (ret < 0)
		dev_err(&client->dev, "%s: err %d\n", __func__, ret);

	/* ADC Detect Time: 500ms */
	ret = i2c_smbus_write_byte_data(client, FSA9485_REG_TIMING1, 0x0);
	if (ret < 0)
		dev_err(&client->dev, "%s: err %d\n", __func__, ret);

	usbsw->mansw = i2c_smbus_read_byte_data(client, FSA9485_REG_MANSW1);
	if (usbsw->mansw < 0)
		dev_err(&client->dev, "%s: err %d\n", __func__, usbsw->mansw);

	if (usbsw->mansw)
		ctrl &= ~CON_MANUAL_SW;	/* Manual Switching Mode */
	else
		ctrl &= ~(CON_INT_MASK);

	ret = i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, ctrl);
	if (ret < 0)
		dev_err(&client->dev, "%s: err %d\n", __func__, ret);

	if (!is_ti_muic()) {
		/* apply Battery Charging Spec. 1.1 @TA/USB detect */
		ret = i2c_smbus_write_byte_data(client,
				FSA9485_REG_RESERVED_20, 0x04);
		if (ret < 0)
			dev_err(&client->dev, "%s: err %d\n", __func__, ret);
	} else {
		/* BCDv1.2 Timer  default  1.8s -> 0.6s */
		ret = i2c_smbus_write_byte_data(client,
			FSA9485_REG_RESERVED_20, 0x05);
		if (ret < 0)
			dev_err(&client->dev, "%s: err %d\n", __func__, ret);

	}
}
Exemplo n.º 2
0
static int ms_nxtmmx_send_command(void *context,
				  struct tacho_motor_params *param,
				  enum tacho_motor_command command)
{
	struct ms_nxtmmx_data *mmx = context;
	int err;
	u8 command_bytes[WRITE_SIZE];

	if (IS_RUN_CMD(command)) {
		/* fill in the setpoints with the correct polarity */
		*(int *)command_bytes = cpu_to_le32(mmx->tm.params.position_sp);
		command_bytes[WRITE_SPEED] = ms_nxtmmx_scale_speed(mmx->tm.params.speed_sp);
		if (mmx->tm.params.polarity == DC_MOTOR_POLARITY_INVERSED) {
			*(int *)command_bytes *= -1;
			command_bytes[WRITE_SPEED] *= -1;
		}

		/* set the appropriate command flags based on the run command */

		if (IS_POS_CMD(command))
			mmx->command_flags |= CMD_FLAG_ENCODER_CTRL;
		else
			mmx->command_flags &= ~CMD_FLAG_ENCODER_CTRL;

		if (command == TM_COMMAND_RUN_TO_REL_POS)
			mmx->command_flags |= CMD_FLAG_RELATIVE;
		else
			mmx->command_flags &= ~CMD_FLAG_RELATIVE;

		/* set bits for stop command */

		if (mmx->tm.params.stop_command == TM_STOP_COMMAND_HOLD)
			mmx->command_flags |= CMD_FLAG_HOLD;
		else
			mmx->command_flags &= ~CMD_FLAG_HOLD;

		if (mmx->tm.params.stop_command == TM_STOP_COMMAND_BRAKE)
			mmx->command_flags |= CMD_FLAG_BRAKE;
		else
			mmx->command_flags &= ~CMD_FLAG_BRAKE;

		mmx->command_flags |= CMD_FLAG_GO;

		command_bytes[WRITE_TIME] = 0; /* never use timed mode */
		command_bytes[WRITE_COMMAND_B] = 0;
		command_bytes[WRITE_COMMAND_A] = mmx->command_flags;

		/* then write to the individual motor register to GO! */

		err = i2c_smbus_write_i2c_block_data(mmx->i2c->client,
			WRITE_REG(mmx->index), WRITE_SIZE, command_bytes);
		if (err < 0)
			return err;
	} else if (command == TM_COMMAND_STOP) {
		mmx->command_flags = CMD_FLAGS_DEFAULT_VALUE;
		command_bytes[0] = (mmx->tm.params.stop_command == TM_STOP_COMMAND_COAST)
			? COMMAND_FLOAT_STOP(mmx->index) : COMMAND_BRAKE_STOP(mmx->index);
		err = i2c_smbus_write_byte_data(mmx->i2c->client,
			COMMAND_REG, command_bytes[0]);
		if (err < 0)
			return err;
		if (mmx->tm.params.stop_command == TM_STOP_COMMAND_HOLD) {
			/*
			 * Hold only happens when encoder mode is enabled, so
			 * we have to issue a run command to tell it to run to
			 * the current position so that it will hold that position.
			 */
			err = i2c_smbus_read_i2c_block_data(mmx->i2c->client,
				READ_ENCODER_POS_REG(mmx->index), ENCODER_SIZE, command_bytes);
			if (err < 0)
				return err;
			mmx->command_flags = CMD_FLAGS_STOP_HOLD;
			command_bytes[WRITE_SPEED] = 100;
			command_bytes[WRITE_TIME] = 0;
			command_bytes[WRITE_COMMAND_B] = 0;
			command_bytes[WRITE_COMMAND_A] = mmx->command_flags;
			err = i2c_smbus_write_i2c_block_data(mmx->i2c->client,
				WRITE_REG(mmx->index), WRITE_SIZE, command_bytes);
			if (err < 0)
				return err;
		}
	} else if (command == TM_COMMAND_RESET) {
		mmx->tm.params.speed_regulation = TM_SPEED_REGULATION_ON;
		mmx->command_flags = CMD_FLAGS_DEFAULT_VALUE;
		command_bytes[0] = COMMAND_FLOAT_STOP(mmx->index);
		err = i2c_smbus_write_byte_data(mmx->i2c->client,
			COMMAND_REG, command_bytes[0]);
		if (err < 0)
			return err;
		command_bytes[0] = COMMAND_RESET_ENCODER(mmx->index);
		err = i2c_smbus_write_byte_data(mmx->i2c->client,
			COMMAND_REG, command_bytes[0]);
		if (err < 0)
			return err;
	}

	return 0;
}
Exemplo n.º 3
0
static int fsa9485_detach_dev(struct fsa9485_usbsw *usbsw)
{
	int ret;
	struct fsa9485_platform_data *pdata = usbsw->pdata;
	struct i2c_client *client = usbsw->client;
#if defined(CONFIG_VIDEO_MHL_V2)
	u8 mhl_ret = 0;
#endif
	/* USB */
	if (usbsw->dev1 & DEV_USB ||
			usbsw->dev2 & DEV_T2_USB_MASK) {
		pdata->callback(CABLE_TYPE_USB, FSA9485_DETACHED);
		local_usbsw->last_state.detach = USB_CALL;
	} else if (usbsw->dev1 & DEV_USB_CHG) {
		pdata->callback(CABLE_TYPE_CDP, FSA9485_DETACHED);
		local_usbsw->last_state.detach = CDP_CALL;
		/* UART */
	} else if (usbsw->dev1 & DEV_T1_UART_MASK ||
			usbsw->dev2 & DEV_T2_UART_MASK) {
		pdata->callback(CABLE_TYPE_UARTOFF, FSA9485_DETACHED);
		local_usbsw->last_state.detach = UART_CALL;
		uart_connecting = 0;
		dev_info(&client->dev, "[FSA9485] uart disconnect\n");
		/* CHARGER */
	} else if ((usbsw->dev1 & DEV_T1_CHARGER_MASK) ||
			(usbsw->dev3 & DEV_T3_CHARGER_MASK)) {
		pdata->callback(CABLE_TYPE_AC, FSA9485_DETACHED);
		local_usbsw->last_state.detach = CHARGER_CALL;
	/* for SAMSUNG OTG */
	} else if (usbsw->dev1 & DEV_USB_OTG) {
		i2c_smbus_write_byte_data(client,
					FSA9485_REG_CTRL, 0x1E);
	/* JIG */
	} else if (usbsw->dev2 & DEV_T2_JIG_MASK) {
		pdata->callback(CABLE_TYPE_JIG, FSA9485_DETACHED);
		local_usbsw->last_state.detach = JIG_CALL;
	/* Desk Dock */
	} else if ((usbsw->dev2 & DEV_AV) || (usbsw->dev3 & DEV_MHL) ||
			(usbsw->dev3 & DEV_AV_VBUS)) {
			pr_info("Deskdock/MHL Detach\n");
			if (!is_ti_muic())
			i2c_smbus_write_byte_data(client,
				FSA9485_REG_RESERVED_20, 0x04);
#if defined(CONFIG_VIDEO_MHL_V2)
		if (isDeskdockconnected)
			FSA9485_CheckAndHookAudioDock(0);
#if defined CONFIG_MHL_D3_SUPPORT
		mhl_onoff_ex(false);
		detached_status = 1;
#endif
		isDeskdockconnected = 0;
#else
		FSA9485_CheckAndHookAudioDock(0);
#endif
	/* Car Dock */
	} else if (usbsw->dev2 & DEV_JIG_UART_ON) {
		pdata->callback(CABLE_TYPE_CARDOCK,
			FSA9485_DETACHED_DOCK);
		local_usbsw->last_state.detach = CARDOCK_CALL;
		ret = i2c_smbus_read_byte_data(client,
				FSA9485_REG_CTRL);
		if (ret < 0)
			dev_err(&client->dev,
					"%s: err %d\n", __func__, ret);
		ret = i2c_smbus_write_byte_data(client,
				FSA9485_REG_CTRL,
				ret | CON_MANUAL_SW);
		if (ret < 0)
			dev_err(&client->dev,
				"%s: err %d\n", __func__, ret);
		usbsw->dock_attached = FSA9485_DETACHED;
	} else if (usbsw->adc == 0x10) {
		dev_info(&client->dev, "smart dock disconnect\n");
		ret = i2c_smbus_read_byte_data(client,
					FSA9485_REG_CTRL);
		if (ret < 0)
			dev_err(&client->dev,
				"%s: err %d\n", __func__, ret);
			ret = i2c_smbus_write_byte_data(client,
				FSA9485_REG_CTRL,
				ret | CON_MANUAL_SW);
		if (ret < 0)
			dev_err(&client->dev,
				"%s: err %d\n", __func__, ret);
			pdata->callback(CABLE_TYPE_SMART_DOCK,
			FSA9485_DETACHED);
		local_usbsw->last_state.detach = SMARTDOCK_CALL;
		usbsw->adc = 0;
#if defined(CONFIG_VIDEO_MHL_V2)
		mhl_onoff_ex(false);
#endif
	} else if (usbsw->dev2 == DEV_AUDIO_DOCK) {
		dev_info(&client->dev, "audio dock disconnect\n");
		ret = i2c_smbus_read_byte_data(client,
			    FSA9485_REG_CTRL);
		    if (ret < 0)
				dev_err(&client->dev,
				    "%s: err %d\n", __func__, ret);
			ret = i2c_smbus_write_byte_data(client,
					FSA9485_REG_CTRL,
					ret | CON_MANUAL_SW);
		    if (ret < 0)
				dev_err(&client->dev,
					"%s: err %d\n", __func__, ret);
			pdata->callback(CABLE_TYPE_AUDIO_DOCK,
				FSA9485_DETACHED);
		local_usbsw->last_state.detach = AUDIODOCK_CALL;
		usbsw->adc = 0;
	} else if (usbsw->dev3 & DEV_VBUS_DEBOUNCE) {
		dev_info(&client->dev,
				"Incompatible Charger disconnect\n");
		pdata->callback(CABLE_TYPE_INCOMPATIBLE,
				FSA9485_DETACHED);
		local_usbsw->last_state.detach = INCOMPATIBLE_CALL;
	} else
		pr_info("%s cannot detach due to invalid device type",
				__func__);

	usbsw->dev1 = 0;
	usbsw->dev2 = 0;
	usbsw->dev3 = 0;

	return 0;
}
Exemplo n.º 4
0
static int tsl4531_powerdown(struct i2c_client *client)
{
	return i2c_smbus_write_byte_data(client, TSL4531_CONTROL,
		TSL4531_MODE_POWERDOWN);
}
Exemplo n.º 5
0
static int tsl4531_resume(struct device *dev)
{
	return i2c_smbus_write_byte_data(to_i2c_client(dev), TSL4531_CONTROL,
		TSL4531_MODE_NORMAL);
}
Exemplo n.º 6
0
static int g760a_write_value(struct i2c_client *client, enum g760a_regs reg,
			     u16 value)
{
	return i2c_smbus_write_byte_data(client, reg, value);
}
Exemplo n.º 7
0
static int hdmi_sii_enable(struct i2c_client *client)
{
	int rc;
	int retries = 10;
	int count;

	rc = i2c_smbus_write_byte_data(client, 0xC7, 0x00);
	if (rc)
		goto enable_exit;

	do {
		msleep(1);
		rc = i2c_smbus_read_byte_data(client, 0x1B);
	} while ((rc != SII9022_DEVICE_ID) && retries--);

	if (rc != SII9022_DEVICE_ID)
		return -ENODEV;

	rc = i2c_smbus_write_byte_data(client, 0x1A, 0x11);
	if (rc)
		goto enable_exit;

	count = ARRAY_SIZE(video_mode_data);
	rc = i2c_master_send(client, video_mode_data, count);
	if (rc != count) {
		rc = -EIO;
		goto enable_exit;
	}

	rc = i2c_smbus_write_byte_data(client, 0x08, 0x20);
	if (rc)
		goto enable_exit;
	count = ARRAY_SIZE(avi_io_format);
	rc = i2c_master_send(client, avi_io_format, count);
	if (rc != count) {
		rc = -EIO;
		goto enable_exit;
	}

	rc = send_i2c_data(client, regset0, ARRAY_SIZE(regset0));
	if (rc)
		goto enable_exit;

	count = ARRAY_SIZE(video_infoframe);
	rc = i2c_master_send(client, video_infoframe, count);
	if (rc != count) {
		rc = -EIO;
		goto enable_exit;
	}

	rc = send_i2c_data(client, regset1, ARRAY_SIZE(regset1));
	if (rc)
		goto enable_exit;

	count = ARRAY_SIZE(misc_infoframe);
	rc = i2c_master_send(client, misc_infoframe, count);
	if (rc != count) {
		rc = -EIO;
		goto enable_exit;
	}

	rc = send_i2c_data(client, regset2, ARRAY_SIZE(regset2));
	if (rc)
		goto enable_exit;

	return 0;
enable_exit:
	printk(KERN_ERR "%s: exited rc=%d\n", __func__, rc);
	return rc;
}
Exemplo n.º 8
0
static void hmc5883_stop_measure(struct hmc5883_data *hmc5883)
{
	i2c_smbus_write_byte_data(hmc5883->client, HMC5883_REG_MODE, MODE_IDLE);
}
Exemplo n.º 9
0
static void fsa9480_detect_dev(struct fsa9480_usbsw *usbsw)
{
	int device_type, ret;
	unsigned char val1, val2;
	struct fsa9480_platform_data *pdata = usbsw->pdata;
	struct i2c_client *client = usbsw->client;

#ifdef CONFIG_MACH_VICTORY
	adc_fsa  = i2c_smbus_read_word_data(client, FSA9480_REG_ADC);
	if (adc_fsa < 0)
		dev_err(&client->dev, "%s: err %d\n", __func__, adc_fsa);
	if ( adc_fsa == WIMAX_CABLE_50K){
		switch_set_state(&wimax_cable, USB_CABLE_50K);
	} else if (adc_fsa == WIMAX_CABLE_50K_DIS) {
		fsa9480_manual_switching(SWITCH_PORT_AUTO);
		switch_set_state(&wimax_cable, CABLE_DISCONNECT);
	} 
#endif
	device_type = i2c_smbus_read_word_data(client, FSA9480_REG_DEV_T1);
	if (device_type < 0)
		dev_err(&client->dev, "%s: err %d\n", __func__, device_type);

	val1 = device_type & 0xff;
	val2 = device_type >> 8;

	dev_info(&client->dev, "dev1: 0x%x, dev2: 0x%x\n", val1, val2);

	/* Attached */
	if (val1 || val2) {
		/* USB */
#ifdef CONFIG_MACH_VICTORY
		if (val1 & DEV_T1_USB_MASK){
#else		
			if (val1 & DEV_T1_USB_MASK || val2 & DEV_T2_USB_MASK ) {
#endif
			if (pdata->usb_cb)
				pdata->usb_cb(FSA9480_ATTACHED);

			micro_usb_status = 1;
#ifdef _SUPPORT_SAMSUNG_AUTOINSTALLER_
			askon_gadget_disconnect();
			if (!askon_status)
				UsbIndicator(1);
#else
				UsbIndicator(1);
#endif
			if (usbsw->mansw) {
				ret = i2c_smbus_write_byte_data(client,
					FSA9480_REG_MANSW1, usbsw->mansw);
				if (ret < 0)
					dev_err(&client->dev,
						"%s: err %d\n", __func__, ret);
			}
#if defined CONFIG_USB_S3C_OTG_HOST || defined CONFIG_USB_DWC_OTG
// sztupy: handle automatic otg switching
                       if (val1 & DEV_USB_OTG) {
                               // otg cable detected
                               set_otghost_mode(2);
                       } else {
                               // client cable detected
                               set_otghost_mode(1);
                       }
#endif
#ifdef CONFIG_MACH_VICTORY
		} else if ( val2 & DEV_T2_USB_MASK ) {
			if (pdata->wimax_cb)
				pdata->wimax_cb(FSA9480_ATTACHED);
				switch_set_state(&wimax_cable, USB_CABLE_255K);
#endif
		/* UART */
		} else if (val1 & DEV_T1_UART_MASK || val2 & DEV_T2_UART_MASK) {
			if(val2 & DEV_T2_UART_MASK)
				MicroJigUARTOffStatus = 1;

			if (pdata->uart_cb)
				pdata->uart_cb(FSA9480_ATTACHED);

			if (usbsw->mansw) {
				ret = i2c_smbus_write_byte_data(client,
					FSA9480_REG_MANSW1, SW_UART);
				if (ret < 0)
					dev_err(&client->dev,
						"%s: err %d\n", __func__, ret);
			}

			if (val2 & DEV_T2_JIG_MASK) {
				if (pdata->jig_cb)
					pdata->jig_cb(FSA9480_ATTACHED);
			}
		/* CHARGER */
		} else if (val1 & DEV_T1_CHARGER_MASK) {
			if (pdata->charger_cb)
				pdata->charger_cb(FSA9480_ATTACHED);
		/* JIG */
		} else if (val2 & DEV_T2_JIG_MASK) {
			if (pdata->jig_cb)
				pdata->jig_cb(FSA9480_ATTACHED);
		/* Desk Dock */
		} else if (val2 & DEV_AV) {
			if (pdata->deskdock_cb)
				pdata->deskdock_cb(FSA9480_ATTACHED);
				dock_status = 1;
			
			ret = i2c_smbus_write_byte_data(client,
					FSA9480_REG_MANSW1, SW_VAUDIO);
			if (ret < 0)
				dev_err(&client->dev,
					"%s: err %d\n", __func__, ret);

			ret = i2c_smbus_read_byte_data(client,
					FSA9480_REG_CTRL);
			if (ret < 0)
				dev_err(&client->dev,
					"%s: err %d\n", __func__, ret);

			ret = i2c_smbus_write_byte_data(client,
					FSA9480_REG_CTRL, ret & ~CON_MANUAL_SW);
			if (ret < 0)
				dev_err(&client->dev,
					"%s: err %d\n", __func__, ret);
		/* Car Dock */
		} else if (val2 & DEV_JIG_UART_ON) {
			if (pdata->cardock_cb)
				pdata->cardock_cb(FSA9480_ATTACHED);
			dock_status = 1;

                        ret = i2c_smbus_write_byte_data(client,
                                        FSA9480_REG_MANSW1, SW_VAUDIO);
                        if (ret < 0)
                                dev_err(&client->dev,
                                        "%s: err %d\n", __func__, ret);

                        ret = i2c_smbus_read_byte_data(client,
                                        FSA9480_REG_CTRL);
                        if (ret < 0)
                                dev_err(&client->dev,
                                        "%s: err %d\n", __func__, ret);

                        ret = i2c_smbus_write_byte_data(client,
                                FSA9480_REG_CTRL, ret & ~CON_MANUAL_SW);
                        if (ret < 0)
                                dev_err(&client->dev,
                                        "%s: err %d\n", __func__, ret);
		}
	/* Detached */
	} else {
		/* USB */
#ifdef CONFIG_MACH_VICTORY
		if (usbsw->dev1 & DEV_T1_USB_MASK){
#else		
		if (usbsw->dev1 & DEV_T1_USB_MASK ||
				usbsw->dev2 & DEV_T2_USB_MASK) {
#endif
			micro_usb_status = 0;
			UsbIndicator(0);
			if (pdata->usb_cb)
				pdata->usb_cb(FSA9480_DETACHED);
#if defined CONFIG_USB_S3C_OTG_HOST || defined CONFIG_USB_DWC_OTG
                               // sztupy: also switch off otg host mode
                               set_otghost_mode(0);
#endif
#ifdef CONFIG_MACH_VICTORY		
        	/* USB JIG */
		} else if (usbsw->dev2 & DEV_T2_USB_MASK) {
			if (pdata->wimax_cb)
				pdata->wimax_cb(FSA9480_DETACHED);
			switch_set_state(&wimax_cable, CABLE_DISCONNECT);
#endif
		/* UART */
		} else if (usbsw->dev1 & DEV_T1_UART_MASK ||
				usbsw->dev2 & DEV_T2_UART_MASK) {
			if(usbsw->dev2 & DEV_T2_UART_MASK)
				MicroJigUARTOffStatus = 0;

			if (pdata->uart_cb)
				pdata->uart_cb(FSA9480_DETACHED);
			if (usbsw->dev2 & DEV_T2_JIG_MASK) {
				if (pdata->jig_cb)
					pdata->jig_cb(FSA9480_DETACHED);
			}
		/* CHARGER */
		} else if (usbsw->dev1 & DEV_T1_CHARGER_MASK) {
			if (pdata->charger_cb)
				pdata->charger_cb(FSA9480_DETACHED);
		/* JIG */
		} else if (usbsw->dev2 & DEV_T2_JIG_MASK) {
			if (pdata->jig_cb)
				pdata->jig_cb(FSA9480_DETACHED);
		/* Desk Dock */
		} else if (usbsw->dev2 & DEV_AV) {
			if (pdata->deskdock_cb)
				pdata->deskdock_cb(FSA9480_DETACHED);
			dock_status = 0;
			
			ret = i2c_smbus_read_byte_data(client,FSA9480_REG_CTRL);
			if (ret < 0)
				dev_err(&client->dev,
					"%s: err %d\n", __func__, ret);

			ret = i2c_smbus_write_byte_data(client,
					FSA9480_REG_CTRL, ret | CON_MANUAL_SW);
			if (ret < 0)
				dev_err(&client->dev,
					"%s: err %d\n", __func__, ret);
		/* Car Dock */
		} else if (usbsw->dev2 & DEV_JIG_UART_ON) {
			if (pdata->cardock_cb)
				pdata->cardock_cb(FSA9480_DETACHED);
			dock_status = 0;

                        ret = i2c_smbus_read_byte_data(client,
                                        FSA9480_REG_CTRL);
                        if (ret < 0)
                                dev_err(&client->dev,
                                        "%s: err %d\n", __func__, ret);

                        ret = i2c_smbus_write_byte_data(client,
                                        FSA9480_REG_CTRL, ret | CON_MANUAL_SW);
                        if (ret < 0)
                                dev_err(&client->dev,
                                        "%s: err %d\n", __func__, ret);
		}
	}

	usbsw->dev1 = val1;
	usbsw->dev2 = val2;
}

static void fsa9480_reg_init(struct fsa9480_usbsw *usbsw)
{
	struct i2c_client *client = usbsw->client;
	unsigned int ctrl = CON_MASK;
	int ret;
#if defined (CONFIG_MACH_ATLAS) || defined (CONFIG_MACH_FORTE)
	/* mask interrupts (unmask attach/detach only) */
	ret = i2c_smbus_write_word_data(client, FSA9480_REG_INT1_MASK, 0x1ffc);
	if (ret < 0)
		dev_err(&client->dev, "%s: err %d\n", __func__, ret);
#elif CONFIG_MACH_VICTORY
	/* mask interrupts (unmask attach/detach only reserved attach only) */
	ret = i2c_smbus_write_word_data(client, FSA9480_REG_INT1_MASK, 0x1dfc);
	if (ret < 0)
		dev_err(&client->dev, "%s: err %d\n", __func__, ret);
#endif
	/* mask all car kit interrupts */
	ret = i2c_smbus_write_word_data(client, FSA9480_REG_CK_INTMASK1, 0x07ff);
	if (ret < 0)
		dev_err(&client->dev, "%s: err %d\n", __func__, ret);

	/* ADC Detect Time: 500ms */
	ret = i2c_smbus_write_byte_data(client, FSA9480_REG_TIMING1, 0x6);
	if (ret < 0)
		dev_err(&client->dev, "%s: err %d\n", __func__, ret);

	usbsw->mansw = i2c_smbus_read_byte_data(client, FSA9480_REG_MANSW1);
	if (usbsw->mansw < 0)
		dev_err(&client->dev, "%s: err %d\n", __func__, usbsw->mansw);

	if (usbsw->mansw)
		ctrl &= ~CON_MANUAL_SW;	/* Manual Switching Mode */

	ret = i2c_smbus_write_byte_data(client, FSA9480_REG_CTRL, ctrl);
	if (ret < 0)
		dev_err(&client->dev, "%s: err %d\n", __func__, ret);
}

static irqreturn_t fsa9480_irq_thread(int irq, void *data)
{
	struct fsa9480_usbsw *usbsw = data;
	struct i2c_client *client = usbsw->client;
	int intr;
	
	/* read and clear interrupt status bits */
	intr = i2c_smbus_read_word_data(client, FSA9480_REG_INT1);
	if (intr < 0) {
		dev_err(&client->dev, "%s: err %d\n", __func__, intr);
	} else if (intr == 0) {
		/* interrupt was fired, but no status bits were set,
		so device was reset. In this case, the registers were
		reset to defaults so they need to be reinitialised. */
		fsa9480_reg_init(usbsw);
	}

	/* device detection */
	fsa9480_detect_dev(usbsw);
	
	return IRQ_HANDLED;
}

static int fsa9480_irq_init(struct fsa9480_usbsw *usbsw)
{
	struct i2c_client *client = usbsw->client;
	int ret;

	if (client->irq) {
		ret = request_threaded_irq(client->irq, NULL,
			fsa9480_irq_thread, IRQF_TRIGGER_FALLING,
			"fsa9480 micro USB", usbsw);
		if (ret) {
			dev_err(&client->dev, "failed to reqeust IRQ\n");
			return ret;
		}

		ret = enable_irq_wake(client->irq);
		if (ret < 0)
			dev_err(&client->dev,
				"failed to enable wakeup src %d\n", ret);
	}

	return 0;
}

static int __devinit fsa9480_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
	struct fsa9480_usbsw *usbsw;
	int ret = 0;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
		return -EIO;

	usbsw = kzalloc(sizeof(struct fsa9480_usbsw), GFP_KERNEL);
	if (!usbsw) {
		dev_err(&client->dev, "failed to allocate driver data\n");
		return -ENOMEM;
	}

	usbsw->client = client;
	usbsw->pdata = client->dev.platform_data;
	if (!usbsw->pdata)
		goto fail1;

	i2c_set_clientdata(client, usbsw);
	
	local_usbsw = usbsw;  // temp

	if (usbsw->pdata->cfg_gpio)
		usbsw->pdata->cfg_gpio();

	fsa9480_reg_init(usbsw);

	ret = fsa9480_irq_init(usbsw);
	if (ret)
		goto fail1;

	ret = sysfs_create_group(&client->dev.kobj, &fsa9480_group);
	if (ret) {
		dev_err(&client->dev,
				"failed to create fsa9480 attribute group\n");
		goto fail2;
	}

	if (usbsw->pdata->reset_cb)
		usbsw->pdata->reset_cb();

        indicator_dev.name = DRIVER_NAME;
#if 1
        indicator_dev.print_name = print_switch_name;
        indicator_dev.print_state = print_switch_state;
#endif
        switch_dev_register(&indicator_dev);

	/* device detection */
	fsa9480_detect_dev(usbsw);
	
	// set fsa9480 init flag.
	if (usbsw->pdata->set_init_flag)
		usbsw->pdata->set_init_flag();
#if defined(CONFIG_MACH_VICTORY)
	ret = switch_dev_register(&wimax_cable);
	wimax_cable.print_state = wimax_cable_type;	
#endif
	return 0;

fail2:
	if (client->irq)
		free_irq(client->irq, usbsw);
fail1:
	i2c_set_clientdata(client, NULL);
	kfree(usbsw);
	return ret;
}

static int __devexit fsa9480_remove(struct i2c_client *client)
{
	struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client);

	if (client->irq) {
		disable_irq_wake(client->irq);
		free_irq(client->irq, usbsw);
	}
	i2c_set_clientdata(client, NULL);

	sysfs_remove_group(&client->dev.kobj, &fsa9480_group);
	kfree(usbsw);
	return 0;
}

#ifdef CONFIG_PM

static int fsa9480_suspend(struct i2c_client *client, pm_message_t mesg)
{
#ifdef CONFIG_MACH_VICTORY 
	disable_irq(client->irq	);
#endif
	return 0;
}

static int fsa9480_resume(struct i2c_client *client)
{
	struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client);

#ifdef CONFIG_MACH_VICTORY
	enable_irq(client->irq);
#endif
	/* device detection */
	fsa9480_detect_dev(usbsw);

	return 0;
}

#else

#define fsa9480_suspend NULL
#define fsa9480_resume NULL

#endif /* CONFIG_PM */

static const struct i2c_device_id fsa9480_id[] = {
	{"fsa9480", 0},
	{}
};
MODULE_DEVICE_TABLE(i2c, fsa9480_id);

static struct i2c_driver fsa9480_i2c_driver = {
	.driver = {
		.name = "fsa9480",
	},
	.probe = fsa9480_probe,
	.remove = __devexit_p(fsa9480_remove),
	.suspend = fsa9480_suspend,
	.resume = fsa9480_resume,
	.id_table = fsa9480_id,
};
static int gp2a_disable(struct gp2a_data *dt)
{
	return i2c_smbus_write_byte_data(dt->i2c_client, GP2A_ADDR_OPMOD,
					 0x00);
}
static int gp2a_enable(struct gp2a_data *dt)
{
	return i2c_smbus_write_byte_data(dt->i2c_client, GP2A_ADDR_OPMOD,
					 GP2A_CTRL_SSD);
}
Exemplo n.º 12
0
static inline int ad7414_write(struct i2c_client *client, u8 reg, u8 value)
{
	return i2c_smbus_write_byte_data(client, reg, value);
}
Exemplo n.º 13
0
void fsa9485_manual_switching(int path)
{
	struct i2c_client *client = local_usbsw->client;
	int value, ret;
	unsigned int data = 0;

	value = i2c_smbus_read_byte_data(client, FSA9485_REG_CTRL);
	if (value < 0)
		dev_err(&client->dev, "%s: err %d\n", __func__, value);

	if ((value & ~CON_MANUAL_SW) !=
			(CON_SWITCH_OPEN | CON_RAW_DATA | CON_WAIT))
		return;

	if (path == SWITCH_PORT_VAUDIO) {
		data = SW_VAUDIO;
		value &= ~CON_MANUAL_SW;
	} else if (path ==  SWITCH_PORT_UART) {
		data = SW_UART;
		value &= ~CON_MANUAL_SW;
	} else if (path ==  SWITCH_PORT_AUDIO) {
		data = SW_AUDIO;
		value &= ~CON_MANUAL_SW;
	} else if (path ==  SWITCH_PORT_USB) {
		data = SW_DHOST;
		value &= ~CON_MANUAL_SW;
	} else if (path ==  SWITCH_PORT_AUTO) {
		data = SW_AUTO;
		value |= CON_MANUAL_SW;
	} else if (path ==  SWITCH_PORT_USB_OPEN) {
		data = SW_USB_OPEN;
		value &= ~CON_MANUAL_SW;
	} else if (path ==  SWITCH_PORT_ALL_OPEN) {
		data = SW_ALL_OPEN;
		value &= ~CON_MANUAL_SW;
	} else {
		pr_info("%s: wrong path (%d)\n", __func__, path);
		return;
	}

	local_usbsw->mansw = data;

	/* path for FTM sleep */
	if (path ==  SWITCH_PORT_ALL_OPEN) {
		ret = i2c_smbus_write_byte_data(client,
					FSA9485_REG_MANUAL_OVERRIDES1, 0x0a);
		if (ret < 0)
			dev_err(&client->dev, "%s: err %d\n", __func__, ret);

		ret = i2c_smbus_write_byte_data(client,
						FSA9485_REG_MANSW1, data);
		if (ret < 0)
			dev_err(&client->dev, "%s: err %d\n", __func__, ret);

		ret = i2c_smbus_write_byte_data(client,
						FSA9485_REG_MANSW2, data);
		if (ret < 0)
			dev_err(&client->dev, "%s: err %d\n", __func__, ret);

		ret = i2c_smbus_write_byte_data(client,
						FSA9485_REG_CTRL, value);
		if (ret < 0)
			dev_err(&client->dev, "%s: err %d\n", __func__, ret);
	} else {
		ret = i2c_smbus_write_byte_data(client,
						FSA9485_REG_MANSW1, data);
		if (ret < 0)
			dev_err(&client->dev, "%s: err %d\n", __func__, ret);

		ret = i2c_smbus_write_byte_data(client,
						FSA9485_REG_CTRL, value);
		if (ret < 0)
			dev_err(&client->dev, "%s: err %d\n", __func__, ret);
	}

}
Exemplo n.º 14
0
static int fsa9485_detect_dev(struct fsa9485_usbsw *usbsw)
{
	int ret, adc;
	unsigned int val1, val2, val3;
	struct fsa9485_platform_data *pdata = usbsw->pdata;
	struct i2c_client *client = usbsw->client;
#if defined(CONFIG_VIDEO_MHL_V2)
	u8 mhl_ret = 0;
#endif

	val1 = i2c_smbus_read_byte_data(client, FSA9485_REG_DEV_T1);
	if (val1 < 0) {
		dev_err(&client->dev, "%s: err %d\n", __func__, val1);
		return val1;
	}

	val2 = i2c_smbus_read_byte_data(client, FSA9485_REG_DEV_T2);
	if (val2 < 0) {
		dev_err(&client->dev, "%s: err %d\n", __func__, val2);
		return val2;
	}
	jig_state =  (val2 & DEV_T2_JIG_ALL_MASK) ? 1 : 0;

	if (is_ti_muic()) {
		val3 = i2c_smbus_read_byte_data(client, FSA9485_REG_DEV_T3);
		if (val3 < 0) {
			dev_err(&client->dev, "%s: err %d\n", __func__, val3);
			return val3;
		}
	} else {
		val3 = i2c_smbus_read_byte_data(client,
				FSA9485_REG_RESERVED_1D);
		if (val3 < 0) {
			dev_err(&client->dev, "%s: err %d\n", __func__, val3);
			return val3;
		}
		val3 = val3 & 0x02;
	}

	adc = i2c_smbus_read_byte_data(client, FSA9485_REG_ADC);

	if (adc == 0x10)
		val2 = DEV_SMARTDOCK;
	else if (adc == 0x11 || adc == 0x12) {
		val2 = DEV_AUDIO_DOCK;
		dev_err(&client->dev, "adc is audio");
		val1 = 0;
	}
	dev_err(&client->dev,
			"dev1: 0x%x, dev2: 0x%x, dev3: 0x%x, ADC: 0x%x Jig:%s\n",
			val1, val2, val3, adc,
			(check_jig_state() ? "ON" : "OFF"));

	if ((val1+val2+val3 != 0)) {
		pr_info("%s Save state\n", __func__);
		local_usbsw->last_state.dev1 = val1;
		local_usbsw->last_state.dev2 = val2;
		local_usbsw->last_state.dev3 = val3;
	}

	/* Attached */
	if (val1 || val2 || (val3 & ~DEV_VBUS_DEBOUNCE) ||
			((val3 & DEV_VBUS_DEBOUNCE) && (adc != ADC_OPEN))) {
		/* USB */
		if (val1 & DEV_USB || val2 & DEV_T2_USB_MASK) {
			dev_info(&client->dev, "usb connect\n");
			pdata->callback(CABLE_TYPE_USB, FSA9485_ATTACHED);
			local_usbsw->last_state.attach = USB_CALL;

			if (usbsw->mansw) {
				ret = i2c_smbus_write_byte_data(client,
					FSA9485_REG_MANSW1, usbsw->mansw);

				if (ret < 0)
					dev_err(&client->dev,
						"%s: err %d\n", __func__, ret);
			}
		/* USB_CDP */
		} else if (val1 & DEV_USB_CHG) {
			dev_info(&client->dev, "usb_cdp connect\n");
#ifdef CONFIG_TSU6721_CDP_FIX
			pdata->callback(CABLE_TYPE_CDP, is_ti_muic() ? 
					TSU6721_ATTACHED : FSA9485_ATTACHED);
#else
			pdata->callback(CABLE_TYPE_CDP, FSA9485_ATTACHED);
#endif
			local_usbsw->last_state.attach = CDP_CALL;

			if (usbsw->mansw) {
				ret = i2c_smbus_write_byte_data(client,
					FSA9485_REG_MANSW1, usbsw->mansw);

				if (ret < 0)
					dev_err(&client->dev,
						"%s: err %d\n", __func__, ret);
			}

		/* UART */
		} else if (val1 & DEV_T1_UART_MASK || val2 & DEV_T2_UART_MASK) {
			uart_connecting = 1;
			dev_info(&client->dev, "uart connect\n");
			i2c_smbus_write_byte_data(client,
						FSA9485_REG_CTRL, 0x1E);
			pdata->callback(CABLE_TYPE_UARTOFF, FSA9485_ATTACHED);
			local_usbsw->last_state.attach = UART_CALL;

			if (usbsw->mansw) {
				ret = i2c_smbus_write_byte_data(client,
					FSA9485_REG_MANSW1, SW_UART);

				if (ret < 0)
					dev_err(&client->dev,
						"%s: err %d\n", __func__, ret);
			}
		/* CHARGER */
		} else if ((val1 & DEV_T1_CHARGER_MASK) ||
				(val3 & DEV_T3_CHARGER_MASK)) {
			dev_info(&client->dev, "charger connect\n");
			pdata->callback(CABLE_TYPE_AC, FSA9485_ATTACHED);
			local_usbsw->last_state.attach = CHARGER_CALL;
		/* for SAMSUNG OTG */
#if defined(CONFIG_USB_HOST_NOTIFY)
		} else if (val1 & DEV_USB_OTG) {
			dev_info(&client->dev, "otg connect\n");
			pdata->callback(CABLE_TYPE_OTG, FSA9485_ATTACHED);
			local_usbsw->last_state.attach = OTG_CALL;

			i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1,
					is_ti_muic() ? 0x25 : 0x27);
			i2c_smbus_write_byte_data(client,
						FSA9485_REG_MANSW2, 0x02);
			msleep(50);
			i2c_smbus_write_byte_data(client,
						FSA9485_REG_CTRL, 0x1a);
#endif
		/* JIG */
		} else if (val2 & DEV_T2_JIG_MASK) {
			dev_info(&client->dev, "jig connect\n");
			pdata->callback(CABLE_TYPE_JIG, FSA9485_ATTACHED);
			local_usbsw->last_state.attach = JIG_CALL;
		/* Desk Dock */
		} else if ((val2 & DEV_AV) || (val3 & DEV_MHL) ||
			(val3 & DEV_AV_VBUS)) {
			if ((!is_ti_muic()) && ((adc & 0x1F) == 0x1A)) {
				pr_info("FSA Deskdock Attach\n");
				FSA9485_CheckAndHookAudioDock(1);
#if defined(CONFIG_VIDEO_MHL_V2)
				isDeskdockconnected = 1;
#endif
				i2c_smbus_write_byte_data(client,
					FSA9485_REG_RESERVED_20, 0x08);
			} else if ((is_ti_muic()) && !(val3 & DEV_MHL)) {
				pr_info("TI Deskdock Attach\n");
				FSA9485_CheckAndHookAudioDock(1);
#if defined(CONFIG_VIDEO_MHL_V2)
				isDeskdockconnected = 1;
#endif
			} else {
				pr_info("MHL Attach\n");
				if (!is_ti_muic())
					i2c_smbus_write_byte_data(client,
						FSA9485_REG_RESERVED_20, 0x08);
#if defined(CONFIG_VIDEO_MHL_V2)
				DisableFSA9480Interrupts();
				if (!isDeskdockconnected) {
					if (!poweroff_charging)
						mhl_ret = mhl_onoff_ex(1);
					else
						pr_info("LPM mode, skip MHL sequence\n");
				}
			local_usbsw->last_state.device = MHL_CALL;
				if (mhl_ret != MHL_DEVICE &&
						(adc & 0x1F) == 0x1A) {
					FSA9485_CheckAndHookAudioDock(1);
					isDeskdockconnected = 1;
				}
				EnableFSA9480Interrupts();
#else
				FSA9485_CheckAndHookAudioDock(1);
#endif
			}
		/* Car Dock */
		} else if (val2 & DEV_JIG_UART_ON) {
			pdata->callback(CABLE_TYPE_CARDOCK,
				FSA9485_ATTACHED);
			local_usbsw->last_state.attach = CARDOCK_CALL;
			ret = i2c_smbus_write_byte_data(client,
					FSA9485_REG_MANSW1, SW_AUDIO);
			if (ret < 0)
				dev_err(&client->dev,
						"%s: err %d\n", __func__, ret);

			ret = i2c_smbus_read_byte_data(client,
					FSA9485_REG_CTRL);
			if (ret < 0)
				dev_err(&client->dev,
						"%s: err %d\n", __func__, ret);

			ret = i2c_smbus_write_byte_data(client,
					FSA9485_REG_CTRL, ret & ~CON_MANUAL_SW);
			if (ret < 0)
				dev_err(&client->dev,
						"%s: err %d\n", __func__, ret);
			usbsw->dock_attached = FSA9485_ATTACHED;
		/* SmartDock */
		} else if (val2 & DEV_SMARTDOCK) {
			usbsw->adc = adc;
			dev_info(&client->dev, "smart dock connect\n");

			usbsw->mansw = SW_DHOST;
			ret = i2c_smbus_write_byte_data(client,
					FSA9485_REG_MANSW1, SW_DHOST);
			if (ret < 0)
				dev_err(&client->dev,
						"%s: err %d\n", __func__, ret);
			ret = i2c_smbus_read_byte_data(client,
					FSA9485_REG_CTRL);
			if (ret < 0)
				dev_err(&client->dev,
						"%s: err %d\n", __func__, ret);
			ret = i2c_smbus_write_byte_data(client,
					FSA9485_REG_CTRL, ret & ~CON_MANUAL_SW);
			if (ret < 0)
				dev_err(&client->dev,
						"%s: err %d\n", __func__, ret);

			pdata->callback(CABLE_TYPE_SMART_DOCK,
				FSA9485_ATTACHED);
			local_usbsw->last_state.attach = SMARTDOCK_CALL;
#if defined(CONFIG_VIDEO_MHL_V2)
			mhl_onoff_ex(1);
#endif
#if defined(CONFIG_USB_HOST_NOTIFY)
		/* Audio Dock */
		} else if (val2 & DEV_AUDIO_DOCK) {
			usbsw->adc = adc;
			dev_info(&client->dev, "audio dock connect\n");

			usbsw->mansw = SW_DHOST;

			if (is_ti_muic())
				ret = i2c_smbus_write_byte_data(client,
					FSA9485_REG_MANSW1, SW_DHOST_TSU);
			else
				ret = i2c_smbus_write_byte_data(client,
					FSA9485_REG_MANSW1, SW_DHOST);

			if (ret < 0)
				dev_err(&client->dev,
						"%s: err %d\n", __func__, ret);

			ret = i2c_smbus_read_byte_data(client,
				FSA9485_REG_CTRL);
			if (ret < 0)
				dev_err(&client->dev,
						"%s: err %d\n", __func__, ret);
			ret = i2c_smbus_write_byte_data(client,
				FSA9485_REG_CTRL, ret & ~CON_MANUAL_SW);
			if (ret < 0)
				dev_err(&client->dev,
						"%s: err %d\n", __func__, ret);

			pdata->callback(CABLE_TYPE_AUDIO_DOCK,
				FSA9485_ATTACHED);
			local_usbsw->last_state.attach = AUDIODOCK_CALL;
#endif
		/* Incompatible */
		} else if (val3 & DEV_VBUS_DEBOUNCE) {
			dev_info(&client->dev,
					"Incompatible Charger connect\n");
			pdata->callback(CABLE_TYPE_INCOMPATIBLE,
					FSA9485_ATTACHED);
			local_usbsw->last_state.attach = INCOMPATIBLE_CALL;
		}
	/* Detached */
	} else {
		/* USB */
		if (usbsw->dev1 & DEV_USB ||
				usbsw->dev2 & DEV_T2_USB_MASK) {
			pdata->callback(CABLE_TYPE_USB, FSA9485_DETACHED);
			local_usbsw->last_state.detach = USB_CALL;
		} else if (usbsw->dev1 & DEV_USB_CHG) {
			pdata->callback(CABLE_TYPE_CDP, FSA9485_DETACHED);
			local_usbsw->last_state.detach = CDP_CALL;

		/* UART */
		} else if (usbsw->dev1 & DEV_T1_UART_MASK ||
				usbsw->dev2 & DEV_T2_UART_MASK) {
			pdata->callback(CABLE_TYPE_UARTOFF, FSA9485_DETACHED);
			local_usbsw->last_state.detach = UART_CALL;
			uart_connecting = 0;
			dev_info(&client->dev, "[FSA9485] uart disconnect\n");

		/* CHARGER */
		} else if ((usbsw->dev1 & DEV_T1_CHARGER_MASK) ||
				(usbsw->dev3 & DEV_T3_CHARGER_MASK)) {
			pdata->callback(CABLE_TYPE_AC, FSA9485_DETACHED);
			local_usbsw->last_state.detach = CHARGER_CALL;
		/* for SAMSUNG OTG */
		} else if (usbsw->dev1 & DEV_USB_OTG) {
			i2c_smbus_write_byte_data(client,
						FSA9485_REG_CTRL, 0x1E);
		/* JIG */
		} else if (usbsw->dev2 & DEV_T2_JIG_MASK) {
			pdata->callback(CABLE_TYPE_JIG, FSA9485_DETACHED);
			local_usbsw->last_state.detach = JIG_CALL;
		/* Desk Dock */
		} else if ((usbsw->dev2 & DEV_AV) || (usbsw->dev3 & DEV_MHL) ||
				(usbsw->dev3 & DEV_AV_VBUS)) {

			pr_info("Deskdock/MHL Detach\n");

			if (!is_ti_muic())
				i2c_smbus_write_byte_data(client,
					FSA9485_REG_RESERVED_20, 0x04);
#if defined(CONFIG_VIDEO_MHL_V2)
			if (isDeskdockconnected)
				FSA9485_CheckAndHookAudioDock(0);
#if defined CONFIG_MHL_D3_SUPPORT
			mhl_onoff_ex(false);
			detached_status = 1;
#endif
			isDeskdockconnected = 0;
#else
			FSA9485_CheckAndHookAudioDock(0);
#endif
		/* Car Dock */
		} else if (usbsw->dev2 & DEV_JIG_UART_ON) {
			pdata->callback(CABLE_TYPE_CARDOCK,
				FSA9485_DETACHED_DOCK);
			local_usbsw->last_state.detach = CARDOCK_CALL;
			ret = i2c_smbus_read_byte_data(client,
					FSA9485_REG_CTRL);
			if (ret < 0)
				dev_err(&client->dev,
					"%s: err %d\n", __func__, ret);

			ret = i2c_smbus_write_byte_data(client,
					FSA9485_REG_CTRL,
					ret | CON_MANUAL_SW);
			if (ret < 0)
				dev_err(&client->dev,
					"%s: err %d\n", __func__, ret);
			usbsw->dock_attached = FSA9485_DETACHED;
		} else if (usbsw->adc == 0x10) {
			dev_info(&client->dev, "smart dock disconnect\n");
			ret = i2c_smbus_read_byte_data(client,
						FSA9485_REG_CTRL);
			if (ret < 0)
				dev_err(&client->dev,
					"%s: err %d\n", __func__, ret);

			ret = i2c_smbus_write_byte_data(client,
					FSA9485_REG_CTRL,
					ret | CON_MANUAL_SW);
			if (ret < 0)
				dev_err(&client->dev,
					"%s: err %d\n", __func__, ret);

			pdata->callback(CABLE_TYPE_SMART_DOCK,
				FSA9485_DETACHED);
			local_usbsw->last_state.detach = SMARTDOCK_CALL;
			usbsw->adc = 0;
#if defined(CONFIG_VIDEO_MHL_V2)
			mhl_onoff_ex(false);
#endif
		} else if (usbsw->dev2 == DEV_AUDIO_DOCK) {
			dev_info(&client->dev, "audio dock disconnect\n");
			ret = i2c_smbus_read_byte_data(client,
				    FSA9485_REG_CTRL);
			    if (ret < 0)
					dev_err(&client->dev,
					    "%s: err %d\n", __func__, ret);
				ret = i2c_smbus_write_byte_data(client,
						FSA9485_REG_CTRL,
						ret | CON_MANUAL_SW);
			    if (ret < 0)
					dev_err(&client->dev,
						"%s: err %d\n", __func__, ret);

			pdata->callback(CABLE_TYPE_AUDIO_DOCK,
					FSA9485_DETACHED);
			local_usbsw->last_state.detach = AUDIODOCK_CALL;
			usbsw->adc = 0;
		} else if (usbsw->dev3 & DEV_VBUS_DEBOUNCE) {
			dev_info(&client->dev,
					"Incompatible Charger disconnect\n");
			pdata->callback(CABLE_TYPE_INCOMPATIBLE,
					FSA9485_DETACHED);
			local_usbsw->last_state.detach = INCOMPATIBLE_CALL;
		}
	}
	usbsw->dev1 = val1;
	usbsw->dev2 = val2;
	usbsw->dev3 = val3;

	return adc;
}
Exemplo n.º 15
0
/*
 * Ideally we shouldn't have to initialize anything, since the BIOS
 * should have taken care of everything
 */
static void lm63_init_client(struct i2c_client *client)
{
	struct lm63_data *data = i2c_get_clientdata(client);
	u8 convrate;

	data->config = i2c_smbus_read_byte_data(client, LM63_REG_CONFIG1);
	data->config_fan = i2c_smbus_read_byte_data(client,
						    LM63_REG_CONFIG_FAN);

	/* Start converting if needed */
	if (data->config & 0x40) { /* standby */
		dev_dbg(&client->dev, "Switching to operational mode\n");
		data->config &= 0xA7;
		i2c_smbus_write_byte_data(client, LM63_REG_CONFIG1,
					  data->config);
	}
	/* Tachometer is always enabled on LM64 */
	if (data->kind == lm64)
		data->config |= 0x04;

	/* We may need pwm1_freq before ever updating the client data */
	data->pwm1_freq = i2c_smbus_read_byte_data(client, LM63_REG_PWM_FREQ);
	if (data->pwm1_freq == 0)
		data->pwm1_freq = 1;

	switch (data->kind) {
	case lm63:
	case lm64:
		data->max_convrate_hz = LM63_MAX_CONVRATE_HZ;
		data->lut_size = 8;
		break;
	case lm96163:
		data->max_convrate_hz = LM96163_MAX_CONVRATE_HZ;
		data->lut_size = 12;
		data->trutherm
		  = i2c_smbus_read_byte_data(client,
					     LM96163_REG_TRUTHERM) & 0x02;
		break;
	}
	convrate = i2c_smbus_read_byte_data(client, LM63_REG_CONVRATE);
	if (unlikely(convrate > LM63_MAX_CONVRATE))
		convrate = LM63_MAX_CONVRATE;
	data->update_interval = UPDATE_INTERVAL(data->max_convrate_hz,
						convrate);

	/*
	 * For LM96163, check if high resolution PWM
	 * and unsigned temperature format is enabled.
	 */
	if (data->kind == lm96163) {
		u8 config_enhanced
		  = i2c_smbus_read_byte_data(client,
					     LM96163_REG_CONFIG_ENHANCED);
		if (config_enhanced & 0x20)
			data->lut_temp_highres = true;
		if ((config_enhanced & 0x10)
		    && !(data->config_fan & 0x08) && data->pwm1_freq == 8)
			data->pwm_highres = true;
		if (config_enhanced & 0x08)
			data->remote_unsigned = true;
	}

	/* Show some debug info about the LM63 configuration */
	if (data->kind == lm63)
		dev_dbg(&client->dev, "Alert/tach pin configured for %s\n",
			(data->config & 0x04) ? "tachometer input" :
			"alert output");
	dev_dbg(&client->dev, "PWM clock %s kHz, output frequency %u Hz\n",
		(data->config_fan & 0x08) ? "1.4" : "360",
		((data->config_fan & 0x08) ? 700 : 180000) / data->pwm1_freq);
	dev_dbg(&client->dev, "PWM output active %s, %s mode\n",
		(data->config_fan & 0x10) ? "low" : "high",
		(data->config_fan & 0x20) ? "manual" : "auto");
}
Exemplo n.º 16
0
static int sfe4001_poweron(struct efx_nic *efx)
{
	struct i2c_client *ioexp_client = falcon_board(efx)->ioexp_client;
	struct i2c_client *hwmon_client = falcon_board(efx)->hwmon_client;
	unsigned int i, j;
	int rc;
	u8 out;

	/* Clear any previous over-temperature alert */
	rc = i2c_smbus_read_byte_data(hwmon_client, MAX664X_REG_RSL);
	if (rc < 0)
		return rc;

	/* Enable port 0 and port 1 outputs on IO expander */
	rc = i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0x00);
	if (rc)
		return rc;
	rc = i2c_smbus_write_byte_data(ioexp_client, P1_CONFIG,
				       0xff & ~(1 << P1_SPARE_LBN));
	if (rc)
		goto fail_on;

	/* If PHY power is on, turn it all off and wait 1 second to
	 * ensure a full reset.
	 */
	rc = i2c_smbus_read_byte_data(ioexp_client, P0_OUT);
	if (rc < 0)
		goto fail_on;
	out = 0xff & ~((0 << P0_EN_1V2_LBN) | (0 << P0_EN_2V5_LBN) |
		       (0 << P0_EN_3V3X_LBN) | (0 << P0_EN_5V_LBN) |
		       (0 << P0_EN_1V0X_LBN));
	if (rc != out) {
		netif_info(efx, hw, efx->net_dev, "power-cycling PHY\n");
		rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
		if (rc)
			goto fail_on;
		schedule_timeout_uninterruptible(HZ);
	}

	for (i = 0; i < 20; ++i) {
		/* Turn on 1.2V, 2.5V, 3.3V and 5V power rails */
		out = 0xff & ~((1 << P0_EN_1V2_LBN) | (1 << P0_EN_2V5_LBN) |
			       (1 << P0_EN_3V3X_LBN) | (1 << P0_EN_5V_LBN) |
			       (1 << P0_X_TRST_LBN));
		if (efx->phy_mode & PHY_MODE_SPECIAL)
			out |= 1 << P0_EN_3V3X_LBN;

		rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
		if (rc)
			goto fail_on;
		msleep(10);

		/* Turn on 1V power rail */
		out &= ~(1 << P0_EN_1V0X_LBN);
		rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
		if (rc)
			goto fail_on;

		netif_info(efx, hw, efx->net_dev,
			   "waiting for DSP boot (attempt %d)...\n", i);

		/* In flash config mode, DSP does not turn on AFE, so
		 * just wait 1 second.
		 */
		if (efx->phy_mode & PHY_MODE_SPECIAL) {
			schedule_timeout_uninterruptible(HZ);
			return 0;
		}

		for (j = 0; j < 10; ++j) {
			msleep(100);

			/* Check DSP has asserted AFE power line */
			rc = i2c_smbus_read_byte_data(ioexp_client, P1_IN);
			if (rc < 0)
				goto fail_on;
			if (rc & (1 << P1_AFE_PWD_LBN))
				return 0;
		}
	}

	netif_info(efx, hw, efx->net_dev, "timed out waiting for DSP boot\n");
	rc = -ETIMEDOUT;
fail_on:
	sfe4001_poweroff(efx);
	return rc;
}
Exemplo n.º 17
0
static int mag3110_standby(struct mag3110_data *data)
{
	return i2c_smbus_write_byte_data(data->client, MAG3110_CTRL_REG1,
		data->ctrl_reg1 & ~MAG3110_CTRL_AC);
}
static int abov_glove_mode_enable(struct i2c_client *client, u8 cmd)
{
	return i2c_smbus_write_byte_data(client, ABOV_GLOVE, cmd);
}
static int abov_sleep_mode(struct i2c_client *client, u8 cmd)
{
	return i2c_smbus_write_byte_data(client, ABOV_BTNSTATUS, cmd);
}
Exemplo n.º 20
0
static int max8952_write_reg(struct max8952_data *max8952,
		u8 reg, u8 value)
{
	return i2c_smbus_write_byte_data(max8952->client, reg, value);
}
Exemplo n.º 21
0
static int max8698_i2c_write(struct i2c_client *client, u8 reg, u8 value)
{
	max8698_cache_regs[reg] = value;
	return i2c_smbus_write_byte_data(client, reg, value);
}
Exemplo n.º 22
0
static int da280_enable(struct i2c_client *client, bool enable)
{
	u8 data = enable ? DA280_MODE_ENABLE : DA280_MODE_DISABLE;

	return i2c_smbus_write_byte_data(client, DA280_REG_MODE_BW, data);
}
static int as7116_54x_fan_write_value(struct i2c_client *client, u8 reg, u8 value)
{
    return i2c_smbus_write_byte_data(client, reg, value);
}
Exemplo n.º 24
0
static int write_reg(struct i2c_client *client, u8 reg, u8 value)
{
	return i2c_smbus_write_byte_data(client, reg, value);
}
Exemplo n.º 25
0
static int wis_saa7113_command(struct i2c_client *client,
				unsigned int cmd, void *arg)
{
	struct wis_saa7113 *dec = i2c_get_clientdata(client);

	switch (cmd) {
	case VIDIOC_S_INPUT:
	{
		int *input = arg;

		i2c_smbus_write_byte_data(client, 0x02, 0xC0 | *input);
		i2c_smbus_write_byte_data(client, 0x09,
				*input < 6 ? 0x40 : 0x80);
		break;
	}
	case VIDIOC_S_STD:
	{
		v4l2_std_id *input = arg;
		dec->norm = *input;
		if (dec->norm & V4L2_STD_NTSC) {
			write_reg(client, 0x0e, 0x01);
			write_reg(client, 0x10, 0x40);
		} else if (dec->norm & V4L2_STD_PAL) {
			write_reg(client, 0x0e, 0x01);
			write_reg(client, 0x10, 0x48);
		} else if (dec->norm * V4L2_STD_SECAM) {
			write_reg(client, 0x0e, 0x50);
			write_reg(client, 0x10, 0x48);
		}
		break;
	}
	case VIDIOC_QUERYCTRL:
	{
		struct v4l2_queryctrl *ctrl = arg;

		switch (ctrl->id) {
		case V4L2_CID_BRIGHTNESS:
			ctrl->type = V4L2_CTRL_TYPE_INTEGER;
			strncpy(ctrl->name, "Brightness", sizeof(ctrl->name));
			ctrl->minimum = 0;
			ctrl->maximum = 255;
			ctrl->step = 1;
			ctrl->default_value = 128;
			ctrl->flags = 0;
			break;
		case V4L2_CID_CONTRAST:
			ctrl->type = V4L2_CTRL_TYPE_INTEGER;
			strncpy(ctrl->name, "Contrast", sizeof(ctrl->name));
			ctrl->minimum = 0;
			ctrl->maximum = 127;
			ctrl->step = 1;
			ctrl->default_value = 71;
			ctrl->flags = 0;
			break;
		case V4L2_CID_SATURATION:
			ctrl->type = V4L2_CTRL_TYPE_INTEGER;
			strncpy(ctrl->name, "Saturation", sizeof(ctrl->name));
			ctrl->minimum = 0;
			ctrl->maximum = 127;
			ctrl->step = 1;
			ctrl->default_value = 64;
			ctrl->flags = 0;
			break;
		case V4L2_CID_HUE:
			ctrl->type = V4L2_CTRL_TYPE_INTEGER;
			strncpy(ctrl->name, "Hue", sizeof(ctrl->name));
			ctrl->minimum = -128;
			ctrl->maximum = 127;
			ctrl->step = 1;
			ctrl->default_value = 0;
			ctrl->flags = 0;
			break;
		}
		break;
	}
	case VIDIOC_S_CTRL:
	{
		struct v4l2_control *ctrl = arg;

		switch (ctrl->id) {
		case V4L2_CID_BRIGHTNESS:
			if (ctrl->value > 255)
				dec->brightness = 255;
			else if (ctrl->value < 0)
				dec->brightness = 0;
			else
				dec->brightness = ctrl->value;
			write_reg(client, 0x0a, dec->brightness);
			break;
		case V4L2_CID_CONTRAST:
			if (ctrl->value > 127)
				dec->contrast = 127;
			else if (ctrl->value < 0)
				dec->contrast = 0;
			else
				dec->contrast = ctrl->value;
			write_reg(client, 0x0b, dec->contrast);
			break;
		case V4L2_CID_SATURATION:
			if (ctrl->value > 127)
				dec->saturation = 127;
			else if (ctrl->value < 0)
				dec->saturation = 0;
			else
				dec->saturation = ctrl->value;
			write_reg(client, 0x0c, dec->saturation);
			break;
		case V4L2_CID_HUE:
			if (ctrl->value > 127)
				dec->hue = 127;
			else if (ctrl->value < -128)
				dec->hue = -128;
			else
				dec->hue = ctrl->value;
			write_reg(client, 0x0d, dec->hue);
			break;
		}
		break;
	}
	case VIDIOC_G_CTRL:
	{
		struct v4l2_control *ctrl = arg;

		switch (ctrl->id) {
		case V4L2_CID_BRIGHTNESS:
			ctrl->value = dec->brightness;
			break;
		case V4L2_CID_CONTRAST:
			ctrl->value = dec->contrast;
			break;
		case V4L2_CID_SATURATION:
			ctrl->value = dec->saturation;
			break;
		case V4L2_CID_HUE:
			ctrl->value = dec->hue;
			break;
		}
		break;
	}
	default:
		break;
	}
	return 0;
}
Exemplo n.º 26
0
static inline int
isp1301_clear_bits(struct isp1301 *isp, u8 reg, u8 bits)
{
	return i2c_smbus_write_byte_data(isp->client, reg + 1, bits);
}
Exemplo n.º 27
0
int main(int argc, char *argv[])
{
	char *end;
	const char *maskp = NULL;
	int res, i2cbus, address, size, file;
	int value, daddress, vmask = 0;
	char filename[20];
	int pec = 0;
	int flags = 0;
	int force = 0, yes = 0, version = 0, readback = 0;

	/* handle (optional) flags first */
	while (1+flags < argc && argv[1+flags][0] == '-') {
		switch (argv[1+flags][1]) {
		case 'V': version = 1; break;
		case 'f': force = 1; break;
		case 'y': yes = 1; break;
		case 'm':
			if (2+flags < argc)
				maskp = argv[2+flags];
			flags++;
			break;
		case 'r': readback = 1; break;
		default:
			fprintf(stderr, "Error: Unsupported option "
				"\"%s\"!\n", argv[1+flags]);
			help();
			exit(1);
		}
		flags++;
	}

	if (version) {
		fprintf(stderr, "i2cset version %s\n", VERSION);
		exit(0);
	}

	if (argc < flags + 4)
		help();

	i2cbus = lookup_i2c_bus(argv[flags+1]);
	if (i2cbus < 0)
		help();

	address = parse_i2c_address(argv[flags+2]);
	if (address < 0)
		help();

	daddress = strtol(argv[flags+3], &end, 0);
	if (*end || daddress < 0 || daddress > 0xff) {
		fprintf(stderr, "Error: Data address invalid!\n");
		help();
	}

	if (argc > flags + 4) {
		size = I2C_SMBUS_BYTE_DATA;
		value = strtol(argv[flags+4], &end, 0);
		if (*end || value < 0) {
			fprintf(stderr, "Error: Data value invalid!\n");
			help();
		}
	} else {
		size = I2C_SMBUS_BYTE;
		value = -1;
	}

	if (argc > flags + 5) {
		switch (argv[flags+5][0]) {
		case 'b': size = I2C_SMBUS_BYTE_DATA; break;
		case 'w': size = I2C_SMBUS_WORD_DATA; break;
		default:
			fprintf(stderr, "Error: Invalid mode!\n");
			help();
		}
		pec = argv[flags+5][1] == 'p';
	}

	/* Old method to provide the value mask, deprecated and no longer
	   documented but still supported for compatibility */
	if (argc > flags + 6) {
		if (maskp) {
			fprintf(stderr, "Error: Data value mask provided twice!\n");
			help();
		}
		fprintf(stderr, "Warning: Using deprecated way to set the data value mask!\n");
		fprintf(stderr, "         Please switch to using -m.\n");
		maskp = argv[flags+6];
	}

	if (maskp) {
		vmask = strtol(maskp, &end, 0);
		if (*end || vmask == 0) {
			fprintf(stderr, "Error: Data value mask invalid!\n");
			help();
		}
	}

	if ((size == I2C_SMBUS_BYTE_DATA && value > 0xff)
	 || (size == I2C_SMBUS_WORD_DATA && value > 0xffff)) {
		fprintf(stderr, "Error: Data value out of range!\n");
		help();
	}

	file = open_i2c_dev(i2cbus, filename, 0);
	if (file < 0
	 || check_funcs(file, size, pec)
	 || set_slave_addr(file, address, force))
		exit(1);

	if (!yes && !confirm(filename, address, size, daddress,
			     value, vmask, pec))
		exit(0);

	if (vmask) {
		int oldvalue;

		switch (size) {
		case I2C_SMBUS_BYTE:
			oldvalue = i2c_smbus_read_byte(file);
			break;
		case I2C_SMBUS_WORD_DATA:
			oldvalue = i2c_smbus_read_word_data(file, daddress);
			break;
		default:
			oldvalue = i2c_smbus_read_byte_data(file, daddress);
		}

		if (oldvalue < 0) {
			fprintf(stderr, "Error: Failed to read old value\n");
			exit(1);
		}

		value = (value & vmask) | (oldvalue & ~vmask);

		if (!yes) {
			fprintf(stderr, "Old value 0x%0*x, write mask "
				"0x%0*x: Will write 0x%0*x to register "
				"0x%02x\n",
				size == I2C_SMBUS_WORD_DATA ? 4 : 2, oldvalue,
				size == I2C_SMBUS_WORD_DATA ? 4 : 2, vmask,
				size == I2C_SMBUS_WORD_DATA ? 4 : 2, value,
				daddress);

			fprintf(stderr, "Continue? [Y/n] ");
			fflush(stderr);
			if (!user_ack(1)) {
				fprintf(stderr, "Aborting on user request.\n");
				exit(0);
			}
		}
	}

	if (pec && ioctl(file, I2C_PEC, 1) < 0) {
		fprintf(stderr, "Error: Could not set PEC: %s\n",
			strerror(errno));
		close(file);
		exit(1);
	}

	switch (size) {
	case I2C_SMBUS_BYTE:
		res = i2c_smbus_write_byte(file, daddress);
		break;
	case I2C_SMBUS_WORD_DATA:
		res = i2c_smbus_write_word_data(file, daddress, value);
		break;
	default: /* I2C_SMBUS_BYTE_DATA */
		res = i2c_smbus_write_byte_data(file, daddress, value);
	}
	if (res < 0) {
		fprintf(stderr, "Error: Write failed\n");
		close(file);
		exit(1);
	}

	if (pec) {
		if (ioctl(file, I2C_PEC, 0) < 0) {
			fprintf(stderr, "Error: Could not clear PEC: %s\n",
				strerror(errno));
			close(file);
			exit(1);
		}
	}

	if (!readback) { /* We're done */
		close(file);
		exit(0);
	}

	switch (size) {
	case I2C_SMBUS_BYTE:
		res = i2c_smbus_read_byte(file);
		value = daddress;
		break;
	case I2C_SMBUS_WORD_DATA:
		res = i2c_smbus_read_word_data(file, daddress);
		break;
	default: /* I2C_SMBUS_BYTE_DATA */
		res = i2c_smbus_read_byte_data(file, daddress);
	}
	close(file);

	if (res < 0) {
		printf("Warning - readback failed\n");
	} else
	if (res != value) {
		printf("Warning - data mismatch - wrote "
		       "0x%0*x, read back 0x%0*x\n",
		       size == I2C_SMBUS_WORD_DATA ? 4 : 2, value,
		       size == I2C_SMBUS_WORD_DATA ? 4 : 2, res);
	} else {
		printf("Value 0x%0*x written, readback matched\n",
		       size == I2C_SMBUS_WORD_DATA ? 4 : 2, value);
	}

	exit(0);
}
Exemplo n.º 28
0
int adm1025_write_value(struct i2c_client *client, u8 reg, u8 value)
{
	return i2c_smbus_write_byte_data(client, reg, value);
}
Exemplo n.º 29
0
int pcf8591t_write_value(u8 reg, u8 value)
{
        return i2c_smbus_write_byte_data(g_client, reg, value);
}
Exemplo n.º 30
-1
static int mpr121_phys_init(const struct mpr121_platform_data *pdata,
                            struct mpr121_touchkey *mpr121,
                            struct i2c_client *client)
{
    const struct mpr121_init_register *reg;
    unsigned char usl, lsl, tl, eleconf;
    int i, t, vdd, ret;

    /* Set up touch/release threshold for ele0-ele11 */
    for (i = 0; i <= MPR121_MAX_KEY_COUNT; i++) {
        t = ELE0_TOUCH_THRESHOLD_ADDR + (i * 2);
        ret = i2c_smbus_write_byte_data(client, t, TOUCH_THRESHOLD);
        if (ret < 0)
            goto err_i2c_write;
        ret = i2c_smbus_write_byte_data(client, t + 1,
                                        RELEASE_THRESHOLD);
        if (ret < 0)
            goto err_i2c_write;
    }

    /* Set up init register */
    for (i = 0; i < ARRAY_SIZE(init_reg_table); i++) {
        reg = &init_reg_table[i];
        ret = i2c_smbus_write_byte_data(client, reg->addr, reg->val);
        if (ret < 0)
            goto err_i2c_write;
    }


    /*
     * Capacitance on sensing input varies and needs to be compensated.
     * The internal MPR121-auto-configuration can do this if it's
     * registers are set properly (based on pdata->vdd_uv).
     */
    vdd = pdata->vdd_uv / 1000;
    usl = ((vdd - 700) * 256) / vdd;
    lsl = (usl * 65) / 100;
    tl = (usl * 90) / 100;
    ret = i2c_smbus_write_byte_data(client, AUTO_CONFIG_USL_ADDR, usl);
    ret |= i2c_smbus_write_byte_data(client, AUTO_CONFIG_LSL_ADDR, lsl);
    ret |= i2c_smbus_write_byte_data(client, AUTO_CONFIG_TL_ADDR, tl);

    /*
     * Quick charge bit will let the capacitive charge to ready
     * state quickly, or the buttons may not function after system
     * boot.
     */
    eleconf = mpr121->keycount | ELECTRODE_CONF_QUICK_CHARGE;
    ret |= i2c_smbus_write_byte_data(client, ELECTRODE_CONF_ADDR,
                                     eleconf);
    if (ret != 0)
        goto err_i2c_write;

    dev_dbg(&client->dev, "set up with %x keys.\n", mpr121->keycount);

    return 0;

err_i2c_write:
    dev_err(&client->dev, "i2c write error: %d\n", ret);
    return ret;
}