Add driver to read out SOM id pins (#60)

* add driver to read out som id pins

* fix mistake
This commit is contained in:
Robbe Derks
2024-01-23 16:59:52 +01:00
committed by GitHub
parent b9a7dcefc1
commit 758223fbf5
6 changed files with 142 additions and 0 deletions

View File

@@ -111,6 +111,14 @@
};
&vendor {
gpio-som-id {
status="okay";
compatible = "comma,gpio-som-id";
gpios = <&tlmm 105 0>, <&tlmm 106 0>, <&tlmm 107 0>, <&tlmm 108 0>;
pinctrl-names = "default";
pinctrl-0 = <&som_id_default>;
};
bluetooth: bt_wcn3990 {
compatible = "qca,wcn3990";
qca,bt-vdd-io-supply = <&pm8998_s3>;

View File

@@ -21,6 +21,19 @@
#interrupt-cells = <2>;
interrupt-parent = <&pdc>;
som_id_default: som_id_default {
mux {
pins = "gpio105", "gpio106", "gpio107", "gpio108";
function = "gpio";
};
config {
pins = "gpio105", "gpio106", "gpio107", "gpio108";
bias-pull-up;
drive-strength = <10>;
};
};
ufs_dev_reset_assert: ufs_dev_reset_assert {
config {
pins = "ufs_reset";

View File

@@ -4304,6 +4304,7 @@ CONFIG_MSM_EXT_DISPLAY=y
CONFIG_CLKDEV_LOOKUP=y
CONFIG_HAVE_CLK_PREPARE=y
CONFIG_COMMON_CLK=y
CONFIG_GPIO_SOM_ID=y
#
# Common Clock Framework

View File

@@ -234,4 +234,12 @@ config MSM_RMNET_BAM
for routing IP packets within the MSM using
BAM as a physical transport.
config GPIO_SOM_ID
bool "Simple GPIO-based ID driver"
help
This driver uses the internal pull-ups of the provided GPIOs to
detect the SOM ID. The SOM ID is a 4-bit value that is set by
tying the GPIOs to either ground or VDD. The SOM ID can then
be read in userspace by sysfs.
endmenu

View File

@@ -16,3 +16,4 @@ obj-$(CONFIG_MSM_11AD) += msm_11ad/
obj-$(CONFIG_SEEMP_CORE) += seemp_core/
obj-$(CONFIG_QCOM_GENI_SE) += qcom-geni-se.o
obj-$(CONFIG_MSM_EXT_DISPLAY) += msm_ext_display.o
obj-$(CONFIG_GPIO_SOM_ID) += gpio_som_id.o

View File

@@ -0,0 +1,111 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/of_platform.h>
#include <linux/gpio/consumer.h>
#include <linux/sysfs.h>
struct gpio_som_id {
struct platform_device *pdev;
struct pinctrl *pinctrl;
struct gpio_desc *gpio[4];
};
static ssize_t som_id_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct gpio_som_id *som_id = dev_get_drvdata(dev);
int i, id = 0;
if (!som_id)
goto error;
for (i=0; i<sizeof(som_id->gpio)/sizeof(som_id->gpio[0]); i++) {
id |= gpiod_get_value(som_id->gpio[i]) << i;
}
return sprintf(buf, "%d\n", id);
error:
return -EINVAL;
}
static DEVICE_ATTR_RO(som_id);
static struct attribute *som_id_attrs[] = {
&dev_attr_som_id.attr,
NULL
};
static struct attribute_group som_id_attr_group = {
.attrs = som_id_attrs,
};
static int gpio_som_id_probe(struct platform_device *pdev)
{
struct gpio_som_id *som_id;
int i, rc = 0;
som_id = devm_kzalloc(&pdev->dev, sizeof(*som_id), GFP_KERNEL);
if (!som_id)
return -ENOMEM;
som_id->pdev = pdev;
// you need to set a pinctrl for the GPIOs to have pull-ups
som_id->pinctrl = devm_pinctrl_get(&pdev->dev);
if (IS_ERR(som_id->pinctrl)) {
dev_err(&pdev->dev, "Failed to get pinctrl: %ld\n", PTR_ERR(som_id->pinctrl));
rc = PTR_ERR(som_id->pinctrl);
goto error;
}
// get the GPIOs
for (i=0; i<sizeof(som_id->gpio)/sizeof(som_id->gpio[0]); i++) {
som_id->gpio[i] = devm_gpiod_get_index(&pdev->dev, NULL, i, GPIOD_IN);
if (IS_ERR(som_id->gpio[i])) {
dev_err(&pdev->dev, "Failed to get GPIO: %ld\n", PTR_ERR(som_id->gpio[i]));
rc = PTR_ERR(som_id->gpio[i]);
goto error;
}
}
// make a sysfs entry for the SOM ID
rc = sysfs_create_group(&pdev->dev.kobj, &som_id_attr_group);
if (rc) {
dev_err(&pdev->dev, "Failed to create sysfs entry: %d\n", rc);
goto error;
}
platform_set_drvdata(pdev, som_id);
error:
return rc;
}
static int gpio_som_id_remove(struct platform_device *pdev)
{
struct gpio_som_id *som_id = dev_get_drvdata(&pdev->dev);
sysfs_remove_group(&pdev->dev.kobj, &som_id_attr_group);
return 0;
}
static const struct of_device_id of_match_table[] = {
{ .compatible = "comma,gpio-som-id", },
{}
};
static struct platform_driver gpio_som_id_driver = {
.driver = {
.name = "comma,gpio-som-id",
.of_match_table = of_match_table,
},
.probe = gpio_som_id_probe,
.remove = gpio_som_id_remove,
};
module_driver(gpio_som_id_driver, platform_driver_register, platform_driver_unregister);
MODULE_DESCRIPTION("GPIO SOM ID driver");
MODULE_LICENSE("MIT");