static int raspberrypiI2CReadReg16(int fd, int reg) { return i2c_smbus_read_word_data(fd, reg); }
static int read_r8d16(void *client, u8 reg) { return i2c_smbus_read_word_data(client, reg); }
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); }
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; }
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", ®); } 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'); }
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; }
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; }
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; }
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; }
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; }
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; }
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); }
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; } }
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; }
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; }
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; }
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, };
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); }
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; }
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; }
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); }