Add I2C driver

This commit is contained in:
crides 2022-11-25 17:24:58 -06:00
parent 2e0050fa8f
commit 56a1d796af
6 changed files with 57 additions and 61 deletions

View file

@ -1,6 +1,5 @@
#define DT_DRV_COMPAT cirque_pinnacle
#include <drivers/spi.h>
#include <init.h>
#include <drivers/sensor.h>
#include <zmk/sensors.h>
@ -10,9 +9,11 @@
LOG_MODULE_REGISTER(pinnacle, CONFIG_SENSOR_LOG_LEVEL);
static int pinnacle_seq_read(const struct device *dev, const uint8_t start, uint8_t *buf, const uint8_t len) {
static int pinnacle_seq_read(const struct device *dev, const uint8_t addr, uint8_t *buf, const uint8_t len) {
const struct pinnacle_config *config = dev->config;
#if DT_INST_ON_BUS(0, spi)
uint8_t tx_buffer[len + 3], rx_dummy[3];
tx_buffer[0] = PINNACLE_READ | start;
tx_buffer[0] = PINNACLE_READ | addr;
memset(&tx_buffer[1], PINNACLE_AUTOINC, len + 1);
tx_buffer[len + 2] = PINNACLE_DUMMY;
@ -38,12 +39,15 @@ static int pinnacle_seq_read(const struct device *dev, const uint8_t start, uint
.buffers = rx_buf,
.count = 2,
};
const struct pinnacle_data *data = dev->data;
const struct pinnacle_config *config = dev->config;
return spi_transceive(data->spi, &config->spi_config, &tx, &rx);
return spi_transceive_dt(&config->bus, &tx, &rx);
#elif DT_INST_ON_BUS(0, i2c)
return i2c_burst_read_dt(&config->bus, PINNACLE_READ | addr, buf, len);
#endif
}
static int pinnacle_write(const struct device *dev, const uint8_t addr, const uint8_t val) {
const struct pinnacle_config *config = dev->config;
#if DT_INST_ON_BUS(0, spi)
uint8_t tx_buffer[2] = { PINNACLE_WRITE | addr, val };
uint8_t rx_buffer[2];
@ -65,9 +69,7 @@ static int pinnacle_write(const struct device *dev, const uint8_t addr, const ui
.buffers = rx_buf,
.count = 1,
};
const struct pinnacle_data *data = dev->data;
const struct pinnacle_config *config = dev->config;
const int ret = spi_transceive(data->spi, &config->spi_config, &tx, &rx);
const int ret = spi_transceive_dt(&config->bus, &tx, &rx);
if (rx_buffer[1] != 0xFB) {
LOG_ERR("bad ret val");
return -EIO;
@ -76,6 +78,9 @@ static int pinnacle_write(const struct device *dev, const uint8_t addr, const ui
LOG_ERR("spi ret: %d", ret);
}
return ret;
#elif DT_INST_ON_BUS(0, i2c)
return i2c_reg_write_byte_dt(&config->bus, PINNACLE_WRITE | addr, val);
#endif
}
static int pinnacle_channel_get(const struct device *dev, enum sensor_channel chan, struct sensor_value *val) {
@ -117,7 +122,7 @@ static int pinnacle_sample_fetch(const struct device *dev, enum sensor_channel c
#ifdef CONFIG_PINNACLE_TRIGGER
static void set_int(const struct device *dev, const bool en) {
const struct pinnacle_config *config = dev->config;
int ret = gpio_pin_interrupt_configure(config->dr_port, config->dr_pin, en ? GPIO_INT_LEVEL_ACTIVE : GPIO_INT_DISABLE);
int ret = gpio_pin_interrupt_configure_dt(&config->dr, en ? GPIO_INT_LEVEL_ACTIVE : GPIO_INT_DISABLE);
if (ret < 0) {
LOG_ERR("can't set interrupt");
}
@ -178,7 +183,6 @@ static void pinnacle_gpio_cb(const struct device *port, struct gpio_callback *cb
static int pinnacle_init(const struct device *dev) {
struct pinnacle_data *data = dev->data;
const struct pinnacle_config *config = dev->config;
data->spi = DEVICE_DT_GET(SPI_BUS);
pinnacle_write(dev, PINNACLE_STATUS1, 0); // Clear CC
pinnacle_write(dev, PINNACLE_Z_IDLE, 0); // No Z-Idle packets
@ -201,9 +205,9 @@ static int pinnacle_init(const struct device *dev) {
#ifdef CONFIG_PINNACLE_TRIGGER
data->dev = dev;
gpio_pin_configure(config->dr_port, config->dr_pin, GPIO_INPUT | config->dr_flags);
gpio_init_callback(&data->gpio_cb, pinnacle_gpio_cb, BIT(config->dr_pin));
int ret = gpio_add_callback(config->dr_port, &data->gpio_cb);
gpio_pin_configure_dt(&config->dr, GPIO_INPUT);
gpio_init_callback(&data->gpio_cb, pinnacle_gpio_cb, BIT(config->dr.pin));
int ret = gpio_add_callback(config->dr.port, &data->gpio_cb);
if (ret < 0) {
LOG_ERR("Failed to set DR callback: %d", ret);
return -EIO;
@ -220,6 +224,7 @@ static int pinnacle_init(const struct device *dev) {
#endif
pinnacle_write(dev, PINNACLE_FEED_CFG1, feed_cfg1);
#endif
LOG_WRN("inited");
return 0;
}
@ -234,26 +239,17 @@ static const struct sensor_driver_api pinnacle_driver_api = {
static struct pinnacle_data pinnacle_data;
static const struct pinnacle_config pinnacle_config = {
.spi_cs = {
.gpio_dev = DEVICE_DT_GET(DT_GPIO_CTLR_BY_IDX(SPI_BUS, cs_gpios, SPI_REG)),
.gpio_pin = DT_GPIO_PIN_BY_IDX(SPI_BUS, cs_gpios, SPI_REG),
.delay = 0,
.gpio_dt_flags = DT_GPIO_FLAGS_BY_IDX(SPI_BUS, cs_gpios, SPI_REG),
},
.spi_config = {
.cs = &pinnacle_config.spi_cs,
.frequency = DT_INST_PROP(0, spi_max_frequency),
.slave = DT_INST_REG_ADDR(0),
.operation = (SPI_OP_MODE_MASTER | SPI_WORD_SET(8) | SPI_LINES_SINGLE | SPI_TRANSFER_MSB),
},
#if DT_INST_ON_BUS(0, i2c)
.bus = I2C_DT_SPEC_INST_GET(0),
#elif DT_INST_ON_BUS(0, spi)
.bus = SPI_DT_SPEC_INST_GET(0, SPI_OP_MODE_MASTER | SPI_WORD_SET(8) | SPI_LINES_SINGLE | SPI_TRANSFER_MSB, 0),
#endif
.invert_x = DT_INST_PROP(0, invert_x),
.invert_y = DT_INST_PROP(0, invert_y),
.sleep_en = DT_INST_PROP(0, sleep),
.no_taps = DT_INST_PROP(0, no_taps),
#ifdef CONFIG_PINNACLE_TRIGGER
.dr_port = DEVICE_DT_GET(DT_GPIO_CTLR(DT_DRV_INST(0), dr_gpios)),
.dr_pin = DT_INST_GPIO_PIN(0, dr_gpios),
.dr_flags = DT_INST_GPIO_FLAGS(0, dr_gpios),
.dr = GPIO_DT_SPEC_GET(DT_DRV_INST(0), dr_gpios),
#endif
};

View file

@ -1,6 +1,8 @@
#pragma once
#include <device.h>
#include <drivers/spi.h>
#include <drivers/i2c.h>
#define PINNACLE_READ 0xA0
#define PINNACLE_WRITE 0x80
@ -50,7 +52,6 @@
#define PINNACLE_PACKET0_Y_SIGN BIT(5) // Y delta sign
struct pinnacle_data {
const struct device *spi;
int16_t dx, dy;
int8_t wheel;
uint8_t btn;
@ -70,11 +71,13 @@ struct pinnacle_data {
};
struct pinnacle_config {
struct spi_cs_control spi_cs;
struct spi_config spi_config;
#if DT_INST_ON_BUS(0, i2c)
const struct i2c_dt_spec bus;
#elif DT_INST_ON_BUS(0, spi)
const struct spi_dt_spec bus;
#endif
bool invert_x, invert_y, sleep_en, no_taps;
#ifdef CONFIG_PINNACLE_TRIGGER
const struct device *dr_port;
uint8_t dr_pin, dr_flags;
const struct gpio_dt_spec dr;
#endif
};

View file

@ -0,0 +1,12 @@
properties:
dr-gpios:
type: phandle-array
description: Data ready pin for the trackpad
invert-x:
type: boolean
invert-y:
type: boolean
sleep:
type: boolean
no-taps:
type: boolean

View file

@ -0,0 +1,6 @@
description: |
Sensor driver for the Cirque Pinnacle trackpad ASICs, using the I2C interface
compatible: "cirque,pinnacle"
include: ["i2c-device.yaml", "cirque,pinnacle-common.yaml"]

View file

@ -0,0 +1,6 @@
description: |
Sensor driver for the Cirque Pinnacle trackpad ASICs, using the SPI interface
compatible: "cirque,pinnacle"
include: ["spi-device.yaml", "cirque,pinnacle-common.yaml"]

View file

@ -1,27 +0,0 @@
description: |
Sensor driver for the Cirque Pinnacle trackpad ASICs
compatible: "cirque,pinnacle"
include: spi-device.yaml
on-bus: spi
properties:
spi-max-frequency:
type: int
required: true
description: |
Maximum SPI clock speed supported by the device, in Hz.
dr-gpios:
type: phandle-array
required: true
description: Data ready pin for the trackpad
invert-x:
type: boolean
invert-y:
type: boolean
sleep:
type: boolean
no-taps:
type: boolean