/*
 * 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;
}
示例#6
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);
}
示例#7
0
/**
 * 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);
}
示例#8
0
/**
 * 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;
}
示例#9
0
/**
 * 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);
}
示例#11
0
/**
 * 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;
}
示例#12
0
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;
}
示例#13
0
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);
}
示例#14
0
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 ;
}
示例#15
0
/**
 * 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];
}
示例#16
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];
}
示例#17
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);
	}
}
示例#19
0
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;
}
示例#20
0
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;
}
示例#23
0
/* 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;
}
示例#25
0
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;
}
示例#26
0
/**
 * 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);
}
示例#27
0
文件: lm90.c 项目: zhoupeng/spice4xen
/* 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);
}
示例#28
0
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;
}
示例#29
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;
}
示例#30
0
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;
}