Example #1
0
static int raspberrypiI2CReadReg16(int fd, int reg) {
	return i2c_smbus_read_word_data(fd, reg);
}
Example #2
0
static int read_r8d16(void *client, u8 reg)
{
	return i2c_smbus_read_word_data(client, reg);
}
Example #3
0
static int fsa9485_detect_dev(struct fsa9485_usbsw *usbsw)
{
	int device_type, ret;
	unsigned int val1, val2, adc;
	struct fsa9485_platform_data *pdata = usbsw->pdata;
	struct i2c_client *client = usbsw->client;
#if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2)
	u8 mhl_ret = 0;
#endif
	device_type = i2c_smbus_read_word_data(client, FSA9485_REG_DEV_T1);
	if (device_type < 0) {
		dev_err(&client->dev, "%s: err %d\n", __func__, device_type);
		return device_type;
	}
	val1 = device_type & 0xff;
	val2 = device_type >> 8;
	adc = i2c_smbus_read_byte_data(client, FSA9485_REG_ADC);

	if (usbsw->dock_attached)
		pdata->dock_cb(FSA9485_DETACHED_DOCK);

	if (adc == 0x10)
		val2 = DEV_SMARTDOCK;
	else if (adc == 0x12)
		val2 = DEV_AUDIO_DOCK;

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

	/* Attached */
	if (val1 || val2) {
		/* USB */
		if (val1 & DEV_USB || val2 & DEV_T2_USB_MASK) {
			dev_info(&client->dev, "usb connect\n");

			if (pdata->usb_cb) {
				if (pdata->charger_cb && force_fast_charge != 0) {
				  dev_info(&client->dev, "[imoseyon] fastcharge\n");
				  pdata->charger_cb(FSA9485_ATTACHED);
				} else pdata->usb_cb(FSA9485_ATTACHED);
			}

			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");

			if (pdata->usb_cdp_cb)
				pdata->usb_cdp_cb(FSA9485_ATTACHED);
			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);
			if (pdata->uart_cb)
				pdata->uart_cb(FSA9485_ATTACHED);

			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) {
			dev_info(&client->dev, "charger connect\n");

			if (pdata->charger_cb)
				pdata->charger_cb(FSA9485_ATTACHED);
		/* for SAMSUNG OTG */
		} else if (val1 & DEV_USB_OTG) {
			dev_info(&client->dev, "otg connect\n");
			if (pdata->otg_cb)
				pdata->otg_cb(FSA9485_ATTACHED);
			i2c_smbus_write_byte_data(client,
						FSA9485_REG_MANSW1, 0x27);
			i2c_smbus_write_byte_data(client,
						FSA9485_REG_MANSW2, 0x02);
			msleep(50);
			i2c_smbus_write_byte_data(client,
						FSA9485_REG_CTRL, 0x1a);
		/* JIG */
		} else if (val2 & DEV_T2_JIG_MASK) {
			dev_info(&client->dev, "jig connect\n");

			if (pdata->jig_cb)
				pdata->jig_cb(FSA9485_ATTACHED);
		/* Desk Dock */
		} else if (val2 & DEV_AV) {
			if ((adc & 0x1F) == ADC_DESKDOCK) {
				pr_info("FSA Deskdock Attach\n");
				FSA9485_CheckAndHookAudioDock(1);
				usbsw->deskdock = 1;
#if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2)
				isDeskdockconnected = 1;
#endif
				i2c_smbus_write_byte_data(client,
						FSA9485_REG_RESERVED_20, 0x08);
			} else {
				pr_info("FSA MHL Attach\n");
				i2c_smbus_write_byte_data(client,
						FSA9485_REG_RESERVED_20, 0x08);
#if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2)
				DisableFSA9480Interrupts();
				if (!isDeskdockconnected)
					mhl_ret = mhl_onoff_ex(1);

				if (mhl_ret != MHL_DEVICE &&
						(adc & 0x1F) == 0x1A) {
					FSA9485_CheckAndHookAudioDock(1);
					isDeskdockconnected = 1;
				}
				EnableFSA9480Interrupts();
#else
				pr_info("FSA mhl attach, but not support MHL feature!\n");
#endif
			}
		/* Car Dock */
		} else if (val2 & DEV_JIG_UART_ON) {
			if (pdata->dock_cb)
				pdata->dock_cb(FSA9485_ATTACHED_CAR_DOCK);
			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);

			if (pdata->smartdock_cb)
				pdata->smartdock_cb(FSA9485_ATTACHED);
#if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2)
			mhl_onoff_ex(1);
#endif
		} else if (val2 & DEV_AUDIO_DOCK) {
			usbsw->adc = adc;
			dev_info(&client->dev, "audio 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);

			if (pdata->smartdock_cb)
				pdata->audio_dock_cb(FSA9485_ATTACHED);
		}
	/* Detached */
	} else {
		/* USB */
		if (usbsw->dev1 & DEV_USB ||
				usbsw->dev2 & DEV_T2_USB_MASK) {
			if (pdata->usb_cb) {
			  if (pdata->charger_cb && force_fast_charge != 0) {
                            dev_info(&client->dev, "[imoseyon] fastcharge detached\n");
			    pdata->charger_cb(FSA9485_DETACHED); 
			  } else pdata->usb_cb(FSA9485_DETACHED);
			}
		} else if (usbsw->dev1 & DEV_USB_CHG) {
			if (pdata->usb_cdp_cb)
				pdata->usb_cdp_cb(FSA9485_DETACHED);

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

		/* CHARGER */
		} else if (usbsw->dev1 & DEV_T1_CHARGER_MASK) {
			if (pdata->charger_cb)
				pdata->charger_cb(FSA9485_DETACHED);
		/* 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) {
			if (pdata->jig_cb)
				pdata->jig_cb(FSA9485_DETACHED);
		/* Desk Dock */
		} else if (usbsw->dev2 & DEV_AV) {

			pr_info("FSA MHL Detach\n");
			i2c_smbus_write_byte_data(client,
					FSA9485_REG_RESERVED_20, 0x04);
#if defined(CONFIG_VIDEO_MHL_V1) || 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
			if (usbsw->deskdock) {
				FSA9485_CheckAndHookAudioDock(0);
				usbsw->deskdock = 0;
			} else {
				pr_info("FSA detach mhl cable, but not support MHL feature\n");
			}
#endif
		/* Car Dock */
		} else if (usbsw->dev2 & DEV_JIG_UART_ON) {
			if (pdata->dock_cb)
				pdata->dock_cb(FSA9485_DETACHED_DOCK);
				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);

			if (pdata->smartdock_cb)
				pdata->smartdock_cb(FSA9485_DETACHED);
			usbsw->adc = 0;
#if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2)
			mhl_onoff_ex(false);
#endif
		} else if (usbsw->adc == 0x12) {
			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);

			if (pdata->smartdock_cb)
				pdata->audio_dock_cb(FSA9485_DETACHED);
			usbsw->adc = 0;
		}

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

	return adc;
}
static int fsa9485_detect_dev(struct fsa9485_usbsw *usbsw)
{
	int device_type, ret;
	unsigned int dev1, dev2, dev3, adc;
	struct fsa9485_platform_data *pdata = usbsw->pdata;
	struct i2c_client *client = usbsw->client;
#if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2)
//	u8 mhl_ret = 0;
#endif
	pr_info("%s", __func__);

	device_type = i2c_smbus_read_word_data(client, FSA9485_REG_DEV_T1);
	if (device_type < 0) {
		dev_err(&client->dev, "%s: err %d\n", __func__, device_type);
		return device_type;
	}
	dev1 = device_type & 0xff;
	dev2 = device_type >> 8;

	jig_state = (dev2 & DEV_T2_JIG_MASK) ? 1 : 0;

	adc = i2c_smbus_read_byte_data(client, FSA9485_REG_ADC);

/* remove for right perform for lanhub / defence code for factory */
#if 0
	if (usbsw->dock_attached && usbsw->previous_dock == FSA9485_NONE)
		pdata->dock_cb(FSA9485_DETACHED_DOCK);
#endif

	if (local_usbsw->dock_ready == 1) {
		if (adc == 0x0f)
			dev2 = DEV_INCOMPATIBLE;
		else if (adc == 0x10)
			dev2 = DEV_SMARTDOCK;
		else if (adc == 0x12)
			dev2 = DEV_AUDIO_DOCK;
#ifdef CONFIG_MUIC_FSA9485_SUPPORT_LANHUB
		else if (adc == 0x13)
			dev2 = DEV_LANHUB;
#endif
		else if (adc == 0x14)
			dev2 = DEV_CHARGING_CABLE;
		else if (adc == 0x15){
			dev2 = DEV_MMDOCK;
			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);
			mmdock_connect = 1;
		}
	}

	dev3 = i2c_smbus_read_byte_data(client,
			FSA9485_REG_RESERVED_1D);
	if(dev3 < 0) {
		dev_err(&client->dev, "%s: err %d\n", __func__, dev3);
		return dev3;
	}
	dev3 = dev3 & 0x02;
	dev_info(&client->dev, "dev1: 0x%02x, dev2: 0x%02x,dev3: 0x%02x, adc: 0x%02x\n",
		dev1, dev2, dev3, adc);

	/* Attached */
	if (dev1 || dev2) {
		/* USB */
		if (dev1 & DEV_USB || dev2 & DEV_T2_USB_MASK) {
			dev_info(&client->dev, "usb connect\n");

			if (pdata->usb_cb)
				pdata->usb_cb(FSA9485_ATTACHED);
			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 (dev1 & DEV_USB_CHG) {
			dev_info(&client->dev, "usb_cdp connect\n");

			if (pdata->usb_cdp_cb)
				pdata->usb_cdp_cb(FSA9485_ATTACHED);
			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 (dev1 & DEV_T1_UART_MASK || dev2 & DEV_T2_UART_MASK) {
			uart_connecting = 1;
			dev_info(&client->dev, "uart connect\n");
			i2c_smbus_write_byte_data(client,
						FSA9485_REG_CTRL, 0x1E);
			if (pdata->uart_cb)
				pdata->uart_cb(FSA9485_ATTACHED);

			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 (dev1 & DEV_T1_CHARGER_MASK) {
			dev_info(&client->dev, "charger connect\n");

			if (pdata->charger_cb)
				pdata->charger_cb(FSA9485_ATTACHED);
		/* for SAMSUNG OTG */
		} else if (dev1 & DEV_USB_OTG) {
#ifdef CONFIG_MUIC_FSA9485_SUPPORT_LANHUB
			/* Enable RAWDATA Interrupts */
			fsa9485_enable_rawdataInterrupts();
#endif
			usbsw->dock_attached = FSA9485_ATTACHED;
#ifdef CONFIG_MUIC_FSA9485_SUPPORT_LANHUB
			usbsw->previous_dock = ADC_GND;
#endif
			dev_info(&client->dev, "otg connect\n");
			if (pdata->otg_cb)
				pdata->otg_cb(FSA9485_ATTACHED);
			i2c_smbus_write_byte_data(client,
						FSA9485_REG_MANSW1, 0x27);
			i2c_smbus_write_byte_data(client,
						FSA9485_REG_MANSW2, 0x02);
		/* JIG */
		} else if (dev2 & DEV_T2_JIG_MASK) {
			dev_info(&client->dev, "jig connect\n");

			if (pdata->jig_cb)
				pdata->jig_cb(FSA9485_ATTACHED);
		/* Desk Dock */
		} else if (dev2 & DEV_AV) {
			if ((adc & 0x1F) == ADC_DESKDOCK) {
				dev_info(&client->dev, "FSA Deskdock Attach\n");
				FSA9485_CheckAndHookAudioDock(1);
				usbsw->deskdock = 1;
#if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2)
				isDeskdockconnected = 1;
#endif
				i2c_smbus_write_byte_data(client,
						FSA9485_REG_RESERVED_20, 0x08);
			} else {
				dev_info(&client->dev, "FSA MHL Attach\n");
				i2c_smbus_write_byte_data(client,
						FSA9485_REG_RESERVED_20, 0x08);
#if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2)
				DisableFSA9485Interrupts();

				if (isMhlAttached != MHL_ATTACHED) {
					isMhlAttached = MHL_ATTACHED;
					schedule_delayed_work(&usbsw->mhl_work, msecs_to_jiffies(100));
				} else {
					dev_info(&client->dev, "FSA mhl is initializing... bypass\n");
				}

				EnableFSA9485Interrupts();
#else
				dev_info(&client->dev, "FSA mhl attach, but not support MHL feature!\n");
#endif
			}
		/* Car Dock */
		} else if (dev2 & DEV_JIG_UART_ON) {
#if !defined(CONFIG_MUIC_FSA9485_SUPPORT_CAR_DOCK)
			if (usbsw->is_factory_start) {
#endif
				dev_info(&client->dev, "car dock connect\n");

				if (pdata->dock_cb)
					pdata->dock_cb(FSA9485_ATTACHED_CAR_DOCK);
				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;
#if !defined(CONFIG_MUIC_FSA9485_SUPPORT_CAR_DOCK)
			} else {
				uart_connecting = 1;
				dev_info(&client->dev, "uart connect\n");
				i2c_smbus_write_byte_data(client,
						FSA9485_REG_CTRL, 0x1E);
				if (pdata->uart_cb)
					pdata->uart_cb(FSA9485_ATTACHED);

				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);
				}
			}
#endif /* !CONFIG_MUIC_FSA9485_SUPPORT_CAR_DOCK */
		} else if (dev2 & DEV_INCOMPATIBLE) {
			usbsw->adc = adc;
			dev_info(&client->dev, "Inompatible CHARGER connect\n");

			if (pdata->in_charger_cb)
				pdata->in_charger_cb(FSA9485_ATTACHED);
		/* SmartDock */
		} else if (dev2 & 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);

			if (pdata->smartdock_cb)
				pdata->smartdock_cb(FSA9485_ATTACHED);
#if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2)
//			mhl_onoff_ex(1);
#endif
		/*MMDock*/
		} else if ((dev2 & DEV_MMDOCK) && (dev3 & 0x02)) {
			if(mmdock_flag == 0)
				fsa9485_mmdock_attach();

		} else if (dev2 & DEV_AUDIO_DOCK) {
			usbsw->adc = adc;
			dev_info(&client->dev, "audio 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);

			if (pdata->audio_dock_cb)
				pdata->audio_dock_cb(FSA9485_ATTACHED);
#ifdef CONFIG_MUIC_FSA9485_SUPPORT_LANHUB
		/* LANHUB */
		} else if (dev2 & DEV_LANHUB) {
			/* Enable RAWDATA Interrupts */
			fsa9485_enable_rawdataInterrupts();

			usbsw->adc = adc;
			dev_info(&client->dev, "lanhub connect\n");

			usbsw->dock_attached = FSA9485_ATTACHED;
			usbsw->previous_dock = ADC_LANHUB;
			usbsw->lanhub_ta_status=1;

			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);

			if (pdata->lanhub_cb)
				pdata->lanhub_cb(FSA9485_ATTACHED);
#endif
		/* CHARGING CABLE */
		} else if (dev2 & DEV_CHARGING_CABLE) {
			dev_info(&client->dev, "charging cable connect\n");
			usbsw->dock_attached = FSA9485_ATTACHED;
			usbsw->adc = adc;

			if (pdata->charge_cb)
				pdata->charge_cb(FSA9485_ATTACHED);
		/* Incompatible */
		} else if (dev3 & DEV_VBUS_DEBOUNCE) {
			dev_info(&client->dev,
					"Unsupported ADC, VBUS is valid = CHARGER\n");
			if (pdata->charger_cb)
				pdata->charger_cb(FSA9485_ATTACHED);
		}
	/* Detached */
	} else {
		/* USB */
		if (usbsw->dev1 & DEV_USB ||
				usbsw->dev2 & DEV_T2_USB_MASK) {
			if (pdata->usb_cb)
				pdata->usb_cb(FSA9485_DETACHED);
		} else if (usbsw->dev1 & DEV_USB_CHG) {
			if (pdata->usb_cdp_cb)
				pdata->usb_cdp_cb(FSA9485_DETACHED);

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

		/* CHARGER */
		} else if (usbsw->dev1 & DEV_T1_CHARGER_MASK) {
			if (pdata->charger_cb)
				pdata->charger_cb(FSA9485_DETACHED);
		/* for SAMSUNG OTG */
		} else if (usbsw->dev1 & DEV_USB_OTG) {
#ifdef CONFIG_MUIC_FSA9485_SUPPORT_LANHUB
			/* Disable RAWDATA Interrupts */
			fsa9485_disable_rawdataInterrupts();
			dev_info(&client->dev, "%s:lanhub_ta_status(%d)\n",
					__func__, usbsw->lanhub_ta_status);
			if (pdata->otg_cb && usbsw->lanhub_ta_status == 0)
				pdata->otg_cb(FSA9485_DETACHED);
			else if (pdata->lanhub_cb && usbsw->lanhub_ta_status == 1)
				pdata->lanhub_cb(FSA9485_DETACHED);

			usbsw->dock_attached = FSA9485_DETACHED;
			usbsw->lanhub_ta_status=0;
#else
			if (pdata->otg_cb)
				pdata->otg_cb(FSA9485_DETACHED);
			usbsw->dock_attached = FSA9485_DETACHED;
#endif
			i2c_smbus_write_byte_data(client,
						FSA9485_REG_CTRL, 0x1E);
		/* JIG */
		} else if (usbsw->dev2 & DEV_T2_JIG_MASK) {
			if (pdata->jig_cb)
				pdata->jig_cb(FSA9485_DETACHED);
		/* Desk Dock */
		} else if (usbsw->dev2 & DEV_AV) {

			pr_info("FSA MHL Detach\n");
			i2c_smbus_write_byte_data(client,
					FSA9485_REG_RESERVED_20, 0x04);
#if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2)
			if (isDeskdockconnected)
				FSA9485_CheckAndHookAudioDock(0);

			isMhlAttached = MHL_DETACHED;
			cancel_delayed_work(&usbsw->mhl_work);
			schedule_delayed_work(&usbsw->mhl_work, msecs_to_jiffies(10));

			isDeskdockconnected = 0;
#else
			if (usbsw->deskdock) {
				FSA9485_CheckAndHookAudioDock(0);
				usbsw->deskdock = 0;
			} else {
				pr_info("FSA detach mhl cable, but not support MHL feature\n");
			}
#endif
		/* Car Dock */
		} else if (usbsw->dev2 & DEV_JIG_UART_ON) {
#if !defined(CONFIG_MUIC_FSA9485_SUPPORT_CAR_DOCK)
			if (usbsw->is_factory_start) {
#endif
				if (pdata->dock_cb)
					pdata->dock_cb(FSA9485_DETACHED_DOCK);
					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;
#if !defined(CONFIG_MUIC_FSA9485_SUPPORT_CAR_DOCK)
			} else {
				if (pdata->uart_cb)
					pdata->uart_cb(FSA9485_DETACHED);
				uart_connecting = 0;
				dev_info(&client->dev, "[FSA9485] uart disconnect\n");
			}
#endif /* !CONFIG_MUIC_FSA9485_SUPPORT_CAR_DOCK */
		} else if (usbsw->adc == 0x0f) {
			dev_info(&client->dev, "Incompatible Charger disconnect\n");

			if (pdata->in_charger_cb)
				pdata->in_charger_cb(FSA9485_DETACHED);
			usbsw->adc = 0;
		} 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);

			if (pdata->smartdock_cb)
				pdata->smartdock_cb(FSA9485_DETACHED);
			usbsw->adc = 0;
#if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2)
//			mhl_onoff_ex(false);
#endif
		} else if (usbsw->adc == 0x12) {
			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);

			if (pdata->audio_dock_cb)
				pdata->audio_dock_cb(FSA9485_DETACHED);
			usbsw->adc = 0;
#ifdef CONFIG_MUIC_FSA9485_SUPPORT_LANHUB
		/* LANHUB */
		} else if (usbsw->adc == 0x13) {
			dev_info(&client->dev, "lanhub disconnect\n");

			/* Disable RAWDATA Interrupts */
			fsa9485_disable_rawdataInterrupts();

			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);
			dev_info(&client->dev, "%s:lanhub_ta_status(%d)\n",
					__func__, usbsw->lanhub_ta_status);
			if (pdata->lanhub_cb && usbsw->lanhub_ta_status==1)
				pdata->lanhub_cb(FSA9485_DETACHED);
			else if (pdata->otg_cb && usbsw->lanhub_ta_status == 0)
				pdata->otg_cb(FSA9485_DETACHED);

			usbsw->dock_attached = FSA9485_DETACHED;
			usbsw->adc = 0;
			usbsw->lanhub_ta_status=0;
#endif
		/* Charging Cable */
		} else if (usbsw->adc == 0x14) {
			dev_info(&client->dev, "charging_cable disconnect\n");
			usbsw->dock_attached = FSA9485_DETACHED;
			usbsw->adc = 0;
			usbsw->dev2 = 0;
			if (pdata->charge_cb)
				pdata->charge_cb(FSA9485_DETACHED);
		/*MM DOCK*/
		}else if (mmdock_connect == 1) {
			mmdock_connect = 0;
			if(mmdock_flag == 1)
				fsa9485_mmdock_detach();

		} else if (usbsw->dev3 & DEV_VBUS_DEBOUNCE) {
			dev_info(&client->dev,
					"Unsupported adc, Charger disconnect\n");
			if (pdata->charger_cb)
				pdata->charger_cb(FSA9485_DETACHED);
		}
		/*	set auto mode	*/
		i2c_smbus_write_byte_data(client,FSA9485_REG_CTRL, 0x1E);
	}
	usbsw->dev1 = dev1;
	usbsw->dev2 = dev2;
	usbsw->dev3 = dev3;

	return adc;
}
/* SMBus specifies low byte first, but the TMP102 returns high byte first,
 * so we have to swab16 the values */
static inline int tmp102_read_reg(struct i2c_client *client, u8 reg)
{
	int result = i2c_smbus_read_word_data(client, reg);

	return result < 0 ? result : swab16(result);
}
Example #6
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;

	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 */
		if (val1 & DEV_T1_USB_MASK || val2 & DEV_T2_USB_MASK) {
			if (pdata->usb_cb)
				pdata->usb_cb(FSA9480_ATTACHED);
			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);
			}
		/* UART */
		} else if (val1 & DEV_T1_UART_MASK || val2 & DEV_T2_UART_MASK) {
			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);
			}
		/* 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);

			ret = i2c_smbus_write_byte_data(client,
					FSA9480_REG_MANSW1, SW_DHOST);
			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);
		}
	/* Detached */
	} else {
		/* USB */
		if (usbsw->dev1 & DEV_T1_USB_MASK ||
				usbsw->dev2 & DEV_T2_USB_MASK) {
			if (pdata->usb_cb)
				pdata->usb_cb(FSA9480_DETACHED);
		/* UART */
		} else if (usbsw->dev1 & DEV_T1_UART_MASK ||
				usbsw->dev2 & DEV_T2_UART_MASK) {
			if (pdata->uart_cb)
				pdata->uart_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);

			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);
		}
	}

	usbsw->dev1 = val1;
	usbsw->dev2 = val2;
}
Example #7
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;
	unsigned char block[I2C_SMBUS_BLOCK_MAX];
	int len;

	/* 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();
	}

	/* check for command/mode */
	if (argc == flags + 4) {
		/* Implicit "c" */
		size = I2C_SMBUS_BYTE;
	} else if (argc == flags + 5) {
		/* "c", "cp",  or implicit "b" */
		if (!strcmp(argv[flags+4], "c")
		 || !strcmp(argv[flags+4], "cp")) {
			size = I2C_SMBUS_BYTE;
			pec = argv[flags+4][1] == 'p';
		} else {
			size = I2C_SMBUS_BYTE_DATA;
		}
	} else {
		/* All other commands */
		if (strlen(argv[argc-1]) > 2
		    || (strlen(argv[argc-1]) == 2 && argv[argc-1][1] != 'p')) {
			fprintf(stderr, "Error: Invalid mode '%s'!\n", argv[argc-1]);
			help();
		}
		switch (argv[argc-1][0]) {
		case 'b': size = I2C_SMBUS_BYTE_DATA; break;
		case 'w': size = I2C_SMBUS_WORD_DATA; break;
		case 's': size = I2C_SMBUS_BLOCK_DATA; break;
		case 'i': size = I2C_SMBUS_I2C_BLOCK_DATA; break;
		default:
			fprintf(stderr, "Error: Invalid mode '%s'!\n", argv[argc-1]);
			help();
		}
		pec = argv[argc-1][1] == 'p';
		if (size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA) {
			if (pec && size == I2C_SMBUS_I2C_BLOCK_DATA) {
				fprintf(stderr, "Error: PEC not supported for I2C block writes!\n");
				help();
			}
			if (maskp) {
				fprintf(stderr, "Error: Mask not supported for block writes!\n");
				help();
			}
			if (argc > (int)sizeof(block) + flags + 5) {
				fprintf(stderr, "Error: Too many arguments!\n");
				help();
			}
		} else if (argc != flags + 6) {
			fprintf(stderr, "Error: Too many arguments!\n");
			help();
		}
	}

	len = 0; /* Must always initialize len since it is passed to confirm() */

	/* read values from command line */
	switch (size) {
	case I2C_SMBUS_BYTE_DATA:
	case I2C_SMBUS_WORD_DATA:
		value = strtol(argv[flags+4], &end, 0);
		if (*end || value < 0) {
			fprintf(stderr, "Error: Data value 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();
		}
		break;
	case I2C_SMBUS_BLOCK_DATA:
	case I2C_SMBUS_I2C_BLOCK_DATA:
		for (len = 0; len + flags + 5 < argc; len++) {
			value = strtol(argv[flags + len + 4], &end, 0);
			if (*end || value < 0) {
				fprintf(stderr, "Error: Data value invalid!\n");
				help();
			}
			if (value > 0xff) {
				fprintf(stderr, "Error: Data value out of range!\n");
				help();
			}
			block[len] = value;
		}
		value = -1;
		break;
	default:
		value = -1;
		break;
	}

	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 || size == I2C_SMBUS_BYTE_DATA)
		     && vmask > 0xff) || vmask > 0xffff) {
			fprintf(stderr, "Error: Data value mask out of range!\n");
			help();
		}
	}

	file = open_i2c_dev(i2cbus, filename, sizeof(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, block, len, 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;
	case I2C_SMBUS_BLOCK_DATA:
		res = i2c_smbus_write_block_data(file, daddress, len, block);
		break;
	case I2C_SMBUS_I2C_BLOCK_DATA:
		res = i2c_smbus_write_i2c_block_data(file, daddress, len, block);
		break;
	default: /* I2C_SMBUS_BYTE_DATA */
		res = i2c_smbus_write_byte_data(file, daddress, value);
		break;
	}
	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);
}
int main() {

	int file;
	int adapter_nr = 1; /* probably dynamically determined */
	char filename[20];
	int addr = 0x69; 
	
	snprintf(filename, 19, "/dev/i2c-%d", adapter_nr);
	file = open(filename, O_RDWR);
	if (file < 0) {
		/* ERROR HANDLING; you can check errno to see what went wrong */
		printf("Failed to open the bus.\n");
		exit(1);
	}
	    
    unsigned long funcs;
    
	if (ioctl(file, I2C_FUNCS, &funcs) < 0) {
        printf("Failed to get funcs.\n");
    }else{
		printf("Funcs: %x\n", funcs);
    }
	
	if (ioctl(file,I2C_SLAVE, addr) < 0) {
        printf("Failed to acquire bus access and/or talk to slave.\n");
        exit(1);
    }
    
	char c;
	int reg, value, res;
	do {
		scanf("%c", &c);
		if (c != 'e') {
			printf("Reg: ");
			scanf("%d", &reg);
		}
		switch (c) {
			case 'w':
				printf("Val: ");
				scanf("%d", &value);
				if (i2c_smbus_write_byte_data(file, reg, value) < 0)
					printf("Error!\n");				
				break;
			case 'W':
				printf("Val: ");
				scanf("%d", &value);
				if (i2c_smbus_write_word_data(file, reg, value) < 0)
					printf("Error!\n");				
				break;
			case 'r':
				res = i2c_smbus_read_byte_data(file, reg);
				if (res < 0) {
					printf("Error!\n");				
				}else{
					printf("Res: %x\n", res);
				}
				break;
			case 'R':
				res = i2c_smbus_read_word_data(file, reg);
				if (res < 0) {
					printf("Error!\n");				
				}else{
					printf("Res: %x\n", res);
				}
				break;
		}
	}while(c != 'e');
    
}
Example #9
0
static acpi_status
acpi_i2c_space_handler(u32 function, acpi_physical_address command,
			u32 bits, u64 *value64,
			void *handler_context, void *region_context)
{
	struct gsb_buffer *gsb = (struct gsb_buffer *)value64;
	struct acpi_i2c_handler_data *data = handler_context;
	struct acpi_connection_info *info = &data->info;
	struct acpi_resource_i2c_serialbus *sb;
	struct i2c_adapter *adapter = data->adapter;
	struct i2c_client client;
	struct acpi_resource *ares;
	u32 accessor_type = function >> 16;
	u8 action = function & ACPI_IO_MASK;
	acpi_status ret = AE_OK;
	int status;

	ret = acpi_buffer_to_resource(info->connection, info->length, &ares);
	if (ACPI_FAILURE(ret))
		return ret;

	if (!value64 || ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) {
		ret = AE_BAD_PARAMETER;
		goto err;
	}

	sb = &ares->data.i2c_serial_bus;
	if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_I2C) {
		ret = AE_BAD_PARAMETER;
		goto err;
	}

	memset(&client, 0, sizeof(client));
	client.adapter = adapter;
	client.addr = sb->slave_address;
	client.flags = 0;

	if (sb->access_mode == ACPI_I2C_10BIT_MODE)
		client.flags |= I2C_CLIENT_TEN;

	switch (accessor_type) {
	case ACPI_GSB_ACCESS_ATTRIB_SEND_RCV:
		if (action == ACPI_READ) {
			status = i2c_smbus_read_byte(&client);
			if (status >= 0) {
				gsb->bdata = status;
				status = 0;
			}
		} else {
			status = i2c_smbus_write_byte(&client, gsb->bdata);
		}
		break;

	case ACPI_GSB_ACCESS_ATTRIB_BYTE:
		if (action == ACPI_READ) {
			status = i2c_smbus_read_byte_data(&client, command);
			if (status >= 0) {
				gsb->bdata = status;
				status = 0;
			}
		} else {
			status = i2c_smbus_write_byte_data(&client, command,
					gsb->bdata);
		}
		break;

	case ACPI_GSB_ACCESS_ATTRIB_WORD:
		if (action == ACPI_READ) {
			status = i2c_smbus_read_word_data(&client, command);
			if (status >= 0) {
				gsb->wdata = status;
				status = 0;
			}
		} else {
			status = i2c_smbus_write_word_data(&client, command,
					gsb->wdata);
		}
		break;

	case ACPI_GSB_ACCESS_ATTRIB_BLOCK:
		if (action == ACPI_READ) {
			status = i2c_smbus_read_block_data(&client, command,
					gsb->data);
			if (status >= 0) {
				gsb->len = status;
				status = 0;
			}
		} else {
			status = i2c_smbus_write_block_data(&client, command,
					gsb->len, gsb->data);
		}
		break;

	case ACPI_GSB_ACCESS_ATTRIB_MULTIBYTE:
		if (action == ACPI_READ) {
			status = acpi_gsb_i2c_read_bytes(&client, command,
					gsb->data, info->access_length);
			if (status > 0)
				status = 0;
		} else {
			status = acpi_gsb_i2c_write_bytes(&client, command,
					gsb->data, info->access_length);
		}
		break;

	default:
		pr_info("protocol(0x%02x) is not supported.\n", accessor_type);
		ret = AE_BAD_PARAMETER;
		goto err;
	}

	gsb->status = status;

 err:
	ACPI_FREE(ares);
	return ret;
}
Example #10
0
static int
update_params(void)
{
	int status;
	int retval = 1;
	static u64 first_failure = 0;

	if (!ltc4100_attached) return 0;

	down(&update_mutex);

	status = i2c_smbus_read_word_data(&client_ltc4100, 0x13);

	if (status != -1) {
		if (first_failure) {
			printk(KERN_DEBUG "Time between failures: %llu\n",
				jiffies_64 - first_failure);
			first_failure = 0;
		}

		last_update    = jiffies_64;
		onAC           = (status & (1 << 15)) ? 1 : 0;
		batteryPresent = (status & (1 << 14)) ? 1 : 0;

		if (machine_is_ghi270()) {
			batteryCharging =
				pxa_gpio_get_value(GHI270_H_GPIO26_CHGEN)?1:0;
		} else {
			batteryCharging =
				pxa_gpio_get_value(GHI270_HG_GPIO53_CHGEN)?1:0;
		}

		rsoc        = 0;
		voltage     = 0;
		temp        = 0;
		time        = 0;
		current_now = 0;

		if (batteryPresent && bq20z80_attached) {
			/* Only read the battery itself when it is there. */
			int tmp;
			tmp = i2c_smbus_read_word_data(&client_bq20z80, 0xd);
			if (tmp != -1) {
				/* Relative state of charge */
				pr_debug("RSOC: %d\n", tmp);
				rsoc = tmp;
			} else printk(KERN_ERR "rsoc fail\n");
			tmp = i2c_smbus_read_word_data(&client_bq20z80, 0x9);
			if (tmp != -1) {
				pr_debug("Voltage: %d\n", tmp);
				voltage = tmp;
			} else printk(KERN_ERR "voltage fail\n");
			tmp = i2c_smbus_read_word_data(&client_bq20z80, 0x8);
			if (tmp != -1) {
				pr_debug("Temperature: %d\n", tmp);
				temp = tmp;
			} else printk(KERN_ERR "temp fail\n");
			tmp = i2c_smbus_read_word_data(&client_bq20z80, 0x11);
			if (tmp != -1) {
				pr_debug("Time: %d\n", tmp);
				time = tmp;
			} else printk(KERN_ERR "time fail\n");
			tmp = i2c_smbus_read_word_data(&client_bq20z80, 0xa);
			if (tmp != -1) {
				pr_debug("Current: %d\n", tmp);
				current_now = -((short)tmp);
			} else printk(KERN_ERR "current fail\n");
		}
	} else {
		retval = 0;
		if (!first_failure) {
			/* There has been a problem with reading the LTC4100
			 * on the proto HG that I'm using.  Hopefully others
			 * will not have this problem.  The H does not, and
			 * the battery circuitry is the same.
			 */
			printk(KERN_DEBUG "First failure\n");
			first_failure = jiffies_64;
		}
	}

	up(&update_mutex);

	return retval;
}
Example #11
0
static int
detect(struct i2c_adapter *adapter, int address, int kind)
{
	int err = 0;

	if (address == 9) {
		/* LTC4100 */

		if (!i2c_check_functionality(adapter,
				I2C_FUNC_SMBUS_WORD_DATA)) {
			goto exit;
		}

		memset(&client_ltc4100, 0, sizeof(client_ltc4100));

		i2c_set_clientdata(&client_ltc4100, &client_ltc4100);
		client_ltc4100.addr = address;
		client_ltc4100.adapter = adapter;
		client_ltc4100.driver = &ghi270_driver;
		strlcpy(client_ltc4100.name, "ghi270_ltc4100", I2C_NAME_SIZE);

		if (0x2 !=
		    (err = i2c_smbus_read_word_data(&client_ltc4100, 0x11))) {
			if (err != -1) {
				printk(KERN_ERR "Did not read expected\n");
			}
		}

		if ((err = i2c_attach_client(&client_ltc4100))) {
			goto exit;
		}

		INIT_DELAYED_WORK(&battery_work, battery_work_callback);
		if (!update_params()) {
			mdelay(100);
			if (!update_params()) {
				mdelay(100);
				if (!update_params()) {
				    printk(KERN_ERR "Battery update fail\n");
				}
			}
		}
#		ifdef CONFIG_POWER_SUPPLY
			power_supply_register(0, &battery_info);
#		endif
		ltc4100_attached = 1;
	} else {
		/* bq20z80 */
		if (bq20z80_attached) {
			printk(KERN_ERR "Already Attached!!\n");
			return 0;
		}


		memset(&client_bq20z80, 0, sizeof(client_bq20z80));

		i2c_set_clientdata(&client_bq20z80, &client_bq20z80);
		client_bq20z80.addr = address;
		client_bq20z80.adapter = adapter;
		client_bq20z80.driver = &ghi270_driver;
		strlcpy(client_bq20z80.name, "ghi270_bq20z80", I2C_NAME_SIZE);

		/* This device may not be on the i2c bus at any given time
		 * because it is in the battery itself. */

		if ((err = i2c_attach_client(&client_bq20z80))) {
			goto exit;
		}
		bq20z80_attached = 1;
	}
	return 0;

exit:
	return err;
}
Example #12
0
int main(int argc, char *argv[])
{
	char *end;
	int res, i2cbus, address, size, file;
	int daddress;
	char filename[20];
	int pec = 0;
	int flags = 0;
	int force = 0, yes = 0, version = 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;
		default:
			fprintf(stderr, "Error: Unsupported option "
				"\"%s\"!\n", argv[1+flags]);
			help();
			exit(1);
		}
		flags++;
	}

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

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

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

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

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

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

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

	if (!yes && !confirm(filename, address, size, daddress, pec))
		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:
		if (daddress >= 0) {
#if 1
/*Use eepromer for large eeproms with two-byte addresses:*/
            __u8 buf[2] = { (daddress >> 8) & 0x0ff, daddress & 0x0ff};
/*            ioctl(file, BLKFLSBUF); // clear kernel read buffer*/
            res =i2c_smbus_write_byte_data(file, buf[0], buf[1]);
#else
/*Use eeprom for small eeproms with one-byte addresses:*/
/*            res = i2c_smbus_write_byte(file, daddress);*/
#endif
			if (res < 0)
				fprintf(stderr, "Warning - write failed\n");
		}
/*        ioctl(file, BLKFLSBUF); // clear kernel read buffer*/
		res = i2c_smbus_read_byte(file);
		break;
	case I2C_SMBUS_WORD_DATA:
        {
#if 1
/*Use eepromer for large eeproms with two-byte addresses:*/
/*            __u8 buf[2] = { (daddress >> 8) & 0x0ff, daddress & 0x0ff};*/
            __u8 buf[2] = { 0x00, 0x00};
/*            ioctl(file, BLKFLSBUF); // clear kernel read buffer*/
            res =i2c_smbus_write_byte_data(file, buf[0], buf[1]);
#endif
            res = i2c_smbus_read_word_data(file, daddress);
        }
		break;
	default: /* I2C_SMBUS_BYTE_DATA */
        {
#if 1
/*Use eepromer for large eeproms with two-byte addresses:*/
/*            __u8 buf[2] = { (daddress >> 8) & 0x0ff, daddress & 0x0ff};*/
            __u8 buf[2] = { 0x00, 0x00};
/*            ioctl(file, BLKFLSBUF); // clear kernel read buffer*/
            res =i2c_smbus_write_byte_data(file, buf[0], buf[1]);
#endif
            res = i2c_smbus_read_byte_data(file, daddress);
        }
	}
static inline int
isp1301_get_u16(struct isp1301 *isp, u8 reg)
{
	return i2c_smbus_read_word_data(&isp->client, reg);
}
/* no error returns, they'd just make bus scanning stop */
static int isp1301_probe(struct i2c_adapter *bus, int address, int kind)
{
	int			status;
	struct isp1301		*isp;
	struct i2c_client	*i2c;

	if (the_transceiver)
		return 0;

	isp = kzalloc(sizeof *isp, GFP_KERNEL);
	if (!isp)
		return 0;

	INIT_WORK(&isp->work, isp1301_work);
	init_timer(&isp->timer);
	isp->timer.function = isp1301_timer;
	isp->timer.data = (unsigned long) isp;

	isp->irq = -1;
	isp->client.addr = address;
	i2c_set_clientdata(&isp->client, isp);
	isp->client.adapter = bus;
	isp->client.driver = &isp1301_driver;
	strlcpy(isp->client.name, DRIVER_NAME, I2C_NAME_SIZE);
	i2c = &isp->client;

	/* if this is a true probe, verify the chip ... */
	if (kind < 0) {
		status = isp1301_get_u16(isp, ISP1301_VENDOR_ID);
		if (status != I2C_VENDOR_ID_PHILIPS) {
			dev_dbg(&bus->dev, "addr %d not philips id: %d\n",
				address, status);
			goto fail1;
		}
		status = isp1301_get_u16(isp, ISP1301_PRODUCT_ID);
		if (status != I2C_PRODUCT_ID_PHILIPS_1301) {
			dev_dbg(&bus->dev, "%d not isp1301, %d\n",
				address, status);
			goto fail1;
		}
	}

	status = i2c_attach_client(i2c);
	if (status < 0) {
		dev_dbg(&bus->dev, "can't attach %s to device %d, err %d\n",
				DRIVER_NAME, address, status);
fail1:
		kfree(isp);
		return 0;
	}
	isp->i2c_release = i2c->dev.release;
	i2c->dev.release = isp1301_release;

	/* initial development used chiprev 2.00 */
	status = i2c_smbus_read_word_data(i2c, ISP1301_BCD_DEVICE);
	dev_info(&i2c->dev, "chiprev %x.%02x, driver " DRIVER_VERSION "\n",
		status >> 8, status & 0xff);

	/* make like power-on reset */
	isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_MASK);

	isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, MC2_BI_DI);
	isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_2, ~MC2_BI_DI);

	isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1,
				OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN);
	isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1,
				~(OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN));

	isp1301_clear_bits(isp, ISP1301_INTERRUPT_LATCH, ~0);
	isp1301_clear_bits(isp, ISP1301_INTERRUPT_FALLING, ~0);
	isp1301_clear_bits(isp, ISP1301_INTERRUPT_RISING, ~0);

#ifdef	CONFIG_USB_OTG
	status = otg_bind(isp);
	if (status < 0) {
		dev_dbg(&i2c->dev, "can't bind OTG\n");
		goto fail2;
	}
#endif

	if (machine_is_omap_h2()) {
		/* full speed signaling by default */
		isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1,
			MC1_SPEED_REG);
		isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2,
			MC2_SPD_SUSP_CTRL);

		/* IRQ wired at M14 */
		omap_cfg_reg(M14_1510_GPIO2);
		isp->irq = OMAP_GPIO_IRQ(2);
		if (gpio_request(2, "isp1301") == 0)
			gpio_direction_input(2);
		isp->irq_type = IRQF_TRIGGER_FALLING;
	}

	isp->irq_type |= IRQF_SAMPLE_RANDOM;
	status = request_irq(isp->irq, isp1301_irq,
			isp->irq_type, DRIVER_NAME, isp);
	if (status < 0) {
		dev_dbg(&i2c->dev, "can't get IRQ %d, err %d\n",
				isp->irq, status);
#ifdef	CONFIG_USB_OTG
fail2:
#endif
		i2c_detach_client(i2c);
		goto fail1;
	}

	isp->otg.dev = &isp->client.dev;
	isp->otg.label = DRIVER_NAME;

	isp->otg.set_host = isp1301_set_host,
	isp->otg.set_peripheral = isp1301_set_peripheral,
	isp->otg.set_power = isp1301_set_power,
	isp->otg.start_srp = isp1301_start_srp,
	isp->otg.start_hnp = isp1301_start_hnp,

	enable_vbus_draw(isp, 0);
	power_down(isp);
	the_transceiver = isp;

#ifdef	CONFIG_USB_OTG
	update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE));
	update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS));
#endif

	dump_regs(isp, __func__);

#ifdef	VERBOSE
	mod_timer(&isp->timer, jiffies + TIMER_JIFFIES);
	dev_dbg(&i2c->dev, "scheduled timer, %d min\n", TIMER_MINUTES);
#endif

	status = otg_set_transceiver(&isp->otg);
	if (status < 0)
		dev_err(&i2c->dev, "can't register transceiver, %d\n",
			status);

	return 0;
}
Example #15
0
static int ad7152_read_raw(struct iio_dev *indio_dev,
			   struct iio_chan_spec const *chan,
			   int *val, int *val2,
			   long mask)
{
	struct ad7152_chip_info *chip = iio_priv(indio_dev);
	int ret;
	u8 regval = 0;

	mutex_lock(&indio_dev->mlock);

	switch (mask) {
	case 0:
		/* First set whether in differential mode */

		regval = chip->setup[chan->channel];

		if (chan->differential)
			chip->setup[chan->channel] |= AD7152_SETUP_CAPDIFF;
		else
			chip->setup[chan->channel] &= ~AD7152_SETUP_CAPDIFF;

		if (regval != chip->setup[chan->channel]) {
			ret = i2c_smbus_write_byte_data(chip->client,
				ad7152_addresses[chan->channel][AD7152_SETUP],
				chip->setup[chan->channel]);
			if (ret < 0)
				goto out;
		}
		/* Make sure the channel is enabled */
		if (chan->channel == 0)
			regval = AD7152_CONF_CH1EN;
		else
			regval = AD7152_CONF_CH2EN;

		/* Trigger a single read */
		regval |= AD7152_CONF_MODE_SINGLE_CONV;
		ret = i2c_smbus_write_byte_data(chip->client, AD7152_REG_CFG,
				regval);
		if (ret < 0)
			goto out;

		msleep(ad7152_filter_rate_table[chip->filter_rate_setup][1]);
		/* Now read the actual register */
		ret = i2c_smbus_read_word_data(chip->client,
				ad7152_addresses[chan->channel][AD7152_DATA]);
		if (ret < 0)
			goto out;
		*val = swab16(ret);

		if (chan->differential)
			*val -= 0x8000;

		ret = IIO_VAL_INT;
		break;
	case IIO_CHAN_INFO_CALIBSCALE:

		ret = i2c_smbus_read_word_data(chip->client,
				ad7152_addresses[chan->channel][AD7152_GAIN]);
		if (ret < 0)
			goto out;
		/* 1 + gain_val / 2^16 */
		*val = 1;
		*val2 = (15625 * swab16(ret)) / 1024;

		ret = IIO_VAL_INT_PLUS_MICRO;
		break;
	case IIO_CHAN_INFO_CALIBBIAS:
		ret = i2c_smbus_read_word_data(chip->client,
				ad7152_addresses[chan->channel][AD7152_OFFS]);
		if (ret < 0)
			goto out;
		*val = swab16(ret);

		ret = IIO_VAL_INT;
		break;
	case IIO_CHAN_INFO_SCALE:
		ret = i2c_smbus_read_byte_data(chip->client,
				ad7152_addresses[chan->channel][AD7152_SETUP]);
		if (ret < 0)
			goto out;
		*val = 0;
		*val2 = ad7152_scale_table[ret >> 6];

		ret = IIO_VAL_INT_PLUS_NANO;
		break;
	default:
		ret = -EINVAL;
	};
out:
	mutex_unlock(&indio_dev->mlock);
	return ret;
}
Example #16
0
static int bma250_probe(struct i2c_client *client,
		const struct i2c_device_id *id)
{
	int err = 0;
	int tempvalue;
	struct bma250_data *data;

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		printk(KERN_INFO "i2c_check_functionality error\n");
		goto exit;
	}
	data = kzalloc(sizeof(struct bma250_data), GFP_KERNEL);
	if (!data) {
		err = -ENOMEM;
		goto exit;
	}
	/* read chip id */
	tempvalue = 0;
	tempvalue = i2c_smbus_read_word_data(client, BMA250_CHIP_ID_REG);

	if ((tempvalue&0x00FF) == BMA250_CHIP_ID) {
		printk(KERN_INFO "Bosch Sensortec Device detected!\n" \
				"BMA250 registered I2C driver!\n");
	} else{
		printk(KERN_INFO "Bosch Sensortec Device not found, \
				i2c error %d \n", tempvalue);
		err = -1;
		goto kfree_exit;
	}
	i2c_set_clientdata(client, data);
	data->bma250_client = client;
	mutex_init(&data->mode_mutex);
	mutex_init(&data->enable_mutex);
	bma250_set_bandwidth(client, BMA250_BW_SET);
	bma250_set_range(client, BMA250_RANGE_SET);

	INIT_DELAYED_WORK(&data->work, bma250_work_func);
	atomic_set(&data->delay, BMA250_DEFAULT_DELAY);
	atomic_set(&data->enable, 0);
	err = bma250_input_init(data);
	if (err < 0)
		goto kfree_exit;

	err = sysfs_create_group(&data->input->dev.kobj,
			&bma250_attribute_group);
	if (err < 0)
		goto error_sysfs;

#ifdef CONFIG_HAS_EARLYSUSPEND
	data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	data->early_suspend.suspend = bma250_early_suspend;
	data->early_suspend.resume = bma250_late_resume;
	register_early_suspend(&data->early_suspend);
#endif
	err = bma250_set_mode(client, BMA250_MODE_SUSPEND);
	if (err)
		goto error_sysfs;

	return 0;

error_sysfs:
	bma250_input_delete(data);

kfree_exit:
	kfree(data);
exit:
	return err;
}
Example #17
0
static int reg_read(struct i2c_client *client, const u8 reg)
{
	s32 data = i2c_smbus_read_word_data(client, reg);
	return data < 0 ? data : swab16(data);
}
Example #18
0
int main(int argc, char *argv[])
{
	int i, j, res, i2cbus, address, size, file;
	int bank = 0;
	char filename[20];
	int block[256], s_length = 0;
	int pec = 0, even = 0;
	int force = 0;
	int first = 0x00, last = 0xff;

        char addr[6];
        int addrSize = sizeof(addr);
        int addrPos = 0;

	i2cbus = I2C_BUS_NUM;
	if (i2cbus < 0) {
		exit(1);
	}

	address = I2C_EEPROM_ADDR;
	if (address < 0) {
		exit(1);
	}
	size = I2C_SMBUS_BYTE_DATA;

	first = I2C_EEPROM_RANGE_FIRST;
	last = I2C_EEPROM_RANGE_LAST;

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

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

	/* handle all but word data */
	if (size != I2C_SMBUS_WORD_DATA || even) {
		/* do the block transaction */
		if (size == I2C_SMBUS_BLOCK_DATA
		 || size == I2C_SMBUS_I2C_BLOCK_DATA) {
			unsigned char cblock[288];

			if (size == I2C_SMBUS_BLOCK_DATA) {
				res = i2c_smbus_read_block_data(file, bank,
				      cblock);
			} else {
				for (res = 0; res < 256; res += i) {
					i = i2c_smbus_read_i2c_block_data(file,
						res, 32, cblock + res);
					if (i <= 0) {
						res = i;
						break;
					}
				}
			}
			if (res <= 0) {
				fprintf(stderr, "Error: Block read failed, "
					"return code %d\n", res);
				exit(1);
			}
			if (res >= 256)
				res = 256;
			for (i = 0; i < res; i++)
				block[i] = cblock[i];
			if (size != I2C_SMBUS_BLOCK_DATA)
				for (i = res; i < 256; i++)
					block[i] = -1;
		}

		if (size == I2C_SMBUS_BYTE) {
			res = i2c_smbus_write_byte(file, first);
			if(res != 0) {
				fprintf(stderr, "Error: Write start address "
					"failed, return code %d\n", res);
				exit(1);
			}
		}

		i = first;
		for (j = 0; j <= (last-first); j++) {
			fflush(stdout);
			/* Skip unwanted registers */
			if (i+j < first || i+j > last) {
				if (size == I2C_SMBUS_WORD_DATA) {
					j++;
				}
				continue;
			}

			if (size == I2C_SMBUS_BYTE_DATA) {
				block[i+j] = res =
					i2c_smbus_read_byte_data(file, i+j);
			} else if (size == I2C_SMBUS_WORD_DATA) {
				res = i2c_smbus_read_word_data(file,
						i+j);
				if (res < 0) {
					block[i+j] = res;
					block[i+j+1] = res;
				} else {
					block[i+j] = res & 0xff;
					block[i+j+1] = res >> 8;
				}
			} else if (size == I2C_SMBUS_BYTE) {
				block[i+j] = res =
					i2c_smbus_read_byte(file);
			} else
				res = block[i+j];

			if (size == I2C_SMBUS_BLOCK_DATA
					&& i+j >= s_length) {
				printf("   ");
			} else if (res < 0) {
				printf("XX ");
				if (size == I2C_SMBUS_WORD_DATA)
					printf("XX ");
			} else {
                                if(addrPos < addrSize)
                                {
                                  addr[addrPos] = block[i+j];
                                  addrPos++;
                                }
                                else
                                {
                                  fprintf(stderr, "ERROR: MAC Address buffer overflow\n");
                                  exit(1);
                                }
			}
			if (size == I2C_SMBUS_WORD_DATA)
				j++;
		}
static int mlx90614_read_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *channel, int *val,
			    int *val2, long mask)
{
	struct mlx90614_data *data = iio_priv(indio_dev);
	u8 cmd;
	s32 ret;

	switch (mask) {
	case IIO_CHAN_INFO_RAW: /* 0.02K / LSB */
		switch (channel->channel2) {
		case IIO_MOD_TEMP_AMBIENT:
			cmd = MLX90614_TA;
			break;
		case IIO_MOD_TEMP_OBJECT:
			switch (channel->channel) {
			case 0:
				cmd = MLX90614_TOBJ1;
				break;
			case 1:
				cmd = MLX90614_TOBJ2;
				break;
			default:
				return -EINVAL;
			}
			break;
		default:
			return -EINVAL;
		}

		ret = mlx90614_power_get(data, true);
		if (ret < 0)
			return ret;
		ret = i2c_smbus_read_word_data(data->client, cmd);
		mlx90614_power_put(data);

		if (ret < 0)
			return ret;

		/* MSB is an error flag */
		if (ret & 0x8000)
			return -EIO;

		*val = ret;
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_OFFSET:
		*val = MLX90614_CONST_OFFSET_DEC;
		*val2 = MLX90614_CONST_OFFSET_REM;
		return IIO_VAL_INT_PLUS_MICRO;
	case IIO_CHAN_INFO_SCALE:
		*val = MLX90614_CONST_SCALE;
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_CALIBEMISSIVITY: /* 1/65535 / LSB */
		mlx90614_power_get(data, false);
		mutex_lock(&data->lock);
		ret = i2c_smbus_read_word_data(data->client,
					       MLX90614_EMISSIVITY);
		mutex_unlock(&data->lock);
		mlx90614_power_put(data);

		if (ret < 0)
			return ret;

		if (ret == MLX90614_CONST_RAW_EMISSIVITY_MAX) {
			*val = 1;
			*val2 = 0;
		} else {
			*val = 0;
			*val2 = ret * MLX90614_CONST_EMISSIVITY_RESOLUTION;
		}
		return IIO_VAL_INT_PLUS_NANO;
	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: /* IIR setting with
							     FIR = 1024 */
		mlx90614_power_get(data, false);
		mutex_lock(&data->lock);
		ret = i2c_smbus_read_word_data(data->client, MLX90614_CONFIG);
		mutex_unlock(&data->lock);
		mlx90614_power_put(data);

		if (ret < 0)
			return ret;

		*val = mlx90614_iir_values[ret & MLX90614_CONFIG_IIR_MASK] / 100;
		*val2 = (mlx90614_iir_values[ret & MLX90614_CONFIG_IIR_MASK] % 100) *
			10000;
		return IIO_VAL_INT_PLUS_MICRO;
	default:
		return -EINVAL;
	}
}
Example #20
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);
}
static int fsa9485_detect_lanhub(struct fsa9485_usbsw *usbsw) {
	int device_type, ret;
	unsigned int dev1, dev2, adc;
	struct fsa9485_platform_data *pdata = usbsw->pdata;
	struct i2c_client *client = usbsw->client;

	pr_info("%s", __func__);

	device_type = i2c_smbus_read_word_data(client, FSA9485_REG_DEV_T1);
	if (device_type < 0) {
		dev_err(&client->dev, "%s: err %d\n", __func__, device_type);
		return device_type;
	}
	dev1 = device_type & 0xff;
	dev2 = device_type >> 8;
	adc = i2c_smbus_read_byte_data(client, FSA9485_REG_ADC);
	dev_info(&client->dev, "dev1: 0x%02x, dev2: 0x%02x, adc: 0x%02x\n",
		dev1, dev2, adc);

	/* Attached */
	switch(adc){
	/* Switch LANHUB+TA to LANHUB */
	case ADC_GND:
#ifdef CONFIG_MUIC_FSA9485_SUPPORT_LANHUB
		if(usbsw->previous_dock == FSA9485_NONE) {
			dev_info(&client->dev, "%s:otg(lanhub) connect\n", __func__);
			if (pdata->otg_cb)
				pdata->otg_cb(FSA9485_ATTACHED);
		} else if (usbsw->previous_dock == ADC_LANHUB) {
			dev_info(&client->dev, "%s:switch lanhub+ta to lanhub\n", __func__);
			usbsw->lanhub_ta_status=0;
			if (pdata->lanhubta_cb)
				pdata->lanhubta_cb(FSA9485_DETACHED);
		}

		usbsw->dock_attached = FSA9485_ATTACHED;
		usbsw->previous_dock = ADC_GND;
#else
		dev_info(&client->dev, "%s:otg connect\n", __func__);
		if (pdata->otg_cb)
			pdata->otg_cb(FSA9485_ATTACHED);

		usbsw->dock_attached = FSA9485_ATTACHED;
#endif
		i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1, 0x27);
		i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW2, 0x02);
		break;
	/* Switch LANHUB to LANHUB+TA */
	case ADC_LANHUB:
		usbsw->adc = adc;
		dev_info(&client->dev, "%s:switch lanhub to lanhub+ta\n", __func__);

		if(usbsw->previous_dock == FSA9485_NONE) {
			dev_info(&client->dev, "%s:switch lanhub to lanhub+ta\n", __func__);
			if (pdata->lanhub_cb)
				pdata->lanhub_cb(FSA9485_ATTACHED);
		} else if (usbsw->previous_dock == ADC_GND) {
			dev_info(&client->dev, "%s:switch lanhub to lanhub+ta\n", __func__);
			usbsw->lanhub_ta_status = 1;
			if (pdata->lanhubta_cb)
				pdata->lanhubta_cb(FSA9485_ATTACHED);
		}

		usbsw->dock_attached = FSA9485_ATTACHED;
		usbsw->previous_dock = ADC_LANHUB;

		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);

		break;
	case ADC_OPEN:
		dev_info(&client->dev, "%s:ignore ADC_OPEN case\n", __func__);
		usbsw->previous_dock = FSA9485_NONE;
		break;
	default:
		dev_info(&client->dev, "%s:Not reaching here(adc:0x%02x)\n",
			__func__, adc);
		break;
	}

	return adc;
}
Example #22
0
int wiringPiI2CReadReg16 (int fd, int reg)
{
  return i2c_smbus_read_word_data (fd, reg) ;
}
static int l3g4200d_probe(struct i2c_client *client,
			       const struct i2c_device_id *devid)
{
	struct l3g4200d_data *data;
	struct gyro_platform_data *platform_data = NULL;
	int ret = -1;
	int tempvalue;
	GYRO_DBG("l3g4200d_probe start!\n");
	
	if (client->dev.platform_data == NULL) {
		dev_err(&client->dev, "platform data is NULL. exiting.\n");
		ret = -ENODEV;
		goto exit;
	}
	/*gyro mate power*/
	platform_data = client->dev.platform_data;
	if(platform_data->gyro_power)
	{
		ret = platform_data->gyro_power(IC_PM_ON);
		if( ret < 0)
		{
			dev_err(&client->dev, "gyro power on error!\n");
			goto exit;
		}
	}  
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		ret = -ENODEV;
		goto exit_pm_off;
	}

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)){
		ret = -ENODEV;
		goto exit_pm_off;
	}
	
	/*
	 * OK. For now, we presume we have a valid client. We now create the
	 * client structure, even though we cannot fill it completely yet.
	 */
	data = kzalloc(sizeof(struct l3g4200d_data), GFP_KERNEL);

	if (NULL == data) {
		dev_err(&client->dev,
			"failed to allocate memory for module data\n");
		ret = -ENOMEM;
		goto exit_pm_off;
	}
	mutex_init(&data->mlock);

	INIT_WORK(&data->work, gy_work_func);
	i2c_set_clientdata(client, data);
	data->client = client;
	data->pdata = platform_data;
	
	ret = l3g4200d_validate_pdata(data);
	if (ret < 0) {
		dev_err(&client->dev, "failed to validate platform data\n");
		goto exit_kfree;
	}

    ret = i2c_smbus_read_byte(client);
	if ( ret < 0) {
		GYRO_DBG("i2c_smbus_read_byte error!!\n");
		goto err_detect_failed;
	} else {
		GYRO_DBG("L3G4200D Device detected!\n");
	}

	/* read chip id */
	tempvalue = i2c_smbus_read_word_data(client, WHO_AM_I);
	if ((tempvalue & 0x00FF) == 0x00D3) {
		GYRO_DBG("I2C driver registered!\n");
	} else {
		data->client = NULL;
		ret = -ENODEV;
		goto err_detect_failed;
	}
	if (sensor_dev == NULL)
	{
		data->input_dev = input_allocate_device();
		if (data->input_dev == NULL) {
			ret = -ENOMEM;
			printk(KERN_ERR "gs_probe: Failed to allocate input device\n");
			goto err_input_dev_alloc_failed;
		}
       
		data->input_dev->name = "gy_sensors";
		sensor_dev = data->input_dev;

	}else{
		data->input_dev = sensor_dev;
	}
	data->input_dev->id.vendor = VENDOR;
	#if 0
	set_bit(EV_REL,data->input_dev->evbit);
	set_bit(REL_RX, data->input_dev->absbit);
	set_bit(REL_RY, data->input_dev->absbit);
	set_bit(REL_RZ, data->input_dev->absbit);
	#endif
	set_bit(EV_ABS,data->input_dev->evbit);
	/* modify the func of init */
	input_set_abs_params(data->input_dev, ABS_RX, MIN_VALUE, MAX_VALUE, 0, 0);
	input_set_abs_params(data->input_dev, ABS_RY, MIN_VALUE, MAX_VALUE, 0, 0);
	input_set_abs_params(data->input_dev, ABS_RZ, MIN_VALUE, MAX_VALUE, 0, 0);
	input_set_abs_params(data->input_dev, ABS_X, MIN_VALUE, MAX_VALUE, 0, 0);
	input_set_abs_params(data->input_dev, ABS_Y, MIN_VALUE, MAX_VALUE, 0, 0);
	input_set_abs_params(data->input_dev, ABS_Z, MIN_VALUE, MAX_VALUE, 0, 0);
	
	input_set_abs_params(data->input_dev, ABS_THROTTLE, MIN_VALUE, MAX_VALUE, 0, 0);
	input_set_abs_params(data->input_dev, ABS_RUDDER, MIN_VALUE, MAX_VALUE, 0, 0);
	input_set_abs_params(data->input_dev, ABS_WHEEL, MIN_VALUE, MAX_VALUE, 0, 0);
	
	input_set_abs_params(data->input_dev, ABS_GAS, MIN_VALUE, MAX_VALUE, 0, 0);
	input_set_abs_params(data->input_dev, ABS_HAT0X, MIN_VALUE, MAX_VALUE, 0, 0);
	input_set_abs_params(data->input_dev, ABS_HAT0Y, MIN_VALUE, MAX_VALUE, 0, 0);
	input_set_abs_params(data->input_dev, ABS_BRAKE, MIN_VALUE, MAX_VALUE, 0, 0);
	set_bit(EV_SYN,data->input_dev->evbit);
	data->input_dev->id.bustype = BUS_I2C;
	input_set_drvdata(data->input_dev, data);
	ret = input_register_device(data->input_dev);
	if (ret) {
		printk(KERN_ERR "gy_probe: Unable to register %s input device\n", data->input_dev->name);
	/* create l3g-dev device class */
		goto err_input_register_device_failed;
	}
	ret = misc_register(&gysensor_device);

	if (ret) {
		printk(KERN_ERR "gy_probe: gysensor_device register failed\n");
		goto err_misc_device_register_failed;
	}

	hrtimer_init(&data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	data->timer.function = gy_timer_func;
	atomic_set(&a_flag, 0);
	data->flags = -1;
#ifdef CONFIG_HAS_EARLYSUSPEND
	data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	data->early_suspend.suspend = gy_early_suspend;
	data->early_suspend.resume = gy_late_resume;
	register_early_suspend(&data->early_suspend);
#endif
	GYRO_DBG("L3G4200D device created successfully\n");
	gy_wq = create_singlethread_workqueue("gy_wq");
	/* log for create workqueue fail */
	if (!gy_wq)
	{
		ret = -ENOMEM;
		printk(KERN_ERR "%s, line %d: create_singlethread_workqueue fail!\n", __func__, __LINE__);
		goto err_gy_create_workqueue_failed;
	}

	gyro = data;
//	hrtimer_start(&this_gs_data->timer, ktime_set(0, 500000000), HRTIMER_MODE_REL);
	#ifdef CONFIG_HUAWEI_HW_DEV_DCT
	/* detect current device successful, set the flag as present */
	set_hw_dev_flag(DEV_I2C_GYROSCOPE);
	#endif
	
	ret = set_sensor_input(GYRO, data->input_dev->dev.kobj.name);
	if (ret) {
		dev_err(&client->dev, "%s set_sensor_input failed\n", __func__);
		goto err_misc_device_register_failed;
	}
	printk(KERN_DEBUG "l3g4200d_probe   successful");

	set_sensors_list(GY_SENSOR);
	return 0;
/*add gyro exception process*/
err_gy_create_workqueue_failed:
#ifdef CONFIG_HAS_EARLYSUSPEND
	unregister_early_suspend(&data->early_suspend);
#endif

	hrtimer_cancel(&data->timer);
err_misc_device_register_failed:
	misc_deregister(&gysensor_device);
err_input_register_device_failed:
	input_free_device(gyro->input_dev);
err_input_dev_alloc_failed:
err_detect_failed:
exit_kfree:
	kfree(gyro);
exit_pm_off:
/*No need to power down*/
exit:
	return ret;
}
Example #24
0
struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id,
						  unsigned int *size)
{
	struct wf_sat *sat;
	int err;
	unsigned int i, len;
	u8 *buf;
	u8 data[4];

	/* TODO: Add the resulting partition to the device-tree */

	if (sat_id > 1 || (sat = sats[sat_id]) == NULL)
		return NULL;

	err = i2c_smbus_write_word_data(sat->i2c, 8, id << 8);
	if (err) {
		printk(KERN_ERR "smu_sat_get_sdb_part wr error %d\n", err);
		return NULL;
	}

	err = i2c_smbus_read_word_data(sat->i2c, 9);
	if (err < 0) {
		printk(KERN_ERR "smu_sat_get_sdb_part rd len error\n");
		return NULL;
	}
	len = err;
	if (len == 0) {
		printk(KERN_ERR "smu_sat_get_sdb_part no partition %x\n", id);
		return NULL;
	}

	len = le16_to_cpu(len);
	len = (len + 3) & ~3;
	buf = kmalloc(len, GFP_KERNEL);
	if (buf == NULL)
		return NULL;

	for (i = 0; i < len; i += 4) {
		err = i2c_smbus_read_i2c_block_data(sat->i2c, 0xa, 4, data);
		if (err < 0) {
			printk(KERN_ERR "smu_sat_get_sdb_part rd err %d\n",
			       err);
			goto fail;
		}
		buf[i] = data[1];
		buf[i+1] = data[0];
		buf[i+2] = data[3];
		buf[i+3] = data[2];
	}
#ifdef DEBUG
	DBG(KERN_DEBUG "sat %d partition %x:", sat_id, id);
	for (i = 0; i < len; ++i)
		DBG(" %x", buf[i]);
	DBG("\n");
#endif

	if (size)
		*size = len;
	return (struct smu_sdbp_header *) buf;

 fail:
	kfree(buf);
	return NULL;
}
Example #25
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);
			}
#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);
#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;
#ifdef CONFIG_MACH_FORTE 
        s3c_gpio_cfgpin(GPIO_USB_SCL_28V, S3C_GPIO_OUTPUT);
        s3c_gpio_setpull(GPIO_USB_SCL_28V, S3C_GPIO_PULL_NONE);

        s3c_gpio_cfgpin(GPIO_USB_SDA_28V, S3C_GPIO_OUTPUT);
        s3c_gpio_setpull(GPIO_USB_SDA_28V, S3C_GPIO_PULL_NONE);
#endif

	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);

#if defined(CONFIG_MACH_VICTORY)
		ret = switch_dev_register(&wimax_cable);
		wimax_cable.print_state = wimax_cable_type; 
#endif

	/* device detection */
	fsa9480_detect_dev(usbsw);
	
	// set fsa9480 init flag.
	if (usbsw->pdata->set_init_flag)
		usbsw->pdata->set_init_flag();

	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,
};
Example #26
0
int main(int argc, char *argv[])
{
	char *end;
	int res, i2cbus, address, size, file;
	int daddress;
	char filename[20];
	int pec = 0;
	int flags = 0;
	int force = 0, yes = 0, version = 0, extend = 0;
	char buf[2];// = {0x0,0x1};

	/* 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 'e': extend = 1; break;
		default:
			fprintf(stderr, "Error: Unsupported option "
				"\"%s\"!\n", argv[1+flags]);
			help();
			exit(1);
		}
		flags++;
	}

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

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

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

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

	if (argc > flags + 3) {
		size = I2C_SMBUS_BYTE_DATA;
		daddress = strtol(argv[flags+3], &end, 0);
		if (*end || daddress < 0 || daddress > 0xff) {
			fprintf(stderr, "Error: Data address invalid!\n");
			help();
		}
	} else {
		size = I2C_SMBUS_BYTE;
		daddress = -1;
	}
	char *pEnd;
	if (extend) {
		buf[0] = strtol(argv[flags+3], &pEnd, 0);
		buf[1] = strtol(argv[flags+4], &pEnd, 0); 
		
		file = open_i2c_dev(i2cbus, filename, sizeof(filename), 0);
		address = parse_i2c_address(argv[flags+2]);
		
		two_byte_address_read(buf, file, address);
	}


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

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

	if (!yes && !confirm(filename, address, size, daddress, pec))
		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:
		if (daddress >= 0) {
			res = i2c_smbus_write_byte(file, daddress);
			if (res < 0)
				fprintf(stderr, "Warning - write failed\n");
		}
		res = i2c_smbus_read_byte(file);
		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) {
		fprintf(stderr, "Error: Read failed\n");
		exit(2);
	}

	printf("0x%0*x\n", size == I2C_SMBUS_WORD_DATA ? 4 : 2, res);

	exit(0);
}
Example #27
0
static irqreturn_t fsa9485_irq_thread(int irq, void *data)
{
	struct fsa9485_usbsw *usbsw = data;
	struct i2c_client *client = usbsw->client;
	int intr, intr2, detect;

	/* FSA9485 : Read interrupt -> Read Device
	 FSA9485 : Read Device -> Read interrupt */

	pr_info("fsa9485_irq_thread is called\n");
	/* device detection */
	mutex_lock(&usbsw->mutex);
	detect = fsa9485_detect_dev(usbsw);
	mutex_unlock(&usbsw->mutex);
	pr_info("%s: detect dev_adc: %x\n", __func__, detect);

	/* read and clear interrupt status bits */
	intr = i2c_smbus_read_word_data(client, FSA9485_REG_INT1);
	dev_info(&client->dev, "%s: intr : 0x%x intr2 : 0x%x\n",
					__func__, intr & 0xff, intr >> 8);
	intr2 = intr >> 8;

	if (intr < 0) {
		msleep(100);
		dev_err(&client->dev, "%s: err %d\n", __func__, intr);
		intr = i2c_smbus_read_word_data(client, FSA9485_REG_INT1);
		if (intr < 0)
			dev_err(&client->dev,
				"%s: err at read %d\n", __func__, intr);
		fsa9485_reg_init(usbsw);
		return IRQ_HANDLED;
	} 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. */
		fsa9485_reg_init(usbsw);
	}
	/* ADC_value(key pressed) changed at AV_Dock.*/
	if (intr2) {
		if (intr2 & 0x4) { /* for adc change */
			fsa9485_handle_dock_vol_key(usbsw, detect);
			dev_info(&client->dev,
					"intr2: 0x%x, adc_val: %x\n",
							intr2, detect);
		} else if (intr2 & 0x2) { /* for smart dock */
			i2c_smbus_read_word_data(client, FSA9485_REG_INT1);

		} else if (intr2 & 0x1) { /* for av change (desk dock, hdmi) */
			dev_info(&client->dev,
				"%s enter Av charing\n", __func__);
			fsa9485_detect_dev(usbsw);
		} else {
			dev_info(&client->dev,
				"%s intr2 but, nothing happend, intr2: 0x%x\n",
				__func__, intr2);
		}
		return IRQ_HANDLED;
	}

	return IRQ_HANDLED;
}
Example #28
0
static u16 ads7828_read_value(struct i2c_client *client, u8 reg)
{
	return swab16(i2c_smbus_read_word_data(client, reg));
}
static int bma254_probe(struct i2c_client *client,
	const struct i2c_device_id *id)
{
	int ret = 0;
	struct bma254_data *bma254;
	struct input_dev *dev;
#ifdef CONFIG_BMA254_SMART_ALERT
	int err = 0;
	struct bma254_platform_data *pdata;
#endif

	pr_info("%s, is called\n", __func__);

	if (client == NULL) {
		pr_err("%s, client doesn't exist\n", __func__);
		ret = -ENOMEM;
		return ret;
	}
#ifdef CONFIG_SENSORS_POWERCONTROL
	ret = bma254_regulator_onoff(&client->dev, true);
	if (ret) {
		pr_err("%s, Power Up Failed\n", __func__);
		return ret;
	}
#endif
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		pr_err("%s,client not i2c capable\n", __func__);
		return -ENOMEM;
	}

	ret = i2c_smbus_read_word_data(client, BMA254_CHIP_ID);
	if ((ret & 0x00ff) != 0xfa) {
		pr_err("%s,i2c failed(%x)\n", __func__, ret & 0x00ff);
		ret = -ENOMEM;
		return ret;
	} else {
		pr_err("%s,chip id %x\n", __func__, ret & 0x00ff);
	}

	bma254 = kzalloc(sizeof(struct bma254_data), GFP_KERNEL);
	if (!bma254) {
		pr_err("%s, kzalloc error\n", __func__);
		ret = -ENOMEM;
		return ret;
	}

#ifdef CONFIG_BMA254_SMART_ALERT
	if(client->dev.of_node) {
		pdata = devm_kzalloc(&client->dev,
			sizeof(struct bma254_platform_data), GFP_KERNEL);
		if (!pdata) {
			dev_err(&client->dev, "Failed to allocate memory \n");
			kfree(bma254);

			return -ENOMEM;
		}
	}else{
		pr_err("%s,this_node is empty\n", __func__);
		kfree(bma254);
		return -ENODEV;
	}

	bma254->pdata = pdata;
#endif
	ret = bma254_parse_dt(bma254, &client->dev);
	if (ret) {
		pr_err("%s, get gpio is failed\n", __func__);
		goto parse_dt_err;
	}

	i2c_set_clientdata(client, bma254);
	bma254->client = client;

	bma254_activate(bma254, false);

	dev = input_allocate_device();
	if (!dev){
		goto input_allocate_device_err;
	}
	dev->name = "accelerometer";
	dev->id.bustype = BUS_I2C;
#if !defined(CONFIG_MACH_VICTORLTE) && !defined(CONFIG_MACH_VICTOR3GDSDTV_LTN)
	dev->dev.parent = &client->dev;
#endif
#ifdef REPORT_ABS
	input_set_capability(dev, EV_ABS, ABS_MISC);
	input_set_abs_params(dev, ABS_X, ABSMIN, ABSMAX, 0, 0);
	input_set_abs_params(dev, ABS_Y, ABSMIN, ABSMAX, 0, 0);
	input_set_abs_params(dev, ABS_Z, ABSMIN, ABSMAX, 0, 0);
#else
	input_set_capability(dev, EV_REL, REL_X);
	input_set_capability(dev, EV_REL, REL_Y);
	input_set_capability(dev, EV_REL, REL_Z);
#endif
	input_set_drvdata(dev, bma254);

	ret = input_register_device(dev);
	if (ret < 0) {
		pr_err("%s,sysfs_create_group failed\n", __func__);
		goto input_register_device_err;
	}
	bma254->input = dev;

#ifdef CONFIG_BMA254_SMART_ALERT
	pr_info("%s:  HW_rev success %d\n", __func__, system_rev);
	INIT_WORK(&bma254->alert_work, bma254_work_func_alert);
	wake_lock_init(&bma254->reactive_wake_lock, WAKE_LOCK_SUSPEND,
		"reactive_wake_lock");
	err = bma254_setup_irq(bma254);
	if (err) {
		bma254->pin_check_fail = true;
		pr_err("%s: could not setup irq\n", __func__);
		goto err_setup_irq;
	}
	mutex_init(&bma254->data_mutex);
#endif

	ret = sensors_create_symlink(&dev->dev.kobj, dev->name);
	if (ret < 0) {
		input_unregister_device(dev);
		return ret;
	}
	ret = sysfs_create_group(&bma254->input->dev.kobj,
			&bma254_attribute_group);
	if (ret < 0) {
		pr_err("%s,sysfs_create_group failed\n", __func__);
		sensors_remove_symlink(&bma254->input->dev.kobj,
			bma254->input->name);
		goto sysfs_create_group_err;
	}

	INIT_DELAYED_WORK(&bma254->work, bma254_work_func);
	bma254->delay = MAX_DELAY;
	bma254->enable = 0;

	ret = sensors_register(bma254->dev, bma254,
		bma254_attrs, "accelerometer_sensor");
	if (ret < 0) {
		pr_info("%s: could not sensors_register\n", __func__);
		goto sensors_register_err;
	}

#ifdef CONFIG_SENSORS_POWERCONTROL
	bma254_regulator_onoff(&client->dev, false);
#endif
	pr_info("[SENSOR]: %s - Probe done!(chip pos : %d)\n",
		__func__, bma254->position);

	return 0;

sensors_register_err:
	sysfs_remove_group(&bma254->input->dev.kobj,
			&bma254_attribute_group);
	sensors_remove_symlink(&bma254->input->dev.kobj, bma254->input->name);
sysfs_create_group_err:
	input_unregister_device(bma254->input);
#ifdef CONFIG_BMA254_SMART_ALERT
err_setup_irq:
	wake_lock_destroy(&bma254->reactive_wake_lock);
#endif
input_register_device_err:
	input_free_device(dev);
input_allocate_device_err:
parse_dt_err:
	kfree(bma254);
	pr_err("[SENSOR]: %s - Probe fail!\n", __func__);
#ifdef CONFIG_SENSORS_POWERCONTROL
	bma254_regulator_onoff(&client->dev, false);
#endif
	return ret;
}
Example #30
0
static void fsa9480_detect_dev(struct fsa9480_usbsw *usbsw)
{
	int device_type, hidden_reg, vbus_in;
	int ret = 0;
	int vchg = 0;
	unsigned char val1, val2;
	struct fsa9480_platform_data *pdata = usbsw->pdata;
#if (defined(CONFIG_MHL_SWITCH) && defined(CONFIG_MHL_SII9234))

        local_pdata = usbsw->pdata;
#endif
	struct i2c_client *client = usbsw->client;

	mutex_lock(&usbsw->lock);
	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 OTG*/
		if (val1 & DEV_T1_USB_OTG_MASK) {
			if (pdata->otg_cb)
				pdata->otg_cb(FSA9480_ATTACHED);
			if (usbsw->mansw)
				ret = i2c_smbus_write_byte_data(client,
					FSA9480_REG_CTRL, CON_MASK);
				if (ret < 0)
					dev_err(&client->dev, "%s: err %d\n", __func__, ret);
		/* USB */
		} else if (val1 & DEV_T1_USB_MASK || val2 & DEV_T2_USB_MASK) {
			if (pdata->usb_cb) {
				usb_state = USB_CONFIGURED;
				pdata->usb_cb(FSA9480_ATTACHED);
			}
			if (pdata->inform_charger_connection)
				pdata->inform_charger_connection(true);

			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);
			}
		/* UART */
		} else if (val1 & DEV_T1_UART_MASK || val2 & DEV_T2_UART_MASK) {
			if (pdata->uart_cb)
				vchg = pdata->uart_cb(FSA9480_ATTACHED);

			dev_info(&client->dev, "[FSA9480] Attached UART, vchg = %d \n", vchg );
			if (vchg && pdata->inform_charger_connection)
				pdata->inform_charger_connection(true);
			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);
			}
		/* CHARGER */
		} else if (val1 & DEV_T1_CHARGER_MASK) {
			if (pdata->charger_cb)
				pdata->charger_cb(FSA9480_ATTACHED);
			if (pdata->inform_charger_connection)
				pdata->inform_charger_connection(true);
		/* 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 (defined(CONFIG_MHL_SWITCH) && defined(CONFIG_MHL_SII9234))		
			printk("FSA MHL Attach");
			printk("mhl_cable_status = %d \n", mhl_cable_status);
			
			FSA9480_MhlSwitchSel(1);
#else
			hidden_reg = i2c_smbus_read_word_data(client, FSA9480_REG_HIDDEN2);
			vbus_in = ((hidden_reg & HD2_VBUS_VALID) ? 1:0);
			dev_info(&client->dev, "[FSA9480] Deskdock Attach, hidden_reg2 = %x, vbus_in = %d \n", hidden_reg, vbus_in );
			if (pdata->deskdock_cb)
				pdata->deskdock_cb(FSA9480_ATTACHED);
			if (vbus_in == 1 && pdata->dock_charger_cb)
				pdata->dock_charger_cb(FSA9480_ATTACHED);
#endif
		/* Car Dock */
		} else if (val2 & DEV_JIG_UART_ON) {
			hidden_reg = i2c_smbus_read_word_data(client, FSA9480_REG_HIDDEN2);
			vbus_in = ((hidden_reg & HD2_VBUS_VALID) ? 1:0);
			dev_info(&client->dev, "[FSA9480] Cardock Attach, hidden_reg2 = %x, vbus_in = %d \n", hidden_reg, vbus_in );
			if (pdata->cardock_cb)
				pdata->cardock_cb(FSA9480_ATTACHED);
			if (vbus_in == 1 && pdata->dock_charger_cb)
				pdata->dock_charger_cb(FSA9480_ATTACHED);
		}
	/* Detached */
	} else {
		/* USB OTG*/
		if (usbsw->dev1 & DEV_T1_USB_OTG_MASK) {
			if (pdata->otg_cb)
				pdata->otg_cb(FSA9480_DETACHED);
		/* USB */
		} else if (usbsw->dev1 & DEV_T1_USB_MASK ||
				usbsw->dev2 & DEV_T2_USB_MASK) {
			if (pdata->usb_cb) {
				usb_state = USB_NOT_CONFIGURED;
				pdata->usb_cb(FSA9480_DETACHED);
			}
			if (pdata->inform_charger_connection)
				pdata->inform_charger_connection(false);
		/* UART */
		} else if (usbsw->dev1 & DEV_T1_UART_MASK ||
				usbsw->dev2 & DEV_T2_UART_MASK) {
			if (pdata->uart_cb)
				vchg = pdata->uart_cb(FSA9480_DETACHED);

			dev_info(&client->dev, "[FSA9480] Detached UART , vchg = %d\n", vchg);
			if (vchg && pdata->inform_charger_connection)
				pdata->inform_charger_connection(false);						
		/* CHARGER */
		} else if (usbsw->dev1 & DEV_T1_CHARGER_MASK) {
			if (pdata->charger_cb)
				pdata->charger_cb(FSA9480_DETACHED);
			if (pdata->inform_charger_connection)
				pdata->inform_charger_connection(false);
		/* 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 (defined(CONFIG_MHL_SWITCH) && defined(CONFIG_MHL_SII9234))	
			printk("FSA MHL Detach\n");		
			
			FSA9480_MhlSwitchSel(0);
#else 
			if (pdata->deskdock_cb)
				pdata->deskdock_cb(FSA9480_DETACHED);
			if (pdata->dock_charger_cb)
				pdata->dock_charger_cb(FSA9480_DETACHED);
#endif
		/* Car Dock */
		} else if (usbsw->dev2 & DEV_JIG_UART_ON) {
			if (pdata->cardock_cb)
				pdata->cardock_cb(FSA9480_DETACHED);
			if (pdata->dock_charger_cb)
				pdata->dock_charger_cb(FSA9480_DETACHED);
		}
	}

	usbsw->dev1 = val1;
	usbsw->dev2 = val2;
	mutex_unlock(&usbsw->lock);
}