Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add adg1414 driver #2344

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

add adg1414 driver #2344

wants to merge 2 commits into from

Conversation

kseerp
Copy link
Contributor

@kseerp kseerp commented Nov 15, 2023

the driver was tested on rpi4 with eval-adg1414

datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ADG1414.pdf

Copy link
Contributor

@amiclaus amiclaus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some comments on my side. I'd suggest sending this upstream first (mainline kernel), since the datasheet is public.

Documentation/devicetree/bindings/gpio/gpio-adg1414.yaml Outdated Show resolved Hide resolved
Documentation/devicetree/bindings/gpio/gpio-adg1414.yaml Outdated Show resolved Hide resolved
Documentation/devicetree/bindings/gpio/gpio-adg1414.yaml Outdated Show resolved Hide resolved
spi-max-frequency:
maximum: 50000000

spi-cpha: true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

drop this after including $ref: /schemas/spi/spi-peripheral-props.yaml#

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i checked other drivers and found out that most of them still include the spi-cpha

struct gpio_chip chip;
struct mutex lock; /* protect sensor state */
u8 buffer[32];

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

drop extra line

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checkpatch will show a warning when removing the extra line. I think i have to retain it

drivers/gpio/gpio-adg1414.c Outdated Show resolved Hide resolved
drivers/gpio/gpio-adg1414.c Outdated Show resolved Hide resolved
@kseerp
Copy link
Contributor Author

kseerp commented Nov 17, 2023

v2:

dt-bindings
added $ref: /schemas/spi/spi-peripheral-props.yaml#
dropped spi-max-frequency property
replaced additionalProperties to unevaluatedProperties

driver
placed ARCH_KMALLOC_MINALIGN inline
dropped lock/unlock

@kseerp
Copy link
Contributor Author

kseerp commented Nov 24, 2023

Hi, just to follow up, is this ready to be sent upstream?

@nunojsa
Copy link
Collaborator

nunojsa commented Nov 24, 2023

Hi, just to follow up, is this ready to be sent upstream?

I'll have a look today

description: GPIO specifier that resets the device.
maxItems: 1

daisy-chained-devices:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see this in Documentation/devicetree/bindings/common-properties.txt as #daisy-chained-devices. However I'm not sure if there's any schema for it? Are your bindings passsing validation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK, it passed the binding check

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm not sure if this is how to properly define this

  '#daisy-chained-devices':
    description: The number of daisy-chained devices.
    default: 1
    minimum: 1
    maximum: 4

struct gpio_chip chip;
u8 buffer[32];

__be32 tx __aligned(ARCH_KMALLOC_MINALIGN);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't forget to adapt this upstream


st->chip.label = "adg1414";
st->chip.parent = dev;
st->chip.owner = THIS_MODULE;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for it

return dev_err_probe(dev, PTR_ERR(reset), "Failed to get reset gpio");

if (reset) {
ndelay(15);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fsleep()


if (reset) {
ndelay(15);
gpiod_set_value_cansleep(reset, 1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gpiod_set_value_cansleep(reset, 0), right?

&num_devices);
if (!ret) {
if (num_devices > 4 || num_devices < 1)
return dev_err_probe(dev, ret,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some #defines would be nice instead of the raw numbers

struct adg1414_state *st = gpiochip_get_data(chip);

return st->buffer[offset];
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAICT, there's no guaranteed locking in gpiolib and you're accessing device shared data in adg1414_get() and adg1414_st(). Your buffer and tx should likely be properly protected.

The ADG1414 is a 9.5 Ω RON ±15 V/+12 V/±5 V iCMOS Serially-Controlled
Octal SPST Switches

Signed-off-by: Kim Seer Paller <kimseer.paller@analog.com>
The ADG1414 is a 9.5 Ω RON ±15 V/+12 V/±5 V iCMOS Serially-Controlled
Octal SPST Switches

Signed-off-by: Kim Seer Paller <kimseer.paller@analog.com>
@kseerp kseerp reopened this Nov 29, 2023
@kseerp
Copy link
Contributor Author

kseerp commented Nov 29, 2023

v3

modified daisy-chained-devices property
added mutex lock
replaced ndelay to fsleep
changed gpiod_set_value_cansleep to correct state

Copy link
Collaborator

@nunojsa nunojsa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alright, check my comments and feel free to send this upstream. Again, I'm not sure if gpio is really the right place for this but it feels to be the only acceptable place I'm aware of...

@@ -1606,6 +1606,16 @@ config GPIO_74X164
shift registers. This driver can be used to provide access
to more GPIO outputs.

config GPIO_ADG1414
tristate "ADG1414 SPST Switch Driver"
depends on GPIOLIB && SPI
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fairly sure you do not need to depend on GPIOLIB

struct adg1414_state {
struct spi_device *spi;
struct gpio_chip chip;
struct mutex lock;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the mutex needs a comment stating why we need it. Otherwise checkpatch will through a warning

struct adg1414_state *st = gpiochip_get_data(chip);
u32 tx = 0;
int i, ret;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: no extra line

"Failed to get reset gpio");

if (reset) {
fsleep(0.015);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh? Did you tested this? This is not going to work... do you really want nanoseconds in here? Just do fsleep(1)...

ret = device_property_read_u32(dev, "#daisy-chained-devices",
&num_devices);
if (!ret) {
if (num_devices > ADG1414_MAX_DEVICES || num_devices < 1)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use !num_devices instead of num_devices < 1


mutex_lock(&st->lock);

st->buffer[offset] = value;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe your buffer could just be a bitmap... then you can use things like set_bit() or clear_bit() to make the code simpler. Also take a look here:

https://elixir.bootlin.com/linux/latest/source/include/linux/bitmap.h

see if you find anything you can use to make the code simpler... Basically I'm fairly sure that you can likely refactor things so that for() loop is not really needed.

@SRaus SRaus changed the base branch from master to main January 9, 2024 09:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants