Compare commits

...

4 commits

Author SHA1 Message Date
Denis
1c885459bb
comment a thing 2023-09-10 16:58:50 +02:00
Denis
51baa87931
print more debug! 2023-09-10 16:55:06 +02:00
Denis
0adb30c4e3
still debugging.... 2023-09-10 16:43:06 +02:00
Denis
12bbdac5a5
debugging... 2023-09-10 16:42:18 +02:00
4 changed files with 1087 additions and 15 deletions

File diff suppressed because it is too large Load diff

View file

@ -173,15 +173,69 @@ static void bmc150_acpi_dual_accel_remove(struct i2c_client *client) {}
static int bmc150_accel_probe(struct i2c_client *client)
{
int ret;
u8 chip_id_first[4];
enum bmc150_device_type dev_type = BMC150;
const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct regmap *regmap;
const char *name = NULL;
enum bmc150_type type = BOSCH_UNKNOWN;
bool block_supported =
bool block_supported = false;
ret = i2c_smbus_read_i2c_block_data(client, 0x00, 4, &chip_id_first[0]);
if (ret != 4) {
dev_err(&client->dev, "error in i2c_smbus_read_i2c_block_data = %d: reg = 0x%02x", (int)ret, 0x00);
goto bmi150_old_probe;
}
if (chip_id_first[2] != 0x43) {
dev_err(&client->dev, "chip is not a bmi323.");
} else {
dev_err(&client->dev, "chip is a bmi323!");
dev_type = BMI323;
}
if (dev_type == BMI323) {
/*dev_warn*/ dev_err(&client->dev, "bmc323: the bmc150 is for sure a bmc323...\n");
struct iio_dev *indio_dev = devm_iio_device_alloc(&client->dev, sizeof(struct bmc150_accel_data));
if (!indio_dev) {
dev_err(&client->dev, "bmc323: out of memory\n");
return -ENOMEM;
}
dev_set_drvdata(&client->dev, indio_dev);
struct bmc150_accel_data *data = iio_priv(indio_dev);
struct bmi323_private_data* bmi323_data = &data->bmi323;
bmi323_data->i2c_client = client;
bmi323_data->spi_client = NULL;
bmi323_data->irq = client->irq;
ret = bmi323_chip_rst(bmi323_data);
if (ret != 0) {
dev_err(&client->dev, "bmc323: error issuing the chip reset: %d\n", ret);
return ret;
}
/*dev_info*/ dev_err(&client->dev, "bmc323: chip rst success\n");
ret = bmi323_iio_init(indio_dev);
if (ret != 0) {
return ret;
}
return 0;
}
bmi150_old_probe:
dev_err(&client->dev, "executing the normal procedure for a bmc150...");
block_supported =
i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ||
i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_READ_I2C_BLOCK);
int ret;
regmap = devm_regmap_init_i2c(client, &bmc150_regmap_conf);
if (IS_ERR(regmap)) {
@ -196,8 +250,9 @@ static int bmc150_accel_probe(struct i2c_client *client)
ret = bmc150_accel_core_probe(&client->dev, regmap, client->irq,
type, name, block_supported);
if (ret)
if (ret) {
return ret;
}
/*
* The !id check avoids recursion when probe() gets called
@ -211,6 +266,24 @@ static int bmc150_accel_probe(struct i2c_client *client)
static void bmc150_accel_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = dev_get_drvdata(&client->dev);
struct bmc150_accel_data *data = iio_priv(indio_dev);
if (data->dev_type == BMI323) {
/*dev_info*/ dev_err(&client->dev, "bmc323 removing driver...\n");
iio_device_unregister(indio_dev);
/*dev_info*/ dev_err(&client->dev, "bmc323 deallocating driver storage...\n");
iio_device_free(indio_dev);
/*dev_info*/ dev_err(&client->dev, "bmc323 removal done.\n");
// TODO: create and call functions for bmi323
return;
}
bmc150_acpi_dual_accel_remove(client);
bmc150_accel_core_remove(&client->dev);

View file

@ -8,6 +8,9 @@
#include <linux/regulator/consumer.h>
#include <linux/workqueue.h>
#include <linux/i2c.h>
#include <linux/spi/spi.h>
struct regmap;
struct i2c_client;
struct bmc150_accel_chip_info;
@ -34,6 +37,11 @@ struct bmc150_accel_interrupt {
atomic_t users;
};
enum bmc150_device_type {
BMC150,
BMI323,
};
struct bmc150_accel_trigger {
struct bmc150_accel_data *data;
struct iio_trigger *indio_trig;
@ -55,6 +63,17 @@ enum bmc150_accel_trigger_id {
BMC150_ACCEL_TRIGGERS,
};
#define BMI323_FLAGS_RESET_FAILED 0x00000001U
struct bmi323_private_data {
struct i2c_client* i2c_client;
struct spi_device* spi_client;
struct device* dev; // pointer at i2c_client->dev or spi_client->dev
struct mutex mutex;
int irq;
uint32_t flags;
};
struct bmc150_accel_data {
struct regmap *regmap;
struct regulator_bulk_data regulators[2];
@ -83,7 +102,29 @@ struct bmc150_accel_data {
void (*resume_callback)(struct device *dev);
struct delayed_work resume_work;
struct iio_mount_matrix orientation;
};
enum bmc150_device_type dev_type;
struct bmi323_private_data bmi323;
};
#define BCM150_BMI323_SOFT_RESET_REG 0x7E
#define BCM150_BMI323_SOFT_RESET_VAL 0xDEAF
int bmc323_write_u16(struct bmi323_private_data *bmi323, u8 in_reg, u16 in_value);
int bmc323_read_s16(struct bmi323_private_data *bmi323, u8 in_reg, s16* out_value);
int bmc323_read_u16(struct bmi323_private_data *bmi323, u8 in_reg, u16* out_value);
int bmi323_chip_check(struct bmi323_private_data *bmi323);
int bmi323_chip_rst(struct bmi323_private_data *bmi323);
/**
* This function MUST be called in probe and is responsible for registering the userspace sysfs.
*
* The indio_dev MUST have been allocated but not registered. This function will perform userspace registration.
*
* @param indio_dev the industrual io device already allocated but not yet registered
*/
int bmi323_iio_init(struct iio_dev *indio_dev);
int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
enum bmc150_type type, const char *name,

View file

@ -1500,17 +1500,26 @@ static DEVICE_ATTR_RW(current_timestamp_clock);
static int iio_device_register_sysfs(struct iio_dev *indio_dev)
{
dev_err(NULL, " begin to_iio_dev_opaque");
struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);
int i, ret = 0, attrcount, attrn, attrcount_orig = 0;
struct iio_dev_attr *p;
struct attribute **attr, *clk = NULL;
dev_err(NULL, " end to_iio_dev_opaque");
/* First count elements in any existing group */
dev_err(NULL, " begin if (indio_dev->info->attrs)");
if (indio_dev->info->attrs) {
dev_err(NULL, " begin attr = indio_dev->info->attrs->attrs");
attr = indio_dev->info->attrs->attrs;
dev_err(NULL, " end attr = indio_dev->info->attrs->attrs");
dev_err(NULL, " begin while (*attr++ != NULL)");
while (*attr++ != NULL)
attrcount_orig++;
dev_err(NULL, " end while (*attr++ != NULL)");
}
dev_err(NULL, " begin end (indio_dev->info->attrs)");
attrcount = attrcount_orig;
/*
* New channel registration method - relies on the fact a group does
@ -1524,7 +1533,9 @@ static int iio_device_register_sysfs(struct iio_dev *indio_dev)
if (chan->type == IIO_TIMESTAMP)
clk = &dev_attr_current_timestamp_clock.attr;
dev_err(NULL, " begin iio_device_add_channel_sysfs #%d/%d", i, (int)indio_dev->num_channels);
ret = iio_device_add_channel_sysfs(indio_dev, chan);
dev_err(NULL, " end iio_device_add_channel_sysfs #%d/%d", i, (int)indio_dev->num_channels);
if (ret < 0)
goto error_clear_attrs;
attrcount += ret;
@ -1540,20 +1551,24 @@ static int iio_device_register_sysfs(struct iio_dev *indio_dev)
if (clk)
attrcount++;
dev_err(NULL, " begin kcalloc");
iio_dev_opaque->chan_attr_group.attrs =
kcalloc(attrcount + 1,
sizeof(iio_dev_opaque->chan_attr_group.attrs[0]),
GFP_KERNEL);
dev_err(NULL, " end kcalloc");
if (iio_dev_opaque->chan_attr_group.attrs == NULL) {
ret = -ENOMEM;
goto error_clear_attrs;
}
/* Copy across original attributes, and point to original binary attributes */
if (indio_dev->info->attrs) {
dev_err(NULL, " begin memcpy");
memcpy(iio_dev_opaque->chan_attr_group.attrs,
indio_dev->info->attrs->attrs,
sizeof(iio_dev_opaque->chan_attr_group.attrs[0])
*attrcount_orig);
dev_err(NULL, " end memcpy");
iio_dev_opaque->chan_attr_group.is_visible =
indio_dev->info->attrs->is_visible;
iio_dev_opaque->chan_attr_group.bin_attrs =
@ -1561,8 +1576,10 @@ static int iio_device_register_sysfs(struct iio_dev *indio_dev)
}
attrn = attrcount_orig;
/* Add all elements from the list. */
dev_err(NULL, " begin list_for_each_entry");
list_for_each_entry(p, &iio_dev_opaque->channel_attr_list, l)
iio_dev_opaque->chan_attr_group.attrs[attrn++] = &p->dev_attr.attr;
dev_err(NULL, " end list_for_each_entry");
if (indio_dev->name)
iio_dev_opaque->chan_attr_group.attrs[attrn++] = &dev_attr_name.attr;
if (indio_dev->label)
@ -1570,15 +1587,19 @@ static int iio_device_register_sysfs(struct iio_dev *indio_dev)
if (clk)
iio_dev_opaque->chan_attr_group.attrs[attrn++] = clk;
dev_err(NULL, " begin iio_device_register_sysfs_group");
ret = iio_device_register_sysfs_group(indio_dev,
&iio_dev_opaque->chan_attr_group);
dev_err(NULL, " end iio_device_register_sysfs_group");
if (ret)
goto error_clear_attrs;
return 0;
error_clear_attrs:
dev_err(NULL, " ERROR HERE: begin iio_free_chan_devattr_list");
iio_free_chan_devattr_list(&iio_dev_opaque->channel_attr_list);
dev_err(NULL, " ERROR HERE: end iio_free_chan_devattr_list");
return ret;
}
@ -1856,8 +1877,8 @@ static int iio_check_unique_scan_index(struct iio_dev *indio_dev)
for (j = i + 1; j < indio_dev->num_channels; j++)
if (channels[i].scan_index == channels[j].scan_index) {
dev_err(&indio_dev->dev,
"Duplicate scan index %d\n",
channels[i].scan_index);
"Duplicate scan index %d at elements (%d, %d)\n",
channels[i].scan_index, i , j);
return -EINVAL;
}
}
@ -1887,6 +1908,7 @@ static const struct iio_buffer_setup_ops noop_ring_setup_ops;
int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod)
{
dev_err(NULL, "begin __iio_device_register\n");
struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);
struct fwnode_handle *fwnode = NULL;
int ret;
@ -1894,6 +1916,8 @@ int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod)
if (!indio_dev->info)
return -EINVAL;
dev_err(NULL, " indio_dev->info is NOT NULL\n");
iio_dev_opaque->driver_module = this_mod;
/* If the calling driver did not initialize firmware node, do it here */
@ -1902,60 +1926,95 @@ int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod)
/* The default dummy IIO device has no parent */
else if (indio_dev->dev.parent)
fwnode = dev_fwnode(indio_dev->dev.parent);
dev_err(NULL, " begin device_set_node\n");
device_set_node(&indio_dev->dev, fwnode);
dev_err(NULL, " end device_set_node\n");
dev_err(NULL, " begin fwnode_property_read_string\n");
fwnode_property_read_string(fwnode, "label", &indio_dev->label);
dev_err(NULL, " end fwnode_property_read_string\n");
dev_err(NULL, " begin iio_check_unique_scan_index\n");
ret = iio_check_unique_scan_index(indio_dev);
dev_err(NULL, " end iio_check_unique_scan_index\n");
if (ret < 0)
return ret;
dev_err(NULL, " begin iio_check_extended_name\n");
ret = iio_check_extended_name(indio_dev);
dev_err(NULL, " end iio_check_extended_name\n");
if (ret < 0)
return ret;
dev_err(NULL, " begin iio_device_register_debugfs\n");
iio_device_register_debugfs(indio_dev);
dev_err(NULL, " end iio_device_register_debugfs\n");
dev_err(NULL, " begin iio_buffers_alloc_sysfs_and_mask\n");
ret = iio_buffers_alloc_sysfs_and_mask(indio_dev);
dev_err(NULL, " end iio_buffers_alloc_sysfs_and_mask\n");
if (ret) {
dev_err(indio_dev->dev.parent,
"Failed to create buffer sysfs interfaces\n");
goto error_unreg_debugfs;
}
dev_err(NULL, " begin iio_device_register_sysfs\n");
ret = iio_device_register_sysfs(indio_dev);
dev_err(NULL, " end iio_device_register_sysfs\n");
if (ret) {
dev_err(indio_dev->dev.parent,
"Failed to register sysfs interfaces\n");
goto error_buffer_free_sysfs;
}
dev_err(NULL, " begin iio_device_register_eventset\n");
ret = iio_device_register_eventset(indio_dev);
dev_err(NULL, " end iio_device_register_eventset\n");
if (ret) {
dev_err(indio_dev->dev.parent,
"Failed to register event set\n");
goto error_free_sysfs;
}
if (indio_dev->modes & INDIO_ALL_TRIGGERED_MODES)
if (indio_dev->modes & INDIO_ALL_TRIGGERED_MODES) {
dev_err(NULL, " begin iio_device_register_trigger_consumer\n");
iio_device_register_trigger_consumer(indio_dev);
dev_err(NULL, " end iio_device_register_trigger_consumer\n");
} else {
dev_err(NULL, " no iio_device_register_trigger_consumer performed\n");
}
if ((indio_dev->modes & INDIO_ALL_BUFFER_MODES) &&
indio_dev->setup_ops == NULL)
indio_dev->setup_ops = &noop_ring_setup_ops;
if (iio_dev_opaque->attached_buffers_cnt)
if (iio_dev_opaque->attached_buffers_cnt) {
dev_err(NULL, " begin cdev_init 1\n");
cdev_init(&iio_dev_opaque->chrdev, &iio_buffer_fileops);
else if (iio_dev_opaque->event_interface)
dev_err(NULL, " end cdev_init 1\n");
}
else if (iio_dev_opaque->event_interface) {
dev_err(NULL, " begin cdev_init 2\n");
cdev_init(&iio_dev_opaque->chrdev, &iio_event_fileops);
dev_err(NULL, " end cdev_init 1\n");
} else {
dev_err(NULL, " no cdev_init\n");
}
if (iio_dev_opaque->attached_buffers_cnt || iio_dev_opaque->event_interface) {
dev_err(NULL, " begin MKDEV\n");
indio_dev->dev.devt = MKDEV(MAJOR(iio_devt), iio_dev_opaque->id);
iio_dev_opaque->chrdev.owner = this_mod;
dev_err(NULL, " end MKDEV\n");
}
/* assign device groups now; they should be all registered now */
indio_dev->dev.groups = iio_dev_opaque->groups;
dev_err(NULL, " begin cdev_device_add\n");
ret = cdev_device_add(&iio_dev_opaque->chrdev, &indio_dev->dev);
dev_err(NULL, " end cdev_device_add\n");
if (ret < 0)
goto error_unreg_eventset;