summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsharma-mts <86847754+sharma-mts@users.noreply.github.com>2022-02-04 19:41:20 -0600
committerJohn Klug <john.klug@multitech.com>2022-02-18 17:12:58 -0600
commitbf34d5b36031aa6a8f1720205ff3a4de6b5865a5 (patch)
treed59844ae69593be4ce2fd732e073fff1f6f48b1c
parentf4370ecf1bdb4271d589c5dea58c16de6c74dd4f (diff)
downloadmtac-bf34d5b36031aa6a8f1720205ff3a4de6b5865a5.tar.gz
mtac-bf34d5b36031aa6a8f1720205ff3a4de6b5865a5.tar.bz2
mtac-bf34d5b36031aa6a8f1720205ff3a4de6b5865a5.zip
Convert mtac driver to use gpio descriptors
-rw-r--r--mtac.c467
1 files changed, 247 insertions, 220 deletions
diff --git a/mtac.c b/mtac.c
index 22af08f..749868e 100644
--- a/mtac.c
+++ b/mtac.c
@@ -6,6 +6,7 @@
#include <linux/types.h>
#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/firmware.h>
#include <linux/kmod.h>
@@ -19,8 +20,8 @@
/* accessory card EEPROMs, read outside of driver */
uint8_t mts_ap_eeprom[NUM_AP][MTS_AP_EEPROM_SIZE];
EXPORT_SYMBOL(mts_ap_eeprom);
-
-static const char* eeprom_file_name[NUM_AP] = {
+
+static const char* eeprom_file_name[NUM_AP] = {
#if NUM_AP > 0
#ifdef mtcdt
"1-0050/eeprom", "1-0052/eeprom"
@@ -45,19 +46,23 @@ void mtac_clear_port_pins(int port_index)
char buf[32];
struct gpio_pin *pin;
struct gpio_pin *pins;
-
+
snprintf(buf,sizeof buf,"AP%d_",port_index+1);
-
+
/* Find all the GPIO pins for this port and
* free them all.
*/
log_debug("mtac_clear_port_pins: State of mtac mutex is %s",
- mutex_is_locked(&mtac_mutex) ? "locked" : "unlocked");
+ mutex_is_locked(&mtac_mutex) ? "locked" : "unlocked");
mutex_lock(&mtac_mutex);
pins = mtac_port_info[port_index]->gpio_pins;
for (pin = pins; *pin->name; pin++) {
if (!memcmp(pin->name,buf,strlen(buf))) {
- gpio_free(pin->pin.gpio);
+ if (pin->do_gpio_desc) {
+ gpiod_put(pin->desc);
+ } else {
+ gpio_free(pin->pin.gpio);
+ }
}
}
mtac_port_info[port_index]->gpio_pins = NULL;
@@ -76,48 +81,48 @@ void mtac_set_port_pins(int port_index, struct gpio_pin *pins, struct kobject *s
EXPORT_SYMBOL(mtac_set_port_pins);
struct kobj_attribute* mtac_create_attribute(const char* _name, umode_t _mode) {
- char* attr_name;
- struct kobj_attribute* _attr;
-
- _attr = kzalloc(sizeof(struct kobj_attribute), GFP_KERNEL);
- if (! _attr) {
- log_error("kzalloc of attribute [%s] failed", _name);
- return NULL;
- }
- sysfs_attr_init(_attr);
- attr_name = kstrdup(_name, GFP_KERNEL);
- if (! attr_name) {
- log_error("GFP_KERNEL dup failed for attribute [%s]", _name);
- return NULL;
- }
- _attr->attr.name = attr_name;
- _attr->attr.mode = _mode;
-
- return _attr;
+ char* attr_name;
+ struct kobj_attribute* _attr;
+
+ _attr = kzalloc(sizeof(struct kobj_attribute), GFP_KERNEL);
+ if (! _attr) {
+ log_error("kzalloc of attribute [%s] failed", _name);
+ return NULL;
+ }
+ sysfs_attr_init(_attr);
+ attr_name = kstrdup(_name, GFP_KERNEL);
+ if (! attr_name) {
+ log_error("GFP_KERNEL dup failed for attribute [%s]", _name);
+ return NULL;
+ }
+ _attr->attr.name = attr_name;
+ _attr->attr.mode = _mode;
+
+ return _attr;
}
EXPORT_SYMBOL(mtac_create_attribute);
int mtac_port_from_kobject(struct kobject *kobj) {
- int port;
- const char *name;
-
- name = kobj->name;
- if (! name) {
- log_error("kobject->name is NULL");
- return -1;
- }
-
- if (sscanf(name, "ap%d", &port) < 1) {
- log_error("failed to scan port from kobject->name [%s]", name);
- return -1;
- }
-
- if (port < 1 || port > NUM_AP) {
- log_error("port number %d is invalid", port);
- return -1;
- }
-
- return port;
+ int port;
+ const char *name;
+
+ name = kobj->name;
+ if (! name) {
+ log_error("kobject->name is NULL");
+ return -1;
+ }
+
+ if (sscanf(name, "ap%d", &port) < 1) {
+ log_error("failed to scan port from kobject->name [%s]", name);
+ return -1;
+ }
+
+ if (port < 1 || port > NUM_AP) {
+ log_error("port number %d is invalid", port);
+ return -1;
+ }
+
+ return port;
}
EXPORT_SYMBOL(mtac_port_from_kobject);
@@ -126,76 +131,76 @@ EXPORT_SYMBOL(mtac_port_from_kobject);
* This function is not normally used directly by mtac modules.
*/
ssize_t mtac_show_product_info(struct kobject *kobj, struct kobj_attribute *attr, char *buf) {
- ssize_t value;
- int port;
- int port_index;
- struct mts_ap_eeprom_layout *app;
-
- port = mtac_port_from_kobject(kobj);
- if (port < 1) {
- log_error("mtac_port_from_kobject returned %d", port);
- return -1;
- }
- port_index = port - 1;
-
- app = (struct mts_ap_eeprom_layout *)mts_ap_eeprom[port_index];
- if (! strcmp(attr->attr.name, "vendor-id")) {
- value = snprintf(buf, 32, "%s\n", app->vendor_id);
- } else if (! strcmp(attr->attr.name, "product-id")) {
- value = snprintf(buf, 32, "%s\n", app->product_id);
- } else if (! strcmp(attr->attr.name, "device-id")) {
- value = snprintf(buf, 32, "%s\n", app->device_id);
- } else if (! strcmp(attr->attr.name, "hw-version")) {
- value = snprintf(buf, 32, "%s\n", app->hw_version);
- } else {
- log_error("attribute [%s] not found", attr->attr.name);
- value = -1;
- }
- return value;
+ ssize_t value;
+ int port;
+ int port_index;
+ struct mts_ap_eeprom_layout *app;
+
+ port = mtac_port_from_kobject(kobj);
+ if (port < 1) {
+ log_error("mtac_port_from_kobject returned %d", port);
+ return -1;
+ }
+ port_index = port - 1;
+
+ app = (struct mts_ap_eeprom_layout *)mts_ap_eeprom[port_index];
+ if (! strcmp(attr->attr.name, "vendor-id")) {
+ value = snprintf(buf, 32, "%s\n", app->vendor_id);
+ } else if (! strcmp(attr->attr.name, "product-id")) {
+ value = snprintf(buf, 32, "%s\n", app->product_id);
+ } else if (! strcmp(attr->attr.name, "device-id")) {
+ value = snprintf(buf, 32, "%s\n", app->device_id);
+ } else if (! strcmp(attr->attr.name, "hw-version")) {
+ value = snprintf(buf, 32, "%s\n", app->hw_version);
+ } else {
+ log_error("attribute [%s] not found", attr->attr.name);
+ value = -1;
+ }
+ return value;
}
EXPORT_SYMBOL(mtac_show_product_info);
bool mtac_add_product_info_attributes(int port, struct attribute** attrs, int* index) {
- char buf[32];
- struct kobj_attribute* kobj_attr;
-
- sprintf(buf, "vendor-id");
- kobj_attr = mtac_create_attribute(buf, MTS_ATTR_MODE_RO);
- if (! kobj_attr) {
- log_error("failed to create attribute [%s] in port %d", buf, port);
- return false;
- }
- kobj_attr->show = mtac_show_product_info;
- attrs[(*index)++] = &kobj_attr->attr;
-
- sprintf(buf, "product-id");
- kobj_attr = mtac_create_attribute(buf, MTS_ATTR_MODE_RO);
- if (! kobj_attr) {
- log_error("failed to create attribute [%s] in port %d", buf, port);
- return false;
- }
- kobj_attr->show = mtac_show_product_info;
- attrs[(*index)++] = &kobj_attr->attr;
-
- sprintf(buf, "device-id");
- kobj_attr = mtac_create_attribute(buf, MTS_ATTR_MODE_RO);
- if (! kobj_attr) {
- log_error("failed to create attribute [%s] in port %d", buf, port);
- return false;
- }
- kobj_attr->show = mtac_show_product_info;
- attrs[(*index)++] = &kobj_attr->attr;
-
- sprintf(buf, "hw-version");
- kobj_attr = mtac_create_attribute(buf, MTS_ATTR_MODE_RO);
- if (! kobj_attr) {
- log_error("failed to create attribute [%s] in port %d", buf, port);
- return false;
- }
- kobj_attr->show = mtac_show_product_info;
- attrs[(*index)++] = &kobj_attr->attr;
-
- return true;
+ char buf[32];
+ struct kobj_attribute* kobj_attr;
+
+ sprintf(buf, "vendor-id");
+ kobj_attr = mtac_create_attribute(buf, MTS_ATTR_MODE_RO);
+ if (! kobj_attr) {
+ log_error("failed to create attribute [%s] in port %d", buf, port);
+ return false;
+ }
+ kobj_attr->show = mtac_show_product_info;
+ attrs[(*index)++] = &kobj_attr->attr;
+
+ sprintf(buf, "product-id");
+ kobj_attr = mtac_create_attribute(buf, MTS_ATTR_MODE_RO);
+ if (! kobj_attr) {
+ log_error("failed to create attribute [%s] in port %d", buf, port);
+ return false;
+ }
+ kobj_attr->show = mtac_show_product_info;
+ attrs[(*index)++] = &kobj_attr->attr;
+
+ sprintf(buf, "device-id");
+ kobj_attr = mtac_create_attribute(buf, MTS_ATTR_MODE_RO);
+ if (! kobj_attr) {
+ log_error("failed to create attribute [%s] in port %d", buf, port);
+ return false;
+ }
+ kobj_attr->show = mtac_show_product_info;
+ attrs[(*index)++] = &kobj_attr->attr;
+
+ sprintf(buf, "hw-version");
+ kobj_attr = mtac_create_attribute(buf, MTS_ATTR_MODE_RO);
+ if (! kobj_attr) {
+ log_error("failed to create attribute [%s] in port %d", buf, port);
+ return false;
+ }
+ kobj_attr->show = mtac_show_product_info;
+ attrs[(*index)++] = &kobj_attr->attr;
+
+ return true;
}
EXPORT_SYMBOL(mtac_add_product_info_attributes);
@@ -204,27 +209,27 @@ EXPORT_SYMBOL(mtac_add_product_info_attributes);
* This function is not normally used directly by mtac modules.
*/
struct gpio_pin *mtac_gpio_pin_by_attr_name(const char *name, int port) {
- struct gpio_pin *pin;
- char *pin_attr_name;
- int port_index = port - 1;
- struct gpio_pin *port_gpio_pins;
-
- log_debug("mtac_gpio_pin_by_attr_name: State of mtac mutex is %s",
- mutex_is_locked(&mtac_mutex) ? "locked" : "unlocked");
- mutex_lock(&mtac_mutex);
- pin_attr_name = mtac_port_info[port_index]->gpio_pin_name_by_attr_name(name, port);
- port_gpio_pins = mtac_port_info[port_index]->gpio_pins;
-
- for (pin = port_gpio_pins; *pin->name; pin++) {
- if (!strcmp(pin->pin.label, pin_attr_name)) {
- mutex_unlock(&mtac_mutex);
- return pin;
- }
- }
- mutex_unlock(&mtac_mutex);
-
- log_error("pin with attr name [%s] not found", name);
- return NULL;
+ struct gpio_pin *pin;
+ char *pin_attr_name;
+ int port_index = port - 1;
+ struct gpio_pin *port_gpio_pins;
+
+ log_debug("mtac_gpio_pin_by_attr_name: State of mtac mutex is %s",
+ mutex_is_locked(&mtac_mutex) ? "locked" : "unlocked");
+ mutex_lock(&mtac_mutex);
+ pin_attr_name = mtac_port_info[port_index]->gpio_pin_name_by_attr_name(name, port);
+ port_gpio_pins = mtac_port_info[port_index]->gpio_pins;
+
+ for (pin = port_gpio_pins; *pin->name; pin++) {
+ if (!strcmp(pin->pin.label, pin_attr_name)) {
+ mutex_unlock(&mtac_mutex);
+ return pin;
+ }
+ }
+ mutex_unlock(&mtac_mutex);
+
+ log_error("pin with attr name [%s] not found", name);
+ return NULL;
}
EXPORT_SYMBOL(mtac_gpio_pin_by_attr_name);
@@ -235,32 +240,36 @@ ssize_t mtac_attr_show_ap_gpio_pin(struct kobject *kobj,
int value;
int port;
struct gpio_pin *pin;
-
+
port = mtac_port_from_kobject(kobj);
if (port < 1) {
- log_error("mtac_port_from_kobject returned %d", port);
- return -EINVAL;
+ log_error("mtac_port_from_kobject returned %d", port);
+ return -EINVAL;
}
pin = mtac_gpio_pin_by_attr_name(attr->attr.name, port);
if (!pin) {
- return -ENODEV;
+ return -ENODEV;
}
log_debug("mtac_attr_show_ap_gpio_pin: State of mtac mutex is %s",
- mutex_is_locked(&mtac_mutex) ? "locked" : "unlocked");
+ mutex_is_locked(&mtac_mutex) ? "locked" : "unlocked");
mutex_lock(&mtac_mutex);
- value = gpio_get_value(pin->pin.gpio);
+ if (pin->do_gpio_desc) {
+ value = gpiod_get_value(pin->desc);
+ } else {
+ value = gpio_get_value(pin->pin.gpio);
+ }
mutex_unlock(&mtac_mutex);
if (value < 0) {
- return value;
+ return value;
}
if (pin->active_low) {
- value = !value;
+ value = !value;
}
return sprintf(buf, "%d\n", value);
@@ -271,45 +280,48 @@ EXPORT_SYMBOL(mtac_attr_show_ap_gpio_pin);
ssize_t mtac_attr_store_ap_gpio_pin(struct kobject *kobj,
struct kobj_attribute *attr, const char *buf, size_t count)
{
- int value;
- int port;
- struct gpio_pin *pin;
-
- port = mtac_port_from_kobject(kobj);
- if (port < 1) {
- log_error("mtac_port_from_kobject returned %d", port);
- return -EINVAL;
- }
-
- pin = mtac_gpio_pin_by_attr_name(attr->attr.name, port);
- if (!pin) {
- return -ENODEV;
- }
-
- if (sscanf(buf, "%i", &value) != 1) {
- return -EINVAL;
- }
-
- if (pin->active_low) {
- value = !value;
- }
-
- log_debug("mtac_attr_store_ap_gpio_pin: State of mtac mutex is %s",
- mutex_is_locked(&mtac_mutex) ? "locked" : "unlocked");
- mutex_lock(&mtac_mutex);
-
- gpio_set_value(pin->pin.gpio, value);
-
- mutex_unlock(&mtac_mutex);
-
- return count;
+ int value;
+ int port;
+ struct gpio_pin *pin;
+
+ port = mtac_port_from_kobject(kobj);
+ if (port < 1) {
+ log_error("mtac_port_from_kobject returned %d", port);
+ return -EINVAL;
+ }
+
+ pin = mtac_gpio_pin_by_attr_name(attr->attr.name, port);
+ if (!pin) {
+ return -ENODEV;
+ }
+
+ if (sscanf(buf, "%i", &value) != 1) {
+ return -EINVAL;
+ }
+
+ if (pin->active_low) {
+ value = !value;
+ }
+
+ log_debug("mtac_attr_store_ap_gpio_pin: State of mtac mutex is %s",
+ mutex_is_locked(&mtac_mutex) ? "locked" : "unlocked");
+ mutex_lock(&mtac_mutex);
+
+ if (pin->do_gpio_desc) {
+ gpiod_set_value(pin->desc, value);
+ } else {
+ gpio_set_value(pin->pin.gpio, value);
+ }
+ mutex_unlock(&mtac_mutex);
+
+ return count;
}
EXPORT_SYMBOL(mtac_attr_store_ap_gpio_pin);
static void display_port(int port_index) {
int port = port_index + 1;
struct mts_ap_eeprom_layout *app;
-
+
/* Our caller has locked the mtac_mutex */
if(!mutex_is_locked(&mtac_mutex))
@@ -325,40 +337,55 @@ static void display_port(int port_index) {
static void acquire_gpio(struct gpio_pin *pins, int port_index)
{
- char buf[32];
- struct gpio_pin *pin;
- int ret;
-
- snprintf(buf,sizeof buf,"AP%d_",port_index+1);
- for (pin = pins; *pin->name; pin++) {
- if (!memcmp(pin->name,buf,strlen(buf))) {
- log_debug("Request name:%s label: %s pin: %d", pin->name, pin->pin.label, pin->pin.gpio);
- ret = gpio_request_one(pin->pin.gpio, pin->pin.flags, pin->pin.label);
- if (ret)
- log_debug("could not request pin %s (%d) but it could have already been requested under a different pin name", pin->name, ret);
- }
- }
+ char buf[32];
+ struct gpio_pin *pin;
+ int ret;
+
+ snprintf(buf,sizeof buf,"AP%d_",port_index+1);
+ for (pin = pins; *pin->name; pin++) {
+ if (!memcmp(pin->name,buf,strlen(buf))) {
+ if (pin->do_gpio_desc) {
+ log_debug("Request name:%s label: %s", pin->name, pin->pin.label);
+ pin->desc = devm_gpiod_get_optional(&mts_io_platform_device->dev, pin->name, pin->pin.flags);
+ if (IS_ERR(pin->desc)) {
+ dev_dbg(&mts_io_platform_device->dev,
+ "%s: Could not get gpio %s: Error: %ld\n", __func__, pin->name, PTR_ERR(pin->desc));
+ } else {
+ if (pin->desc == NULL)
+ dev_dbg(&mts_io_platform_device->dev,"gpio_desc is null for name: %s, label: %s\n",
+ pin->name, pin->pin.label);
+ else
+ dev_dbg(&mts_io_platform_device->dev,"Found gpio %s\n", pin->name);
+ }
+ } else {
+ log_debug("Request name:%s label: %s pin: %d", pin->name, pin->pin.label, pin->pin.gpio);
+ ret = gpio_request_one(pin->pin.gpio, pin->pin.flags, pin->pin.label);
+ if (ret)
+ log_debug("could not request pin %s (%d) but it could have already been requested under a different pin name", pin->name, ret);
+ }
+ }
+ }
}
#include <linux/delay.h>
struct gpio_pin *mtac_gpio_pin_by_name(const char *name, int port_index) {
- struct gpio_pin *pin;
-
- log_debug("mtac_gpio_pin_by_name: State of mtac mutex is %s",
- mutex_is_locked(&mtac_mutex) ? "locked" : "unlocked");
- mutex_lock(&mtac_mutex);
- for (pin = mtac_port_info[port_index]->gpio_pins; *pin->name; pin++) {
- if (!strcmp(pin->name, name)) {
- mutex_unlock(&mtac_mutex);
- return pin;
- }
- }
- mutex_unlock(&mtac_mutex);
-
- log_error("pin named %s not found", name);
-
- return NULL;
+ struct gpio_pin *pin;
+
+ log_debug("mtac_gpio_pin_by_name: State of mtac mutex is %s",
+ mutex_is_locked(&mtac_mutex) ? "locked" : "unlocked");
+ mutex_lock(&mtac_mutex);
+ for (pin = mtac_port_info[port_index]->gpio_pins; *pin->name; pin++) {
+ if (!strcmp(pin->name, name)) {
+ mutex_unlock(&mtac_mutex);
+ return pin;
+ }
+ }
+ mutex_unlock(&mtac_mutex);
+
+ log_error("pin named %s not found", name);
+
+ return NULL;
}
EXPORT_SYMBOL(mtac_gpio_pin_by_name);
@@ -366,24 +393,24 @@ EXPORT_SYMBOL(mtac_gpio_pin_by_name);
/* static gpio_pins */
// A GPIO pin number must only occur once.
struct gpio_pin *mtac_gpio_pin_by_num(unsigned num, int port_index) {
- int ipin = 0;
- struct gpio_pin *port_gpio_pins;
-
- log_debug("mtac_gpio_pin_by_num: State of mtac mutex is %s",
- mutex_is_locked(&mtac_mutex) ? "locked" : "unlocked");
- mutex_lock(&mtac_mutex);
- port_gpio_pins = mtac_port_info[port_index]->gpio_pins;
- while(*(port_gpio_pins[ipin].name)) {
- if (port_gpio_pins[ipin].pin.gpio == num) {
- mutex_unlock(&mtac_mutex);
- return &(port_gpio_pins[ipin]);
- }
- ipin++;
- }
- mutex_unlock(&mtac_mutex);
- log_error("pin numbered %u not found", num);
-
- return NULL;
+ int ipin = 0;
+ struct gpio_pin *port_gpio_pins;
+
+ log_debug("mtac_gpio_pin_by_num: State of mtac mutex is %s",
+ mutex_is_locked(&mtac_mutex) ? "locked" : "unlocked");
+ mutex_lock(&mtac_mutex);
+ port_gpio_pins = mtac_port_info[port_index]->gpio_pins;
+ while(*(port_gpio_pins[ipin].name)) {
+ if (port_gpio_pins[ipin].pin.gpio == num) {
+ mutex_unlock(&mtac_mutex);
+ return &(port_gpio_pins[ipin]);
+ }
+ ipin++;
+ }
+ mutex_unlock(&mtac_mutex);
+ log_error("pin numbered %u not found", num);
+
+ return NULL;
}
EXPORT_SYMBOL(mtac_gpio_pin_by_num);
@@ -464,7 +491,7 @@ void mtac_free(const char *product_id, bool(* setup)(enum ap port), const char *
log_debug("setup: %p setup ptr: %p",mtac_port_info[port_index]->setup,setup);
if (mtac_port_info[port_index] && (mtac_port_info[port_index]->setup == setup)) {
log_debug("port_index %d is occupied by us, teardown next",port_index);
-
+
if (count > 1) {
sprintf(buf, "%s-%d",link,port);
} else {