コード例 #1
0
ファイル: tcpci.c プロジェクト: fourier49/BIZ_EC
int tcpm_transmit(int port, enum tcpm_transmit_type type, uint16_t header,
		   const uint32_t *data)
{
	int reg = TCPC_REG_TX_DATA;
	int rv, cnt = 4*PD_HEADER_CNT(header);

	rv = i2c_write8(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
			TCPC_REG_TX_BYTE_CNT, cnt);

	rv |= i2c_write16(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
			  TCPC_REG_TX_HDR, header);

	/* If i2c read fails, return error */
	if (rv)
		return rv;

	if (cnt > 0) {
		i2c_lock(I2C_PORT_TCPC, 1);
		rv = i2c_xfer(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
			      (uint8_t *)&reg, 1, NULL, 0, I2C_XFER_START);
		rv |= i2c_xfer(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
			       (uint8_t *)data, cnt, NULL, 0, I2C_XFER_STOP);
		i2c_lock(I2C_PORT_TCPC, 0);
	}

	/* If i2c read fails, return error */
	if (rv)
		return rv;

	rv = i2c_write8(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
			TCPC_REG_TRANSMIT, TCPC_REG_TRANSMIT_SET(type));

	return rv;
}
コード例 #2
0
ファイル: i2c-stm32f0.c プロジェクト: gelraen/cros-ec
int i2c_read_string(int port, int slave_addr, int offset, uint8_t *data,
	int len)
{
	int rv;
	uint8_t reg, block_length;

	/*
	 * TODO(crosbug.com/p/23569): when i2c_xfer() supports start/stop bits,
	 * merge this with the LM4 implementation and move to i2c_common.c.
	 */

	if ((len <= 0) || (len > SMBUS_MAX_BLOCK))
		return EC_ERROR_INVAL;

	i2c_lock(port, 1);

	/* Read the counted string into the output buffer */
	reg = offset;
	rv = i2c_xfer(port, slave_addr, &reg, 1, data, len, I2C_XFER_SINGLE);
	if (rv == EC_SUCCESS) {
		/* Block length is the first byte of the returned buffer */
		block_length = MIN(data[0], len - 1);

		/* Move data down, then null-terminate it */
		memmove(data, data + 1, block_length);
		data[block_length] = 0;
	}

	i2c_lock(port, 0);
	return rv;
}
コード例 #3
0
/* Come out of standby mode. */
void lb_on(void)
{
	CPRINTS("LB_on");
	i2c_lock(I2C_PORT_LIGHTBAR, 1);
	controller_write(0, 0x01, 0x20);
	controller_write(1, 0x01, 0x20);
	i2c_lock(I2C_PORT_LIGHTBAR, 0);
}
コード例 #4
0
/* Helper function to set one LED color and remember it for later */
static void setrgb(int led, int red, int green, int blue)
{
	int ctrl, bank;
	current[led][0] = red;
	current[led][1] = green;
	current[led][2] = blue;
	ctrl = led_to_ctrl[led];
	bank = led_to_isc[led];
	i2c_lock(I2C_PORT_LIGHTBAR, 1);
	controller_write(ctrl, bank, scale(blue, MAX_BLUE));
	controller_write(ctrl, bank+1, scale(red, MAX_RED));
	controller_write(ctrl, bank+2, scale(green, MAX_GREEN));
	i2c_lock(I2C_PORT_LIGHTBAR, 0);
}
コード例 #5
0
ファイル: gyro_l3gd20h.c プロジェクト: fishbaoz/chrome-ec
static int read(const struct motion_sensor_t *s, vector_3_t v)
{
	uint8_t raw[6];
	uint8_t xyz_reg;
	int ret, range, i, tmp = 0;
	struct l3gd20_data *data = s->drv_data;

	ret = is_data_ready(s, &tmp);
	if (ret != EC_SUCCESS)
		return ret;

	/*
	 * If sensor data is not ready, return the previous read data.
	 * Note: return success so that motion senor task can read again
	 * to get the latest updated sensor data quickly.
	 */
	if (!tmp) {
		if (v != s->raw_xyz)
			memcpy(v, s->raw_xyz, sizeof(s->raw_xyz));
		return EC_SUCCESS;
	}

	xyz_reg = get_xyz_reg(s->type);

	/* Read 6 bytes starting at xyz_reg */
	i2c_lock(s->port, 1);
	ret = i2c_xfer(s->port, s->addr,
			&xyz_reg, 1, raw, 6, I2C_XFER_SINGLE);
	i2c_lock(s->port, 0);

	if (ret != EC_SUCCESS) {
		CPRINTF("[%T %s type:0x%X RD XYZ Error]",
			s->name, s->type);
		return ret;
	}

	for (i = X; i <= Z; i++)
		v[i] = ((int16_t)((raw[i * 2 + 1] << 8) | raw[i * 2]));

	if (s->rot_standard_ref)
		rotate(v, *s->rot_standard_ref, v);

	/* apply offset in the device coordinates */
	range = get_range(s);
	for (i = X; i <= Z; i++)
		v[i] += (data->offset[i] << 5) / range;

	return EC_SUCCESS;
}
コード例 #6
0
ファイル: touchpad_elan.c プロジェクト: coreboot/chrome-ec
static int elan_tp_read_cmd(uint16_t reg, uint16_t *val)
{
	uint8_t buf[2];
	int rv;

	buf[0] = reg;
	buf[1] = reg >> 8;

	i2c_lock(CONFIG_TOUCHPAD_I2C_PORT, 1);
	rv = i2c_xfer(CONFIG_TOUCHPAD_I2C_PORT, CONFIG_TOUCHPAD_I2C_ADDR,
		      buf, sizeof(buf), (uint8_t *)val, sizeof(*val),
		      I2C_XFER_SINGLE);
	i2c_lock(CONFIG_TOUCHPAD_I2C_PORT, 0);

	return rv;
}
コード例 #7
0
ファイル: bh1750.c プロジェクト: peter-mount/piweather.center
static void update(struct sensor *sensor) {
    if (!i2c_lock()) {
        struct state *state = (struct state *) sensor;
        uint8_t cmd[4];
        int r = 0;
        int v;

        cmd[0] = state->level ? CMD_SAMP_HIRES2 : CMD_SAMP_LORES;
        r = i2c_write(state->slave, cmd, 1);

        if (!r) {
            i2c_sleep(state->level ? SPEED_HIRES2 : SPEED_LORES);
            r = i2c_read(state->slave, cmd, 2);
        }

        if (!r) {
            v = (cmd[0] << 8) | cmd[1];
            
            // Scale is 0.1 but we need to convert to the correct value
            // So datasheet says / 1.2 but we use 0.12 as thats 10/1.2 giving
            // us the correct unit
            v = (int) ((double) v / 0.12);
        }

        // log the value
        if (!r) {
            sensor_log(sensor, v, "%s %.1f", state->format, ((double) v) * UNIT);
        }

        i2c_unlock();
    }
}
コード例 #8
0
ファイル: touchpad_elan.c プロジェクト: coreboot/chrome-ec
static int elan_tp_write_cmd(uint16_t reg, uint16_t val)
{
	uint8_t buf[4];
	int rv;

	buf[0] = reg;
	buf[1] = reg >> 8;
	buf[2] = val;
	buf[3] = val >> 8;

	i2c_lock(CONFIG_TOUCHPAD_I2C_PORT, 1);
	rv = i2c_xfer(CONFIG_TOUCHPAD_I2C_PORT, CONFIG_TOUCHPAD_I2C_ADDR,
		      buf, sizeof(buf), NULL, 0, I2C_XFER_SINGLE);
	i2c_lock(CONFIG_TOUCHPAD_I2C_PORT, 0);

	return rv;
}
コード例 #9
0
/* Helper for host command to dump controller registers */
void lb_hc_cmd_dump(struct ec_response_lightbar *out)
{
	int i;
	uint8_t reg;

	BUILD_ASSERT(ARRAY_SIZE(dump_reglist) ==
		     ARRAY_SIZE(out->dump.vals));

	for (i = 0; i < ARRAY_SIZE(dump_reglist); i++) {
		reg = dump_reglist[i];
		out->dump.vals[i].reg = reg;
		i2c_lock(I2C_PORT_LIGHTBAR, 1);
		out->dump.vals[i].ic0 = controller_read(0, reg);
		out->dump.vals[i].ic1 = controller_read(1, reg);
		i2c_lock(I2C_PORT_LIGHTBAR, 0);
	}
}
コード例 #10
0
/* Initialize the controller ICs after reset */
void lb_init(int use_lock)
{
	int i;

	CPRINTF("[%T LB_init_vals ");
	for (i = 0; i < ARRAY_SIZE(init_vals); i++) {
		CPRINTF("%c", '0' + i % 10);
		if (use_lock)
			i2c_lock(I2C_PORT_LIGHTBAR, 1);
		controller_write(0, init_vals[i].reg, init_vals[i].val);
		controller_write(1, init_vals[i].reg, init_vals[i].val);
		if (use_lock)
			i2c_lock(I2C_PORT_LIGHTBAR, 0);
	}
	CPRINTF("]\n");
	memset(current, 0, sizeof(current));
}
コード例 #11
0
ファイル: battery.c プロジェクト: coreboot/chrome-ec
int board_cut_off_battery(void)
{
	int rv;
	uint8_t buf[3];

	buf[0] = SB_MANUFACTURER_ACCESS & 0xff;
	buf[1] = PARAM_CUT_OFF_LOW;
	buf[2] = PARAM_CUT_OFF_HIGH;

	i2c_lock(I2C_PORT_BATTERY, 1);
	rv = i2c_xfer(I2C_PORT_BATTERY, BATTERY_ADDR, buf, 3, NULL, 0,
		      I2C_XFER_SINGLE);
	rv |= i2c_xfer(I2C_PORT_BATTERY, BATTERY_ADDR, buf, 3, NULL, 0,
		      I2C_XFER_SINGLE);
	i2c_lock(I2C_PORT_BATTERY, 0);

	return rv;
}
コード例 #12
0
static void i2c_pre_freq_change_hook(void)
{
	const struct i2c_port_t *p = i2c_ports;
	int i;

	/* Lock I2C ports so freq change can't interrupt an I2C transaction */
	for (i = 0; i < i2c_ports_used; i++, p++)
		i2c_lock(p->port, 1);
}
コード例 #13
0
ファイル: battery.c プロジェクト: Basavaraja-MS/ec_local
static int cutoff(void)
{
	int rv;
	uint8_t buf[3];

	/* Ship mode command must be sent twice to take effect */
	buf[0] = SB_MANUFACTURER_ACCESS & 0xff;
	buf[1] = PARAM_CUT_OFF_LOW;
	buf[2] = PARAM_CUT_OFF_HIGH;

	i2c_lock(I2C_PORT_BATTERY, 1);
	rv = i2c_xfer(I2C_PORT_BATTERY, BATTERY_ADDR, buf, 3, NULL, 0,
		      I2C_XFER_SINGLE);
	rv |= i2c_xfer(I2C_PORT_BATTERY, BATTERY_ADDR, buf, 3, NULL, 0,
		       I2C_XFER_SINGLE);
	i2c_lock(I2C_PORT_BATTERY, 0);

	return rv;
}
コード例 #14
0
static void i2c_freq_change_hook(void)
{
	const struct i2c_port_t *p = i2c_ports;
	int i;

	i2c_freq_change();

	/* Unlock I2C ports we locked in pre-freq change hook */
	for (i = 0; i < i2c_ports_used; i++, p++)
		i2c_lock(p->port, 0);
}
コード例 #15
0
ファイル: i2c.c プロジェクト: alterapraxisptyltd/chromium-ec
int i2c_read16(int port, int slave_addr, int offset, int *data)
{
	int rv;
	uint8_t reg, buf[2];

	reg = offset & 0xff;
	/* I2C read 16-bit word: transmit 8-bit offset, and read 16bits */
	i2c_lock(port, 1);
	rv = i2c_xfer(port, slave_addr, &reg, 1, buf, 2, I2C_XFER_SINGLE);
	i2c_lock(port, 0);

	if (rv)
		return rv;

	if (slave_addr & I2C_FLAG_BIG_ENDIAN)
		*data = ((int)buf[0] << 8) | buf[1];
	else
		*data = ((int)buf[1] << 8) | buf[0];

	return EC_SUCCESS;
}
コード例 #16
0
int pcf50605_write_multiple(int address, const unsigned char* buf, int count)
{
    int i;

    i2c_lock();

    for (i = 0; i < count; i++)
        pp_i2c_send(0x8, address + i, buf[i]);

    i2c_unlock();

    return 0;
}
コード例 #17
0
ファイル: GSensor.c プロジェクト: magic-gjh/NT96655_S600_A5
void GSensor_I2C_WriteReg(UINT32 uiAddr, UINT32 uiValue)
{
    UINT        erReturn;
    UINT32      ulWriteAddr, ulReg1, ulData;
    UINT32      ulReg2 = 0;

    i2c_lock(g_GsensorInfo.I2C_Channel);

    ulWriteAddr = g_GsensorInfo.I2C_Slave_WAddr;
    if (g_GsensorInfo.I2C_RegBytes == GSENSOR_I2C_REGISTER_2BYTE)
    {
        ulReg1      = (uiAddr>>8);
        ulReg2      = ((uiAddr)&(0x000000ff));
    } else {
コード例 #18
0
ファイル: tcpci.c プロジェクト: fourier49/BIZ_EC
int tcpm_get_message(int port, uint32_t *payload, int *head)
{
	int rv, cnt, reg = TCPC_REG_RX_DATA;

	rv = i2c_read8(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
		       TCPC_REG_RX_BYTE_CNT, &cnt);

	rv |= i2c_read16(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
			 TCPC_REG_RX_HDR, (int *)head);

	if (rv == EC_SUCCESS && cnt > 0) {
		i2c_lock(I2C_PORT_TCPC, 1);
		rv = i2c_xfer(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
			      (uint8_t *)&reg, 1, (uint8_t *)payload,
			      cnt, I2C_XFER_SINGLE);
		i2c_lock(I2C_PORT_TCPC, 0);
	}

	/* Read complete, clear RX status alert bit */
	i2c_write16(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
		    TCPC_REG_ALERT, TCPC_REG_ALERT_RX_STATUS);

	return rv;
}
コード例 #19
0
RET_CODE i2c_raw_stop(i2c_bus_t *p_dev)
{
  RET_CODE ret = ERR_NOFEATURE;
  lld_i2c_t *p_lld = (lld_i2c_t *)p_dev->p_priv;
  device_base_t *p_base = (device_base_t *)p_dev->p_base;

  if(drv_check_cond(p_dev) == SUCCESS)
  {
    MT_ASSERT(p_lld->std_read != NULL);
    i2c_lock(p_base);
    ret = p_lld->raw_stop(p_lld);
    i2c_unlock(p_base);
  }
  return ret;
}
コード例 #20
0
RET_CODE i2c_read(i2c_bus_t *p_dev, u8 slv_addr, u8 *p_buf, u32 len, u32 param)
{
  RET_CODE ret = ERR_NOFEATURE;
  lld_i2c_t *p_lld = (lld_i2c_t *)p_dev->p_priv;
  device_base_t *p_base = (device_base_t *)p_dev->p_base;

  if(drv_check_cond(p_dev) == SUCCESS)
  {
    MT_ASSERT(p_lld->read != NULL);
    i2c_lock(p_base);
    ret = p_lld->read(p_lld, slv_addr, p_buf, len, param);
    i2c_unlock(p_base);
  }

  return ret;
}
コード例 #21
0
ファイル: touchpad_elan.c プロジェクト: coreboot/chrome-ec
/* Initialize the controller ICs after reset */
static int elan_tp_init(void)
{
	int rv;
	uint8_t val[2];

	CPRINTS("%s", __func__);

	elan_tp_write_cmd(ETP_I2C_STAND_CMD, ETP_I2C_RESET);
	msleep(100);
	i2c_lock(CONFIG_TOUCHPAD_I2C_PORT, 1);
	rv = i2c_xfer(CONFIG_TOUCHPAD_I2C_PORT, CONFIG_TOUCHPAD_I2C_ADDR,
		      NULL, 0, val, sizeof(val), I2C_XFER_SINGLE);
	i2c_lock(CONFIG_TOUCHPAD_I2C_PORT, 0);

	CPRINTS("reset rv %d buf=%04x", rv, *((uint16_t *)val));
	if (rv)
		goto out;

	/* Read min/max */
	rv = elan_tp_read_cmd(ETP_I2C_MAX_X_AXIS_CMD, &elan_tp_params.max_x);
	if (rv)
		goto out;
	rv = elan_tp_read_cmd(ETP_I2C_MAX_Y_AXIS_CMD, &elan_tp_params.max_y);
	if (rv)
		goto out;

	/* Read min/max */
	rv = elan_tp_read_cmd(ETP_I2C_XY_TRACENUM_CMD, (uint16_t *)val);
	if (rv)
		goto out;
	if (val[0] == 0 || val[1] == 0) {
		CPRINTS("Invalid XY_TRACENUM");
		goto out;
	}

	/* ETP_FWIDTH_REDUCE reduces the apparent width to avoid treating large
	 * finger as palm. Multiply value by 2 as HID multitouch divides it.
	 */
	elan_tp_params.width_x =
		2 * ((elan_tp_params.max_x / val[0]) - ETP_FWIDTH_REDUCE);
	elan_tp_params.width_y =
		2 * ((elan_tp_params.max_y / val[1]) - ETP_FWIDTH_REDUCE);

	rv = elan_tp_read_cmd(ETP_I2C_PRESSURE_CMD, (uint16_t *)val);
	if (rv)
		goto out;
	elan_tp_params.pressure_adj = (val[0] & 0x10) ? 0 : ETP_PRESSURE_OFFSET;

	CPRINTS("max=%d/%d width=%d/%d adj=%d",
		elan_tp_params.max_x, elan_tp_params.max_y,
		elan_tp_params.width_x, elan_tp_params.width_y,
		elan_tp_params.pressure_adj);

	/* Switch to absolute mode */
	rv = elan_tp_write_cmd(ETP_I2C_SET_CMD, ETP_ENABLE_ABS);
	if (rv)
		goto out;

	/* Sleep control off */
	rv = elan_tp_write_cmd(ETP_I2C_STAND_CMD, ETP_I2C_WAKE_UP);

out:
	CPRINTS("%s:%d", __func__, rv);
	return rv;
}
コード例 #22
0
/* Helper for host command to write controller registers directly */
void lb_hc_cmd_reg(const struct ec_params_lightbar *in)
{
	i2c_lock(I2C_PORT_LIGHTBAR, 1);
	controller_write(in->reg.ctrl, in->reg.reg, in->reg.value);
	i2c_lock(I2C_PORT_LIGHTBAR, 0);
}
コード例 #23
0
ファイル: Gsensor_DA380.c プロジェクト: magic-gjh/NT96650_K12
static UINT32 GSensor_DA380_ReadReg_2Byte(UINT32 uiAddr, UINT32 uidata)
{
    UINT32      ulWriteAddr, ulReadAddr, ulReg1;
    static UINT32 ulData1,ulData2;

    ulWriteAddr =0x30;
    ulReadAddr  =0x31;
    ulReg1      =(uiAddr&0x000000ff);
    ulData1     = 0;
    ulData2 = 0;
    //debug_err((">>> read register\r\n"));
    if(i2c_lock(g_GsensorInfo.I2C_Channel) != E_OK)
    {
        debug_err(("GSensor: readReg I2C Lock Fail\r\n"));
        return ulData1;
    }

    if (GSensor_I2C_Transmit(ulWriteAddr, 1, 0) != I2C_STS_OK)
    {
        debug_err(("Error transmit data1!!\r\n"));
        i2c_unlock(g_GsensorInfo.I2C_Channel);
        return  ulData1;
    }

    if (GSensor_I2C_Transmit(ulReg1, 0, 0) != I2C_STS_OK)
    {
        debug_err(("Error transmit data2!!\r\n"));
        i2c_unlock(g_GsensorInfo.I2C_Channel);
        return  ulData1;
    }

    if (GSensor_I2C_Transmit(ulReadAddr, 1, 0) != I2C_STS_OK)
    {
        debug_err(("Error transmit data3!!\r\n"));
        i2c_unlock(g_GsensorInfo.I2C_Channel);
        return  ulData1;
    }

    if (GSensor_I2C_Receive(&ulData1, 0, 0) != I2C_STS_OK)
    {
        debug_err(("Error Receive data!!\r\n"));
        i2c_unlock(g_GsensorInfo.I2C_Channel);
        return  ulData1;
    }

    if (GSensor_I2C_Receive(&ulData2, 1, 1) != I2C_STS_OK)
    {
        debug_err(("Error Receive data!!\r\n"));
        i2c_unlock(g_GsensorInfo.I2C_Channel);
        return  ulData1;
    }
    if(i2c_unlock(g_GsensorInfo.I2C_Channel) != E_OK)
    {
        debug_err(("GSensor: readReg I2C UnLock Fail\r\n"));
        return  ulData1;
    }
    // debug_err((">>>>>uidata = %d %d\r\n",ulData1,ulData2));

    uidata =  (ulData1<<8) + ulData2;
    //debug_err((">>>uidata = %d\r\n",uidata));
    return  uidata;
}
コード例 #24
0
ファイル: touchpad_elan.c プロジェクト: coreboot/chrome-ec
static int elan_tp_read_report(void)
{
	int rv;
	uint8_t tp_buf[ETP_I2C_REPORT_LEN];
	int i;
	uint8_t touch_info;
	uint8_t hover_info;
	uint8_t *finger = tp_buf+ETP_FINGER_DATA_OFFSET;

	i2c_lock(CONFIG_TOUCHPAD_I2C_PORT, 1);
	rv = i2c_xfer(CONFIG_TOUCHPAD_I2C_PORT, CONFIG_TOUCHPAD_I2C_ADDR,
		      NULL, 0, tp_buf, ETP_I2C_REPORT_LEN, I2C_XFER_SINGLE);
	i2c_lock(CONFIG_TOUCHPAD_I2C_PORT, 0);

	if (rv) {
		CPRINTS("read report error");
		return rv;
	}

	CPRINTF("[%T ");
#if 0
	for (i = 0; i < ETP_I2C_REPORT_LEN; i++)
		CPRINTF("%02x", tp_buf[i]);
	CPRINTF(" || ");
#endif

	if (tp_buf[ETP_REPORT_ID_OFFSET] != ETP_REPORT_ID) {
		CPRINTS("Invalid report id (%x)", tp_buf[ETP_REPORT_ID_OFFSET]);
		return -1;
	}

	touch_info = tp_buf[ETP_TOUCH_INFO_OFFSET];
	hover_info = tp_buf[ETP_HOVER_INFO_OFFSET];

	if (touch_info & 0x01)
		CPRINTF("click|");
	if (hover_info & 0x40)
		CPRINTF("hover|");

	for (i = 0; i < ETP_MAX_FINGERS; i++) {
		int valid = touch_info & (1 << (3+i));

		if (valid) {
			int x = ((finger[0] & 0xf0) << 4) | finger[1];
			int y = ((finger[0] & 0x0f) << 8) | finger[2];
			int width = (finger[3] & 0xf0) >> 4;
			int height = finger[3] & 0x0f;
			int pressure = finger[4];

			y = elan_tp_params.max_y - y;
			width = width * elan_tp_params.width_x;
			height = height * elan_tp_params.width_y;
			pressure = pressure + elan_tp_params.pressure_adj;

			if (1)
				CPRINTF("i=%d %d/%d %d/%d %d|", i, x, y,
					width, height, pressure);
			finger += ETP_FINGER_DATA_LEN;
		}
	}
	CPRINTF("]\n");

	return 0;
}