/* * Erase an address and write word. * The mutex must be locked before calling. */ static s32 mlx90614_write_word(const struct i2c_client *client, u8 command, u16 value) { /* * Note: The mlx90614 requires a PEC on writing but does not send us a * valid PEC on reading. Hence, we cannot set I2C_CLIENT_PEC in * i2c_client.flags. As a workaround, we use i2c_smbus_xfer here. */ union i2c_smbus_data data; s32 ret; dev_dbg(&client->dev, "Writing 0x%x to address 0x%x", value, command); data.word = 0x0000; /* erase command */ ret = i2c_smbus_xfer(client->adapter, client->addr, client->flags | I2C_CLIENT_PEC, I2C_SMBUS_WRITE, command, I2C_SMBUS_WORD_DATA, &data); if (ret < 0) return ret; msleep(MLX90614_TIMING_EEPROM); data.word = value; /* actual write */ ret = i2c_smbus_xfer(client->adapter, client->addr, client->flags | I2C_CLIENT_PEC, I2C_SMBUS_WRITE, command, I2C_SMBUS_WORD_DATA, &data); msleep(MLX90614_TIMING_EEPROM); return ret; }
uint8_t I2C_ReadBlock(uint8_t deviceID, uint8_t offset,uint8_t *buf, uint8_t len) { int i; uint8_t accessI2cAddr; union i2c_smbus_data data; int32_t status; if (I2cAccessCheck() != HAL_RET_SUCCESS) { return 0x00; } accessI2cAddr = deviceID>>1; memset(buf,0xff,len); for(i = 0 ;i < len;i++) { status = i2c_smbus_xfer(gMhlDevice.pI2cClient->adapter, accessI2cAddr, 0, I2C_SMBUS_READ, offset + i, I2C_SMBUS_BYTE_DATA, &data); if (status < 0) { return 0; } *buf = data.byte; buf++; } return len; }
void I2C_WriteBlock(uint8_t deviceID, uint8_t offset, uint8_t *buf, uint8_t len) { int i; uint8_t accessI2cAddr; union i2c_smbus_data data; int32_t status; if (I2cAccessCheck() != HAL_RET_SUCCESS) { return ; } accessI2cAddr = deviceID>>1; for(i = 0 ;i < len;i++) { data.byte = *buf; status = i2c_smbus_xfer(gMhlDevice.pI2cClient->adapter, accessI2cAddr, 0, I2C_SMBUS_WRITE, offset + i, I2C_SMBUS_BYTE_DATA, &data); if (status < 0) { return ; } buf++; } return ; }
static int fc7100_mezz_r12_ioexpand1_setup(struct i2c_client *client, unsigned gpio, unsigned ngpio, void *context) { union i2c_smbus_data data; char *screen_name=NULL; gpio_request_one(FC7100_IOEXPAND1_GPIO_NR(14), GPIOF_OUT_INIT_HIGH, "LCD-nrst"); gpio_request_one(FC7100_IOEXPAND0_GPIO_NR(4), GPIOF_OUT_INIT_HIGH, "Touch-nrst"); /* force sd2 power and ldo en */ gpio_request_one(FC7100_IOEXPAND0_GPIO_NR(7), GPIOF_OUT_INIT_HIGH, "sd2 power"); gpio_request_one(FC7100_IOEXPAND1_GPIO_NR(15), GPIOF_OUT_INIT_HIGH, "sd2 bus en"); fc7100_export_gpios(); /* Setup avi, now that chipsets are powered */ /* If avi chip is pluged on mezz, force configuration */ if(i2c_smbus_xfer(i2c_get_adapter(2), 0x3b, 0, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE_DATA, &data) >= 0) { pr_info("Detected sii hdmi chip %d-0x%02X.\n", 2, 0x3b); screen_name = "sii-hdmi"; } if (screen_name != NULL) fc7100_mezz_avi_update(screen_name, 0); return 0; }
static inline int snd_ak4641_i2c_probe(struct snd_ak4641 *ak) { if (ak->i2c_client.adapter == NULL) return -EINVAL; ak->i2c_client.addr = 0x12; if (i2c_smbus_xfer(ak->i2c_client.adapter, ak->i2c_client.addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL) < 0) return -ENODEV; else return 0; }
/** * i2c_smbus_write_word_data - SMBus "write word" protocol * @client: Handle to slave device * @command: Byte interpreted by slave * @value: 16-bit "word" being written * * This executes the SMBus "write word" protocol, returning negative errno * else zero on success. */ s32 i2c_smbus_write_word_data(const struct i2c_client *client, u8 command, u16 value) { union i2c_smbus_data data; data.word = value; return i2c_smbus_xfer(client->adapter, client->addr, 0 /* client->flags */, I2C_SMBUS_WRITE, command, I2C_SMBUS_WORD_DATA, &data); }
/** * i2c_smbus_write_byte_data - SMBus "write byte" protocol * @client: Handle to slave device * @command: Byte interpreted by slave * @value: Byte being written * * This executes the SMBus "write byte" protocol, returning negative errno * else zero on success. */ s32 i2c_smbus_write_byte_data(const struct i2c_client *client, u8 command, u8 value) { union i2c_smbus_data data; data.byte = value; return i2c_smbus_xfer(client->adapter, client->addr, client->flags, I2C_SMBUS_WRITE, command, I2C_SMBUS_BYTE_DATA, &data); }
/** * i2c_smbus_read_byte_data - SMBus "read byte" protocol * @client: Handle to slave device * @command: Byte interpreted by slave * * This executes the SMBus "read byte" protocol, returning negative errno * else a data byte received from the device. */ s32 i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command) { union i2c_smbus_data data; int status; status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, I2C_SMBUS_READ, command, I2C_SMBUS_BYTE_DATA, &data); return (status < 0) ? status : data.byte; }
/** * i2c_smbus_read_byte - SMBus "receive byte" protocol * @client: Handle to slave device * * This executes the SMBus "receive byte" protocol, returning negative errno * else the byte received from the device. */ s32 i2c_smbus_read_byte(const struct i2c_client *client) { union i2c_smbus_data data; int status; status = i2c_smbus_xfer(client->adapter, client->addr, 0 /* client->flags */, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data); return (status < 0) ? status : data.byte; }
static int dps_800ab_16_d_write_word(struct i2c_client *client, u8 reg, \ u16 value) { union i2c_smbus_data data; data.word = value; return i2c_smbus_xfer(client->adapter, client->addr, client->flags |= I2C_CLIENT_PEC, I2C_SMBUS_WRITE, reg, I2C_SMBUS_WORD_DATA, &data); }
/** * i2c_smbus_read_word_data - SMBus "read word" protocol * @client: Handle to slave device * @command: Byte interpreted by slave * * This executes the SMBus "read word" protocol, returning negative errno * else a 16-bit unsigned "word" received from the device. */ s32 i2c_smbus_read_word_data(const struct i2c_client *client, u8 command) { union i2c_smbus_data data; int status; status = i2c_smbus_xfer(client->adapter, client->addr, 0 /* client->flags */, I2C_SMBUS_READ, command, I2C_SMBUS_WORD_DATA, &data); return (status < 0) ? status : data.word; }
uint8_t I2C_ReadBlock(uint8_t deviceID, uint8_t offset,uint8_t *buf, uint8_t len) { //printk("hdmi enter %s (0x%02x, 0x%02x, 0x%02x)\n", __func__, deviceID, offset, len); int i; uint8_t accessI2cAddr; #if USE_DEFAULT_I2C_CODE union i2c_smbus_data data; #endif int32_t status; u32 client_main_addr; if (I2cAccessCheck() != HAL_RET_SUCCESS) { return 0x00; } accessI2cAddr = deviceID>>1; //backup addr client_main_addr = gMhlDevice.pI2cClient->addr; gMhlDevice.pI2cClient->addr = accessI2cAddr; memset(buf,0xff,len); for(i = 0 ; i < len; i++) { #if USE_DEFAULT_I2C_CODE status = i2c_smbus_xfer(gMhlDevice.pI2cClient->adapter, accessI2cAddr, 0, I2C_SMBUS_READ, offset + i, I2C_SMBUS_BYTE_DATA, &data); if (status < 0) { return 0; } *buf = data.byte; #else u8 tmp; tmp = offset + i; gMhlDevice.pI2cClient->ext_flag |= I2C_DIRECTION_FLAG; status = i2c_master_send(gMhlDevice.pI2cClient, (const char*)&tmp, 1); if (status < 0) { printk("I2C_ReadByte(0x%02x, 0x%02x), i2c_transfer error: %d\n", deviceID, offset, status); } status = i2c_master_recv(gMhlDevice.pI2cClient, (char*)&tmp, 1); *buf = tmp; #endif buf++; } /* restore default client address */ gMhlDevice.pI2cClient->addr = client_main_addr; return len; }
s32 i2c_smbus_write_i2c_block_data(const struct i2c_client *client, u8 command, u8 length, const u8 *values) { union i2c_smbus_data data; if (length > I2C_SMBUS_BLOCK_MAX) length = I2C_SMBUS_BLOCK_MAX; data.block[0] = length; memcpy(data.block + 1, values, length); return i2c_smbus_xfer(client->adapter, client->addr, 0 /* client->flags */, I2C_SMBUS_WRITE, command, I2C_SMBUS_I2C_BLOCK_DATA, &data); }
void I2C_WriteBlock(uint8_t deviceID, uint8_t offset, uint8_t *buf, uint8_t len) { //printk("hdmi enter %s (0x%02x, 0x%02x, 0x%02x)\n",__func__, deviceID, offset, len); int i; uint8_t accessI2cAddr; #if USE_DEFAULT_I2C_CODE union i2c_smbus_data data; #endif int32_t status; u8 tmp[2] = {0}; u32 client_main_addr; if (I2cAccessCheck() != HAL_RET_SUCCESS) { return ; } accessI2cAddr = deviceID>>1; //backup addr client_main_addr = gMhlDevice.pI2cClient->addr; gMhlDevice.pI2cClient->addr = accessI2cAddr; for(i = 0 ; i < len; i++) { #if USE_DEFAULT_I2C_CODE data.byte = *buf; status = i2c_smbus_xfer(gMhlDevice.pI2cClient->adapter, accessI2cAddr, 0, I2C_SMBUS_WRITE, offset + i, I2C_SMBUS_BYTE_DATA, &data); #else tmp[0] = offset + i; tmp[1] = *buf; gMhlDevice.pI2cClient->ext_flag |= I2C_DIRECTION_FLAG; status = i2c_master_send( gMhlDevice.pI2cClient, (const char*)tmp, 2); #endif if (status < 0) { /* restore default client address */ gMhlDevice.pI2cClient->addr = client_main_addr; return ; } buf++; } /* restore default client address */ gMhlDevice.pI2cClient->addr = client_main_addr; return ; }
/** * i2c_smbus_read_block_data - SMBus "block read" protocol * @client: Handle to slave device * @command: Byte interpreted by slave * @values: Byte array into which data will be read; big enough to hold * the data returned by the slave. SMBus allows at most 32 bytes. * * This executes the SMBus "block read" protocol, returning negative errno * else the number of data bytes in the slave's response. * * Note that using this function requires that the client's adapter support * the I2C_FUNC_SMBUS_READ_BLOCK_DATA functionality. Not all adapter drivers * support this; its emulation through I2C messaging relies on a specific * mechanism (I2C_M_RECV_LEN) which may not be implemented. */ s32 i2c_smbus_read_block_data(const struct i2c_client *client, u8 command, u8 *values) { union i2c_smbus_data data; int status; status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, I2C_SMBUS_READ, command, I2C_SMBUS_BLOCK_DATA, &data); if (status) return status; memcpy(values, &data.block[1], data.block[0]); return data.block[0]; }
/* Returns the number of read bytes */ s32 i2c_smbus_read_i2c_block_data(const struct i2c_client *client, u8 command, u8 length, u8 *values) { union i2c_smbus_data data; int status; if (length > I2C_SMBUS_BLOCK_MAX) length = I2C_SMBUS_BLOCK_MAX; data.block[0] = length; status = i2c_smbus_xfer(client->adapter, client->addr, 0 /* client->flags */, I2C_SMBUS_READ, command, I2C_SMBUS_I2C_BLOCK_DATA, &data); if (status < 0) return status; memcpy(values, &data.block[1], data.block[0]); return data.block[0]; }
void I2C_WriteByte(uint8_t deviceID, uint8_t offset, uint8_t value) { //printk("hdmi enter I2C_WriteByte(0x%02x, 0x%02x, 0x%02x) \n", // deviceID, offset, value); uint8_t accessI2cAddr; #if USE_DEFAULT_I2C_CODE union i2c_smbus_data data; #endif int32_t status; u32 client_main_addr; u8 buf[2]; if (I2cAccessCheck() != HAL_RET_SUCCESS) { return; } accessI2cAddr = deviceID>>1;//? //backup addr client_main_addr = gMhlDevice.pI2cClient->addr; gMhlDevice.pI2cClient->addr = accessI2cAddr; #if USE_DEFAULT_I2C_CODE data.byte = value; status = i2c_smbus_xfer(gMhlDevice.pI2cClient->adapter, accessI2cAddr, 0, I2C_SMBUS_WRITE, offset, I2C_SMBUS_BYTE_DATA, &data); #else gMhlDevice.pI2cClient->ext_flag |= I2C_DIRECTION_FLAG; buf[0] = offset; buf[1] = value; status = i2c_master_send( gMhlDevice.pI2cClient, (const char*)buf, 2 /*sizeof(buf)*/); #endif if (status < 0) { printk("I2C_WriteByte(0x%02x, 0x%02x, 0x%02x), i2c_transfer error: %d\n", deviceID, offset, value, status); } /* restore default client address */ gMhlDevice.pI2cClient->addr = client_main_addr; }
void I2C_WriteByte(uint8_t deviceID, uint8_t offset, uint8_t value) { uint8_t accessI2cAddr; union i2c_smbus_data data; int32_t status; if (I2cAccessCheck() != HAL_RET_SUCCESS) { return; } accessI2cAddr = deviceID>>1; data.byte = value; status = i2c_smbus_xfer(gMhlDevice.pI2cClient->adapter, accessI2cAddr, 0, I2C_SMBUS_WRITE, offset, I2C_SMBUS_BYTE_DATA, &data); if (status < 0) { printk("I2C_WriteByte(0x%02x, 0x%02x, 0x%02x), i2c_transfer error: %d\n", deviceID, offset, value, status); } }
static int mlx90614_sleep(struct mlx90614_data *data) { s32 ret; if (!data->wakeup_gpio) { dev_dbg(&data->client->dev, "Sleep disabled"); return -ENOSYS; } dev_dbg(&data->client->dev, "Requesting sleep"); mutex_lock(&data->lock); ret = i2c_smbus_xfer(data->client->adapter, data->client->addr, data->client->flags | I2C_CLIENT_PEC, I2C_SMBUS_WRITE, MLX90614_OP_SLEEP, I2C_SMBUS_BYTE, NULL); mutex_unlock(&data->lock); return ret; }
static int i2c_mux_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data *data) { struct i2c_mux_priv *priv = adap->algo_data; struct i2c_mux_core *muxc = priv->muxc; struct i2c_adapter *parent = muxc->parent; int ret; /* Select the right mux port and perform the transfer. */ ret = muxc->select(muxc, priv->chan_id); if (ret >= 0) ret = i2c_smbus_xfer(parent, addr, flags, read_write, command, size, data); if (muxc->deselect) muxc->deselect(muxc, priv->chan_id); return ret; }
/** * @brief Read a single byte from a register within an I2c device. * *****************************************************************************/ uint8_t I2C_ReadByte(uint8_t deviceID, uint8_t offset) { uint8_t accessI2cAddr; uint8_t addrOffset; union i2c_smbus_data data; int32_t status; if (I2cAccessCheck() != HAL_RET_SUCCESS) { /* Driver expects failed I2C reads to return 0xFF */ return 0xFF; } // Figure I2c address offset from base of I2c device to requested // I2c address. addrOffset = deviceID - BASE_I2C_ADDR; // Get REAL base address of the I2c device on the platform. accessI2cAddr = (uint8_t)(gMhlDevice.pI2cClient->addr << 1); // Calculate REAL I2c access address. accessI2cAddr += addrOffset; accessI2cAddr >>= 1; status = i2c_smbus_xfer(gMhlDevice.pI2cClient->adapter, accessI2cAddr, 0, I2C_SMBUS_READ, offset, I2C_SMBUS_BYTE_DATA, &data); if (status < 0) { SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE, "I2C_ReadByte(0x%02x, 0x%02x), i2c_transfer error: %d\n", deviceID, offset, status); data.byte = 0xFF; } return data.byte; }
uint8_t I2C_ReadByte(uint8_t deviceID, uint8_t offset) { uint8_t accessI2cAddr; union i2c_smbus_data data; int32_t status; if (I2cAccessCheck() != HAL_RET_SUCCESS) { return 0xFF; } accessI2cAddr = deviceID>>1; status = i2c_smbus_xfer(gMhlDevice.pI2cClient->adapter, accessI2cAddr, 0, I2C_SMBUS_READ, offset, I2C_SMBUS_BYTE_DATA, &data); if (status < 0) { if(deviceID != 0xfc) { printk("I2C_ReadByte(0x%02x, 0x%02x), i2c_transfer error: %d\n", deviceID, offset, status); } data.byte = 0xFF; } return data.byte; }
/* Very inefficient for ISA detects, and won't work for 10-bit addresses! */ int i2c_detect(struct i2c_adapter *adapter, struct i2c_address_data *address_data, i2c_found_addr_proc * found_proc) { int addr, i, found, j, err; struct i2c_force_data *this_force; int is_isa = i2c_is_isa_adapter(adapter); int adapter_id = is_isa ? SENSORS_ISA_BUS : i2c_adapter_id(adapter); /* Forget it if we can't probe using SMBUS_QUICK */ if ((!is_isa) && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) return -1; for (addr = 0x00; addr <= (is_isa ? 0xffff : 0x7f); addr++) { if ((is_isa && check_region(addr, 1)) || (!is_isa && i2c_check_addr(adapter, addr))) continue; /* If it is in one of the force entries, we don't do any detection at all */ found = 0; for (i = 0; !found && (this_force = address_data->forces + i, this_force->force); i++) { for (j = 0; !found && (this_force->force[j] != SENSORS_I2C_END); j += 2) { if ( ((adapter_id == this_force->force[j]) || ((this_force-> force[j] == SENSORS_ANY_I2C_BUS) && !is_isa)) && (addr == this_force->force[j + 1])) { #ifdef DEBUG printk ("i2c-proc.o: found force parameter for adapter %d, addr %04x\n", adapter_id, addr); #endif if ( (err = found_proc(adapter, addr, 0, this_force-> kind))) return err; found = 1; } } } if (found) continue; /* If this address is in one of the ignores, we can forget about it right now */ for (i = 0; !found && (address_data->ignore[i] != SENSORS_I2C_END); i += 2) { if ( ((adapter_id == address_data->ignore[i]) || ((address_data-> ignore[i] == SENSORS_ANY_I2C_BUS) && !is_isa)) && (addr == address_data->ignore[i + 1])) { #ifdef DEBUG printk ("i2c-proc.o: found ignore parameter for adapter %d, " "addr %04x\n", adapter_id, addr); #endif found = 1; } } for (i = 0; !found && (address_data->ignore_range[i] != SENSORS_I2C_END); i += 3) { if ( ((adapter_id == address_data->ignore_range[i]) || ((address_data-> ignore_range[i] == SENSORS_ANY_I2C_BUS) & !is_isa)) && (addr >= address_data->ignore_range[i + 1]) && (addr <= address_data->ignore_range[i + 2])) { #ifdef DEBUG printk ("i2c-proc.o: found ignore_range parameter for adapter %d, " "addr %04x\n", adapter_id, addr); #endif found = 1; } } if (found) continue; /* Now, we will do a detection, but only if it is in the normal or probe entries */ if (is_isa) { for (i = 0; !found && (address_data->normal_isa[i] != SENSORS_ISA_END); i += 1) { if (addr == address_data->normal_isa[i]) { #ifdef DEBUG printk ("i2c-proc.o: found normal isa entry for adapter %d, " "addr %04x\n", adapter_id, addr); #endif found = 1; } } for (i = 0; !found && (address_data->normal_isa_range[i] != SENSORS_ISA_END); i += 3) { if ((addr >= address_data->normal_isa_range[i]) && (addr <= address_data->normal_isa_range[i + 1]) && ((addr - address_data->normal_isa_range[i]) % address_data->normal_isa_range[i + 2] == 0)) { #ifdef DEBUG printk ("i2c-proc.o: found normal isa_range entry for adapter %d, " "addr %04x", adapter_id, addr); #endif found = 1; } } } else { for (i = 0; !found && (address_data->normal_i2c[i] != SENSORS_I2C_END); i += 1) { if (addr == address_data->normal_i2c[i]) { found = 1; #ifdef DEBUG printk ("i2c-proc.o: found normal i2c entry for adapter %d, " "addr %02x", adapter_id, addr); #endif } } for (i = 0; !found && (address_data->normal_i2c_range[i] != SENSORS_I2C_END); i += 2) { if ((addr >= address_data->normal_i2c_range[i]) && (addr <= address_data->normal_i2c_range[i + 1])) { #ifdef DEBUG printk ("i2c-proc.o: found normal i2c_range entry for adapter %d, " "addr %04x\n", adapter_id, addr); #endif found = 1; } } } for (i = 0; !found && (address_data->probe[i] != SENSORS_I2C_END); i += 2) { if (((adapter_id == address_data->probe[i]) || ((address_data-> probe[i] == SENSORS_ANY_I2C_BUS) & !is_isa)) && (addr == address_data->probe[i + 1])) { #ifdef DEBUG printk ("i2c-proc.o: found probe parameter for adapter %d, " "addr %04x\n", adapter_id, addr); #endif found = 1; } } for (i = 0; !found && (address_data->probe_range[i] != SENSORS_I2C_END); i += 3) { if ( ((adapter_id == address_data->probe_range[i]) || ((address_data->probe_range[i] == SENSORS_ANY_I2C_BUS) & !is_isa)) && (addr >= address_data->probe_range[i + 1]) && (addr <= address_data->probe_range[i + 2])) { found = 1; #ifdef DEBUG printk ("i2c-proc.o: found probe_range parameter for adapter %d, " "addr %04x\n", adapter_id, addr); #endif } } if (!found) continue; /* OK, so we really should examine this address. First check whether there is some client here at all! */ if (is_isa || (i2c_smbus_xfer (adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL) >= 0)) if ((err = found_proc(adapter, addr, 0, -1))) return err; } return 0; }
int __init init_display_devices(void) { int ret; #ifdef CONFIG_DISPLAY_GENERIC_DSI_PRIMARY_VSYNC struct i2c_adapter *i2c0; #endif ret = fb_register_client(&framebuffer_nb); if (ret) pr_warning("Failed to register framebuffer notifier\n"); ret = mcde_dss_register_notifier(&display_nb); if (ret) pr_warning("Failed to register dss notifier\n"); #ifdef CONFIG_DISPLAY_GENERIC_PRIMARY if (machine_is_hrefv60()) generic_display0_pdata.reset_gpio = HREFV60_DISP1_RST_GPIO; else generic_display0_pdata.reset_gpio = EGPIO_PIN_15; #ifdef CONFIG_DISPLAY_GENERIC_DSI_PRIMARY_VSYNC i2c0 = i2c_get_adapter(0); if (i2c0) { /* * U8500-UIB has the TC35893 at 0x44 on I2C0, the * ST-UIB has not. */ ret = i2c_smbus_xfer(i2c0, 0x44, 0, I2C_SMBUS_WRITE, 0, I2C_SMBUS_QUICK, NULL); i2c_put_adapter(i2c0); /* ret == 0 => U8500 UIB connected */ generic_display0.synchronized_update = (ret == 0); } #endif if (display_initialized_during_boot) generic_display0.power_mode = MCDE_DISPLAY_PM_STANDBY; ret = mcde_display_device_register(&generic_display0); if (ret) pr_warning("Failed to register generic display device 0\n"); #endif #ifdef CONFIG_DISPLAY_GENERIC_DSI_SECONDARY if (machine_is_hrefv60()) generic_subdisplay_pdata.reset_gpio = HREFV60_DISP2_RST_GPIO; else generic_subdisplay_pdata.reset_gpio = EGPIO_PIN_14; ret = mcde_display_device_register(&generic_subdisplay); if (ret) pr_warning("Failed to register generic sub display device\n"); #endif #ifdef CONFIG_DISPLAY_AV8100_TERTIARY INIT_DELAYED_WORK_DEFERRABLE(&work_dispreg_hdmi, delayed_work_dispreg_hdmi); schedule_delayed_work(&work_dispreg_hdmi, msecs_to_jiffies(DISPREG_HDMI_DELAY)); #endif #ifdef CONFIG_DISPLAY_AB8500_TERTIARY ret = mcde_display_device_register(&tvout_ab8500_display); if (ret) pr_warning("Failed to register ab8500 tvout device\n"); #endif return ret; }
static int i2c_scan_bus(struct vmm_chardev *cdev, struct i2c_adapter *adap, int mode, unsigned int funcs, int first, int last) { int i = 0; int j = 0; int cmd = 0; int res = 0; union i2c_smbus_data data; vmm_cprintf(cdev, "I2C detect on %s\n", adap->name); vmm_cprintf(cdev, " 0 1 2 3 4 5 6 7 8 9 a b c d e " "f\n"); for (i = 0; i < 128; i += 16) { vmm_cprintf(cdev, "%02x: ", i); for(j = 0; j < 16; j++) { cmd = mode; /* Select detection command for this address */ if (MODE_AUTO == mode) { if ((i+j >= 0x30 && i+j <= 0x37) || (i+j >= 0x50 && i+j <= 0x5F)) { cmd = MODE_READ; } else { cmd = MODE_QUICK; } } /* Skip unwanted addresses */ if (i + j < first || i + j > last || (cmd == MODE_READ && !(funcs & I2C_FUNC_SMBUS_READ_BYTE)) || (cmd == MODE_QUICK && !(funcs & I2C_FUNC_SMBUS_QUICK))) { vmm_cprintf(cdev, " "); continue; } if (MODE_READ == cmd) { /* This is known to lock SMBus on various write-only chips (mainly clock chips) */ res = i2c_smbus_xfer(adap, i + j, 0, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data); } else { /* MODE_QUICK */ /* This is known to corrupt the Atmel AT24RF08 EEPROM */ res = i2c_smbus_xfer(adap, i + j, 0, I2C_SMBUS_WRITE, 0, I2C_SMBUS_QUICK, NULL); } if (res < 0) vmm_cprintf(cdev, "-- "); else vmm_cprintf(cdev, "%02x ", i + j); } vmm_cprintf(cdev, "\n"); } return VMM_OK; }
/** * i2c_smbus_write_byte - SMBus "send byte" protocol * @client: Handle to slave device * @value: Byte to be sent * * This executes the SMBus "send byte" protocol, returning negative errno * else zero on success. */ s32 i2c_smbus_write_byte(const struct i2c_client *client, u8 value) { return i2c_smbus_xfer(client->adapter, client->addr, 0 /* client->flags */, I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL); }
/* The ADM1032 supports PEC but not on write byte transactions, so we need to explicitly ask for a transaction without PEC. */ static inline s32 adm1032_write_byte(struct i2c_client *client, u8 value) { return i2c_smbus_xfer(client->adapter, client->addr, client->flags & ~I2C_CLIENT_PEC, I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL); }
static int create_iface(struct device_node *np, struct device *dev) { unsigned long steps, *psteps, *prate; unsigned bsteps, tsize, i, nchan, addroffset; struct keywest_iface* iface; int rc; psteps = (unsigned long *)get_property(np, "AAPL,address-step", NULL); steps = psteps ? (*psteps) : 0x10; /* Hrm... maybe we can be smarter here */ for (bsteps = 0; (steps & 0x01) == 0; bsteps++) steps >>= 1; if (!strcmp(np->parent->name, "uni-n")) { nchan = 2; addroffset = 3; } else { addroffset = 0; nchan = 1; } tsize = sizeof(struct keywest_iface) + (sizeof(struct keywest_chan) + 4) * nchan; iface = (struct keywest_iface *) kmalloc(tsize, GFP_KERNEL); if (iface == NULL) { printk(KERN_ERR "i2c-keywest: can't allocate inteface !\n"); return -ENOMEM; } memset(iface, 0, tsize); init_MUTEX(&iface->sem); spin_lock_init(&iface->lock); init_completion(&iface->complete); iface->bsteps = bsteps; iface->chan_count = nchan; iface->state = state_idle; iface->irq = np->intrs[0].line; iface->channels = (struct keywest_chan *) (((unsigned long)(iface + 1) + 3UL) & ~3UL); iface->base = (unsigned long)ioremap(np->addrs[0].address + addroffset, np->addrs[0].size); if (iface->base == 0) { printk(KERN_ERR "i2c-keywest: can't map inteface !\n"); kfree(iface); return -ENOMEM; } init_timer(&iface->timeout_timer); iface->timeout_timer.function = keywest_timeout; iface->timeout_timer.data = (unsigned long)iface; /* Select interface rate */ iface->cur_mode = KW_I2C_MODE_100KHZ; prate = (unsigned long *)get_property(np, "AAPL,i2c-rate", NULL); if (prate) switch(*prate) { case 100: iface->cur_mode = KW_I2C_MODE_100KHZ; break; case 50: iface->cur_mode = KW_I2C_MODE_50KHZ; break; case 25: iface->cur_mode = KW_I2C_MODE_25KHZ; break; default: printk(KERN_WARNING "i2c-keywest: unknown rate %ldKhz, using 100KHz\n", *prate); } /* Select standard sub mode */ iface->cur_mode |= KW_I2C_MODE_STANDARDSUB; /* Write mode */ write_reg(reg_mode, iface->cur_mode); /* Switch interrupts off & clear them*/ write_reg(reg_ier, 0x00); write_reg(reg_isr, KW_I2C_IRQ_MASK); /* Request chip interrupt */ rc = request_irq(iface->irq, keywest_irq, 0, "keywest i2c", iface); if (rc) { printk(KERN_ERR "i2c-keywest: can't get IRQ %d !\n", iface->irq); iounmap((void *)iface->base); kfree(iface); return -ENODEV; } dev_set_drvdata(dev, iface); for (i=0; i<nchan; i++) { struct keywest_chan* chan = &iface->channels[i]; u8 addr; sprintf(chan->adapter.name, "%s %d", np->parent->name, i); chan->iface = iface; chan->chan_no = i; chan->adapter.id = I2C_ALGO_SMBUS; chan->adapter.algo = &keywest_algorithm; chan->adapter.algo_data = NULL; chan->adapter.client_register = NULL; chan->adapter.client_unregister = NULL; i2c_set_adapdata(&chan->adapter, chan); chan->adapter.dev.parent = dev; rc = i2c_add_adapter(&chan->adapter); if (rc) { printk("i2c-keywest.c: Adapter %s registration failed\n", chan->adapter.name); i2c_set_adapdata(&chan->adapter, NULL); } if (probe) { printk("Probe: "); for (addr = 0x00; addr <= 0x7f; addr++) { if (i2c_smbus_xfer(&chan->adapter,addr, 0,0,0,I2C_SMBUS_QUICK,NULL) >= 0) printk("%02x ", addr); } printk("\n"); } } printk(KERN_INFO "Found KeyWest i2c on \"%s\", %d channel%s, stepping: %d bits\n", np->parent->name, nchan, nchan > 1 ? "s" : "", bsteps); return 0; }
static int __init amd756_s4882_init(void) { int i, error; union i2c_smbus_data ioconfig; if (!amd756_smbus.dev.parent) return -ENODEV; /* Configure the PCA9556 multiplexer */ ioconfig.byte = 0x00; /* All I/O to output mode */ error = i2c_smbus_xfer(&amd756_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03, I2C_SMBUS_BYTE_DATA, &ioconfig); if (error) { dev_err(&amd756_smbus.dev, "PCA9556 configuration failed\n"); error = -EIO; goto ERROR0; } /* Unregister physical bus */ i2c_del_adapter(&amd756_smbus); printk(KERN_INFO "Enabling SMBus multiplexing for Tyan S4882\n"); /* Define the 5 virtual adapters and algorithms structures */ if (!(s4882_adapter = kzalloc(5 * sizeof(struct i2c_adapter), GFP_KERNEL))) { error = -ENOMEM; goto ERROR1; } if (!(s4882_algo = kzalloc(5 * sizeof(struct i2c_algorithm), GFP_KERNEL))) { error = -ENOMEM; goto ERROR2; } /* Fill in the new structures */ s4882_algo[0] = *(amd756_smbus.algo); s4882_algo[0].smbus_xfer = amd756_access_virt0; s4882_adapter[0] = amd756_smbus; s4882_adapter[0].algo = s4882_algo; s4882_adapter[0].dev.parent = amd756_smbus.dev.parent; for (i = 1; i < 5; i++) { s4882_algo[i] = *(amd756_smbus.algo); s4882_adapter[i] = amd756_smbus; snprintf(s4882_adapter[i].name, sizeof(s4882_adapter[i].name), "SMBus 8111 adapter (CPU%d)", i-1); s4882_adapter[i].algo = s4882_algo+i; s4882_adapter[i].dev.parent = amd756_smbus.dev.parent; } s4882_algo[1].smbus_xfer = amd756_access_virt1; s4882_algo[2].smbus_xfer = amd756_access_virt2; s4882_algo[3].smbus_xfer = amd756_access_virt3; s4882_algo[4].smbus_xfer = amd756_access_virt4; /* Register virtual adapters */ for (i = 0; i < 5; i++) { error = i2c_add_adapter(s4882_adapter+i); if (error) { printk(KERN_ERR "i2c-amd756-s4882: " "Virtual adapter %d registration " "failed, module not inserted\n", i); for (i--; i >= 0; i--) i2c_del_adapter(s4882_adapter+i); goto ERROR3; } } return 0; ERROR3: kfree(s4882_algo); s4882_algo = NULL; ERROR2: kfree(s4882_adapter); s4882_adapter = NULL; ERROR1: /* Restore physical bus */ i2c_add_adapter(&amd756_smbus); ERROR0: return error; }
int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct i2c_client *client = (struct i2c_client *)file->private_data; struct i2c_rdwr_ioctl_data rdwr_arg; struct i2c_smbus_ioctl_data data_arg; union i2c_smbus_data temp; struct i2c_msg *rdwr_pa; u8 **data_ptrs; int i,datasize,res; unsigned long funcs; #ifdef DEBUG printk(KERN_DEBUG "i2c-dev.o: i2c-%d ioctl, cmd: 0x%x, arg: %lx.\n", MINOR(inode->i_rdev),cmd, arg); #endif /* DEBUG */ switch ( cmd ) { case I2C_SLAVE: case I2C_SLAVE_FORCE: if ((arg > 0x3ff) || (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f)) return -EINVAL; if ((cmd == I2C_SLAVE) && i2c_check_addr(client->adapter,arg)) return -EBUSY; client->addr = arg; return 0; case I2C_TENBIT: if (arg) client->flags |= I2C_M_TEN; else client->flags &= ~I2C_M_TEN; return 0; case I2C_FUNCS: funcs = i2c_get_functionality(client->adapter); return (copy_to_user((unsigned long *)arg,&funcs, sizeof(unsigned long)))?-EFAULT:0; case I2C_RDWR: if (copy_from_user(&rdwr_arg, (struct i2c_rdwr_ioctl_data *)arg, sizeof(rdwr_arg))) return -EFAULT; /* Put an arbritrary limit on the number of messages that can * be sent at once */ if (rdwr_arg.nmsgs > 42) return -EINVAL; rdwr_pa = (struct i2c_msg *) kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg), GFP_KERNEL); if (rdwr_pa == NULL) return -ENOMEM; if (copy_from_user(rdwr_pa, rdwr_arg.msgs, rdwr_arg.nmsgs * sizeof(struct i2c_msg))) { kfree(rdwr_pa); return -EFAULT; } data_ptrs = (u8 **) kmalloc(rdwr_arg.nmsgs * sizeof(u8 *), GFP_KERNEL); if (data_ptrs == NULL) { kfree(rdwr_pa); return -ENOMEM; } res = 0; for( i=0; i<rdwr_arg.nmsgs; i++ ) { /* Limit the size of the message to a sane amount */ if (rdwr_pa[i].len > 8192) { res = -EINVAL; break; } data_ptrs[i] = rdwr_pa[i].buf; rdwr_pa[i].buf = kmalloc(rdwr_pa[i].len, GFP_KERNEL); if(rdwr_pa[i].buf == NULL) { res = -ENOMEM; break; } if(copy_from_user(rdwr_pa[i].buf, data_ptrs[i], rdwr_pa[i].len)) { ++i; /* Needs to be kfreed too */ res = -EFAULT; break; } } if (res < 0) { int j; for (j = 0; j < i; ++j) kfree(rdwr_pa[j].buf); kfree(data_ptrs); kfree(rdwr_pa); return res; } res = i2c_transfer(client->adapter, rdwr_pa, rdwr_arg.nmsgs); while(i-- > 0) { if( res>=0 && (rdwr_pa[i].flags & I2C_M_RD)) { if(copy_to_user( data_ptrs[i], rdwr_pa[i].buf, rdwr_pa[i].len)) { res = -EFAULT; } } kfree(rdwr_pa[i].buf); } kfree(data_ptrs); kfree(rdwr_pa); return res; case I2C_SMBUS: if (copy_from_user(&data_arg, (struct i2c_smbus_ioctl_data *) arg, sizeof(struct i2c_smbus_ioctl_data))) return -EFAULT; if ((data_arg.size != I2C_SMBUS_BYTE) && (data_arg.size != I2C_SMBUS_QUICK) && (data_arg.size != I2C_SMBUS_BYTE_DATA) && (data_arg.size != I2C_SMBUS_WORD_DATA) && (data_arg.size != I2C_SMBUS_PROC_CALL) && (data_arg.size != I2C_SMBUS_BLOCK_DATA) && (data_arg.size != I2C_SMBUS_I2C_BLOCK_DATA)) { #ifdef DEBUG printk(KERN_DEBUG "i2c-dev.o: size out of range (%x) in ioctl I2C_SMBUS.\n", data_arg.size); #endif return -EINVAL; } /* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1, so the check is valid if size==I2C_SMBUS_QUICK too. */ if ((data_arg.read_write != I2C_SMBUS_READ) && (data_arg.read_write != I2C_SMBUS_WRITE)) { #ifdef DEBUG printk(KERN_DEBUG "i2c-dev.o: read_write out of range (%x) in ioctl I2C_SMBUS.\n", data_arg.read_write); #endif return -EINVAL; } /* Note that command values are always valid! */ if ((data_arg.size == I2C_SMBUS_QUICK) || ((data_arg.size == I2C_SMBUS_BYTE) && (data_arg.read_write == I2C_SMBUS_WRITE))) /* These are special: we do not use data */ return i2c_smbus_xfer(client->adapter, client->addr, client->flags, data_arg.read_write, data_arg.command, data_arg.size, NULL); if (data_arg.data == NULL) { #ifdef DEBUG printk(KERN_DEBUG "i2c-dev.o: data is NULL pointer in ioctl I2C_SMBUS.\n"); #endif return -EINVAL; } if ((data_arg.size == I2C_SMBUS_BYTE_DATA) || (data_arg.size == I2C_SMBUS_BYTE)) datasize = sizeof(data_arg.data->byte); else if ((data_arg.size == I2C_SMBUS_WORD_DATA) || (data_arg.size == I2C_SMBUS_PROC_CALL)) datasize = sizeof(data_arg.data->word); else /* size == I2C_SMBUS_BLOCK_DATA */ datasize = sizeof(data_arg.data->block); if ((data_arg.size == I2C_SMBUS_PROC_CALL) || (data_arg.read_write == I2C_SMBUS_WRITE)) { if (copy_from_user(&temp, data_arg.data, datasize)) return -EFAULT; } res = i2c_smbus_xfer(client->adapter,client->addr,client->flags, data_arg.read_write, data_arg.command,data_arg.size,&temp); if (! res && ((data_arg.size == I2C_SMBUS_PROC_CALL) || (data_arg.read_write == I2C_SMBUS_READ))) { if (copy_to_user(data_arg.data, &temp, datasize)) return -EFAULT; } return res; default: return i2c_control(client,cmd,arg); } return 0; }