Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
92de6bc3
Commit
92de6bc3
authored
Feb 14, 2019
by
Linus Walleij
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'ib-pca953x-config' into devel
parents
5340f23d
15add068
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
127 additions
and
18 deletions
+127
-18
Documentation/devicetree/bindings/gpio/gpio.txt
Documentation/devicetree/bindings/gpio/gpio.txt
+12
-0
drivers/gpio/gpio-pca953x.c
drivers/gpio/gpio-pca953x.c
+64
-2
drivers/gpio/gpiolib-of.c
drivers/gpio/gpiolib-of.c
+5
-0
drivers/gpio/gpiolib.c
drivers/gpio/gpiolib.c
+34
-16
drivers/gpio/gpiolib.h
drivers/gpio/gpiolib.h
+2
-0
include/dt-bindings/gpio/gpio.h
include/dt-bindings/gpio/gpio.h
+6
-0
include/linux/gpio/machine.h
include/linux/gpio/machine.h
+2
-0
include/linux/of_gpio.h
include/linux/of_gpio.h
+2
-0
No files found.
Documentation/devicetree/bindings/gpio/gpio.txt
View file @
92de6bc3
...
@@ -67,6 +67,18 @@ Optional standard bitfield specifiers for the last cell:
...
@@ -67,6 +67,18 @@ Optional standard bitfield specifiers for the last cell:
https://en.wikipedia.org/wiki/Open_collector
https://en.wikipedia.org/wiki/Open_collector
- Bit 3: 0 means the output should be maintained during sleep/low-power mode
- Bit 3: 0 means the output should be maintained during sleep/low-power mode
1 means the output state can be lost during sleep/low-power mode
1 means the output state can be lost during sleep/low-power mode
- Bit 4: 0 means no pull-up resistor should be enabled
1 means a pull-up resistor should be enabled
This setting only applies to hardware with a simple on/off
control for pull-up configuration. If the hardware has more
elaborate pull-up configuration, it should be represented
using a pin control binding.
- Bit 5: 0 means no pull-down resistor should be enabled
1 means a pull-down resistor should be enabled
This setting only applies to hardware with a simple on/off
control for pull-down configuration. If the hardware has more
elaborate pull-down configuration, it should be represented
using a pin control binding.
1.1) GPIO specifier best practices
1.1) GPIO specifier best practices
----------------------------------
----------------------------------
...
...
drivers/gpio/gpio-pca953x.c
View file @
92de6bc3
...
@@ -179,6 +179,8 @@ static int pca953x_bank_shift(struct pca953x_chip *chip)
...
@@ -179,6 +179,8 @@ static int pca953x_bank_shift(struct pca953x_chip *chip)
#define PCA957x_BANK_OUTPUT BIT(5)
#define PCA957x_BANK_OUTPUT BIT(5)
#define PCAL9xxx_BANK_IN_LATCH BIT(8 + 2)
#define PCAL9xxx_BANK_IN_LATCH BIT(8 + 2)
#define PCAL9xxx_BANK_PULL_EN BIT(8 + 3)
#define PCAL9xxx_BANK_PULL_SEL BIT(8 + 4)
#define PCAL9xxx_BANK_IRQ_MASK BIT(8 + 5)
#define PCAL9xxx_BANK_IRQ_MASK BIT(8 + 5)
#define PCAL9xxx_BANK_IRQ_STAT BIT(8 + 6)
#define PCAL9xxx_BANK_IRQ_STAT BIT(8 + 6)
...
@@ -200,6 +202,8 @@ static int pca953x_bank_shift(struct pca953x_chip *chip)
...
@@ -200,6 +202,8 @@ static int pca953x_bank_shift(struct pca953x_chip *chip)
* - Extended set, above 0x40, often chip specific.
* - Extended set, above 0x40, often chip specific.
* - PCAL6524/PCAL9555A with custom PCAL IRQ handling:
* - PCAL6524/PCAL9555A with custom PCAL IRQ handling:
* Input latch register 0x40 + 2 * bank_size RW
* Input latch register 0x40 + 2 * bank_size RW
* Pull-up/pull-down enable reg 0x40 + 3 * bank_size RW
* Pull-up/pull-down select reg 0x40 + 4 * bank_size RW
* Interrupt mask register 0x40 + 5 * bank_size RW
* Interrupt mask register 0x40 + 5 * bank_size RW
* Interrupt status register 0x40 + 6 * bank_size R
* Interrupt status register 0x40 + 6 * bank_size R
*
*
...
@@ -248,7 +252,8 @@ static bool pca953x_readable_register(struct device *dev, unsigned int reg)
...
@@ -248,7 +252,8 @@ static bool pca953x_readable_register(struct device *dev, unsigned int reg)
}
}
if
(
chip
->
driver_data
&
PCA_PCAL
)
{
if
(
chip
->
driver_data
&
PCA_PCAL
)
{
bank
|=
PCAL9xxx_BANK_IN_LATCH
|
PCAL9xxx_BANK_IRQ_MASK
|
bank
|=
PCAL9xxx_BANK_IN_LATCH
|
PCAL9xxx_BANK_PULL_EN
|
PCAL9xxx_BANK_PULL_SEL
|
PCAL9xxx_BANK_IRQ_MASK
|
PCAL9xxx_BANK_IRQ_STAT
;
PCAL9xxx_BANK_IRQ_STAT
;
}
}
...
@@ -269,7 +274,8 @@ static bool pca953x_writeable_register(struct device *dev, unsigned int reg)
...
@@ -269,7 +274,8 @@ static bool pca953x_writeable_register(struct device *dev, unsigned int reg)
}
}
if
(
chip
->
driver_data
&
PCA_PCAL
)
if
(
chip
->
driver_data
&
PCA_PCAL
)
bank
|=
PCAL9xxx_BANK_IN_LATCH
|
PCAL9xxx_BANK_IRQ_MASK
;
bank
|=
PCAL9xxx_BANK_IN_LATCH
|
PCAL9xxx_BANK_PULL_EN
|
PCAL9xxx_BANK_PULL_SEL
|
PCAL9xxx_BANK_IRQ_MASK
;
return
pca953x_check_register
(
chip
,
reg
,
bank
);
return
pca953x_check_register
(
chip
,
reg
,
bank
);
}
}
...
@@ -474,6 +480,61 @@ static void pca953x_gpio_set_multiple(struct gpio_chip *gc,
...
@@ -474,6 +480,61 @@ static void pca953x_gpio_set_multiple(struct gpio_chip *gc,
mutex_unlock
(
&
chip
->
i2c_lock
);
mutex_unlock
(
&
chip
->
i2c_lock
);
}
}
static
int
pca953x_gpio_set_pull_up_down
(
struct
pca953x_chip
*
chip
,
unsigned
int
offset
,
unsigned
long
config
)
{
u8
pull_en_reg
=
pca953x_recalc_addr
(
chip
,
PCAL953X_PULL_EN
,
offset
,
true
,
false
);
u8
pull_sel_reg
=
pca953x_recalc_addr
(
chip
,
PCAL953X_PULL_SEL
,
offset
,
true
,
false
);
u8
bit
=
BIT
(
offset
%
BANK_SZ
);
int
ret
;
/*
* pull-up/pull-down configuration requires PCAL extended
* registers
*/
if
(
!
(
chip
->
driver_data
&
PCA_PCAL
))
return
-
ENOTSUPP
;
mutex_lock
(
&
chip
->
i2c_lock
);
/* Disable pull-up/pull-down */
ret
=
regmap_write_bits
(
chip
->
regmap
,
pull_en_reg
,
bit
,
0
);
if
(
ret
)
goto
exit
;
/* Configure pull-up/pull-down */
if
(
config
==
PIN_CONFIG_BIAS_PULL_UP
)
ret
=
regmap_write_bits
(
chip
->
regmap
,
pull_sel_reg
,
bit
,
bit
);
else
if
(
config
==
PIN_CONFIG_BIAS_PULL_DOWN
)
ret
=
regmap_write_bits
(
chip
->
regmap
,
pull_sel_reg
,
bit
,
0
);
if
(
ret
)
goto
exit
;
/* Enable pull-up/pull-down */
ret
=
regmap_write_bits
(
chip
->
regmap
,
pull_en_reg
,
bit
,
bit
);
exit:
mutex_unlock
(
&
chip
->
i2c_lock
);
return
ret
;
}
static
int
pca953x_gpio_set_config
(
struct
gpio_chip
*
gc
,
unsigned
int
offset
,
unsigned
long
config
)
{
struct
pca953x_chip
*
chip
=
gpiochip_get_data
(
gc
);
switch
(
config
)
{
case
PIN_CONFIG_BIAS_PULL_UP
:
case
PIN_CONFIG_BIAS_PULL_DOWN
:
return
pca953x_gpio_set_pull_up_down
(
chip
,
offset
,
config
);
default:
return
-
ENOTSUPP
;
}
}
static
void
pca953x_setup_gpio
(
struct
pca953x_chip
*
chip
,
int
gpios
)
static
void
pca953x_setup_gpio
(
struct
pca953x_chip
*
chip
,
int
gpios
)
{
{
struct
gpio_chip
*
gc
;
struct
gpio_chip
*
gc
;
...
@@ -486,6 +547,7 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
...
@@ -486,6 +547,7 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
gc
->
set
=
pca953x_gpio_set_value
;
gc
->
set
=
pca953x_gpio_set_value
;
gc
->
get_direction
=
pca953x_gpio_get_direction
;
gc
->
get_direction
=
pca953x_gpio_get_direction
;
gc
->
set_multiple
=
pca953x_gpio_set_multiple
;
gc
->
set_multiple
=
pca953x_gpio_set_multiple
;
gc
->
set_config
=
pca953x_gpio_set_config
;
gc
->
can_sleep
=
true
;
gc
->
can_sleep
=
true
;
gc
->
base
=
chip
->
gpio_start
;
gc
->
base
=
chip
->
gpio_start
;
...
...
drivers/gpio/gpiolib-of.c
View file @
92de6bc3
...
@@ -345,6 +345,11 @@ struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
...
@@ -345,6 +345,11 @@ struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
if
(
of_flags
&
OF_GPIO_TRANSITORY
)
if
(
of_flags
&
OF_GPIO_TRANSITORY
)
*
flags
|=
GPIO_TRANSITORY
;
*
flags
|=
GPIO_TRANSITORY
;
if
(
of_flags
&
OF_GPIO_PULL_UP
)
*
flags
|=
GPIO_PULL_UP
;
if
(
of_flags
&
OF_GPIO_PULL_DOWN
)
*
flags
|=
GPIO_PULL_DOWN
;
return
desc
;
return
desc
;
}
}
...
...
drivers/gpio/gpiolib.c
View file @
92de6bc3
...
@@ -2555,6 +2555,14 @@ EXPORT_SYMBOL_GPL(gpiochip_free_own_desc);
...
@@ -2555,6 +2555,14 @@ EXPORT_SYMBOL_GPL(gpiochip_free_own_desc);
* rely on gpio_request() having been called beforehand.
* rely on gpio_request() having been called beforehand.
*/
*/
static
int
gpio_set_config
(
struct
gpio_chip
*
gc
,
unsigned
offset
,
enum
pin_config_param
mode
)
{
unsigned
long
config
=
{
PIN_CONF_PACKED
(
mode
,
0
)
};
return
gc
->
set_config
?
gc
->
set_config
(
gc
,
offset
,
config
)
:
-
ENOTSUPP
;
}
/**
/**
* gpiod_direction_input - set the GPIO direction to input
* gpiod_direction_input - set the GPIO direction to input
* @desc: GPIO to set to input
* @desc: GPIO to set to input
...
@@ -2602,20 +2610,19 @@ int gpiod_direction_input(struct gpio_desc *desc)
...
@@ -2602,20 +2610,19 @@ int gpiod_direction_input(struct gpio_desc *desc)
if
(
status
==
0
)
if
(
status
==
0
)
clear_bit
(
FLAG_IS_OUT
,
&
desc
->
flags
);
clear_bit
(
FLAG_IS_OUT
,
&
desc
->
flags
);
if
(
test_bit
(
FLAG_PULL_UP
,
&
desc
->
flags
))
gpio_set_config
(
chip
,
gpio_chip_hwgpio
(
desc
),
PIN_CONFIG_BIAS_PULL_UP
);
else
if
(
test_bit
(
FLAG_PULL_DOWN
,
&
desc
->
flags
))
gpio_set_config
(
chip
,
gpio_chip_hwgpio
(
desc
),
PIN_CONFIG_BIAS_PULL_DOWN
);
trace_gpio_direction
(
desc_to_gpio
(
desc
),
1
,
status
);
trace_gpio_direction
(
desc_to_gpio
(
desc
),
1
,
status
);
return
status
;
return
status
;
}
}
EXPORT_SYMBOL_GPL
(
gpiod_direction_input
);
EXPORT_SYMBOL_GPL
(
gpiod_direction_input
);
static
int
gpio_set_drive_single_ended
(
struct
gpio_chip
*
gc
,
unsigned
offset
,
enum
pin_config_param
mode
)
{
unsigned
long
config
=
{
PIN_CONF_PACKED
(
mode
,
0
)
};
return
gc
->
set_config
?
gc
->
set_config
(
gc
,
offset
,
config
)
:
-
ENOTSUPP
;
}
static
int
gpiod_direction_output_raw_commit
(
struct
gpio_desc
*
desc
,
int
value
)
static
int
gpiod_direction_output_raw_commit
(
struct
gpio_desc
*
desc
,
int
value
)
{
{
struct
gpio_chip
*
gc
=
desc
->
gdev
->
chip
;
struct
gpio_chip
*
gc
=
desc
->
gdev
->
chip
;
...
@@ -2712,7 +2719,7 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)
...
@@ -2712,7 +2719,7 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)
gc
=
desc
->
gdev
->
chip
;
gc
=
desc
->
gdev
->
chip
;
if
(
test_bit
(
FLAG_OPEN_DRAIN
,
&
desc
->
flags
))
{
if
(
test_bit
(
FLAG_OPEN_DRAIN
,
&
desc
->
flags
))
{
/* First see if we can enable open drain in hardware */
/* First see if we can enable open drain in hardware */
ret
=
gpio_set_
drive_single_ended
(
gc
,
gpio_chip_hwgpio
(
desc
),
ret
=
gpio_set_
config
(
gc
,
gpio_chip_hwgpio
(
desc
),
PIN_CONFIG_DRIVE_OPEN_DRAIN
);
PIN_CONFIG_DRIVE_OPEN_DRAIN
);
if
(
!
ret
)
if
(
!
ret
)
goto
set_output_value
;
goto
set_output_value
;
...
@@ -2721,7 +2728,7 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)
...
@@ -2721,7 +2728,7 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)
return
gpiod_direction_input
(
desc
);
return
gpiod_direction_input
(
desc
);
}
}
else
if
(
test_bit
(
FLAG_OPEN_SOURCE
,
&
desc
->
flags
))
{
else
if
(
test_bit
(
FLAG_OPEN_SOURCE
,
&
desc
->
flags
))
{
ret
=
gpio_set_
drive_single_ended
(
gc
,
gpio_chip_hwgpio
(
desc
),
ret
=
gpio_set_
config
(
gc
,
gpio_chip_hwgpio
(
desc
),
PIN_CONFIG_DRIVE_OPEN_SOURCE
);
PIN_CONFIG_DRIVE_OPEN_SOURCE
);
if
(
!
ret
)
if
(
!
ret
)
goto
set_output_value
;
goto
set_output_value
;
...
@@ -2729,7 +2736,7 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)
...
@@ -2729,7 +2736,7 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)
if
(
!
value
)
if
(
!
value
)
return
gpiod_direction_input
(
desc
);
return
gpiod_direction_input
(
desc
);
}
else
{
}
else
{
gpio_set_
drive_single_ended
(
gc
,
gpio_chip_hwgpio
(
desc
),
gpio_set_
config
(
gc
,
gpio_chip_hwgpio
(
desc
),
PIN_CONFIG_DRIVE_PUSH_PULL
);
PIN_CONFIG_DRIVE_PUSH_PULL
);
}
}
...
@@ -2762,7 +2769,7 @@ int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce)
...
@@ -2762,7 +2769,7 @@ int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce)
}
}
config
=
pinconf_to_config_packed
(
PIN_CONFIG_INPUT_DEBOUNCE
,
debounce
);
config
=
pinconf_to_config_packed
(
PIN_CONFIG_INPUT_DEBOUNCE
,
debounce
);
return
chip
->
set_config
(
chip
,
gpio_chip_hwgpio
(
desc
),
config
);
return
gpio_
set_config
(
chip
,
gpio_chip_hwgpio
(
desc
),
config
);
}
}
EXPORT_SYMBOL_GPL
(
gpiod_set_debounce
);
EXPORT_SYMBOL_GPL
(
gpiod_set_debounce
);
...
@@ -2799,7 +2806,7 @@ int gpiod_set_transitory(struct gpio_desc *desc, bool transitory)
...
@@ -2799,7 +2806,7 @@ int gpiod_set_transitory(struct gpio_desc *desc, bool transitory)
packed
=
pinconf_to_config_packed
(
PIN_CONFIG_PERSIST_STATE
,
packed
=
pinconf_to_config_packed
(
PIN_CONFIG_PERSIST_STATE
,
!
transitory
);
!
transitory
);
gpio
=
gpio_chip_hwgpio
(
desc
);
gpio
=
gpio_chip_hwgpio
(
desc
);
rc
=
chip
->
set_config
(
chip
,
gpio
,
packed
);
rc
=
gpio_
set_config
(
chip
,
gpio
,
packed
);
if
(
rc
==
-
ENOTSUPP
)
{
if
(
rc
==
-
ENOTSUPP
)
{
dev_dbg
(
&
desc
->
gdev
->
dev
,
"Persistence not supported for GPIO %d
\n
"
,
dev_dbg
(
&
desc
->
gdev
->
dev
,
"Persistence not supported for GPIO %d
\n
"
,
gpio
);
gpio
);
...
@@ -4087,6 +4094,17 @@ int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
...
@@ -4087,6 +4094,17 @@ int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
if
(
lflags
&
GPIO_OPEN_SOURCE
)
if
(
lflags
&
GPIO_OPEN_SOURCE
)
set_bit
(
FLAG_OPEN_SOURCE
,
&
desc
->
flags
);
set_bit
(
FLAG_OPEN_SOURCE
,
&
desc
->
flags
);
if
((
lflags
&
GPIO_PULL_UP
)
&&
(
lflags
&
GPIO_PULL_DOWN
))
{
gpiod_err
(
desc
,
"both pull-up and pull-down enabled, invalid configuration
\n
"
);
return
-
EINVAL
;
}
if
(
lflags
&
GPIO_PULL_UP
)
set_bit
(
FLAG_PULL_UP
,
&
desc
->
flags
);
else
if
(
lflags
&
GPIO_PULL_DOWN
)
set_bit
(
FLAG_PULL_DOWN
,
&
desc
->
flags
);
status
=
gpiod_set_transitory
(
desc
,
(
lflags
&
GPIO_TRANSITORY
));
status
=
gpiod_set_transitory
(
desc
,
(
lflags
&
GPIO_TRANSITORY
));
if
(
status
<
0
)
if
(
status
<
0
)
return
status
;
return
status
;
...
...
drivers/gpio/gpiolib.h
View file @
92de6bc3
...
@@ -219,6 +219,8 @@ struct gpio_desc {
...
@@ -219,6 +219,8 @@ struct gpio_desc {
#define FLAG_IRQ_IS_ENABLED 10
/* GPIO is connected to an enabled IRQ */
#define FLAG_IRQ_IS_ENABLED 10
/* GPIO is connected to an enabled IRQ */
#define FLAG_IS_HOGGED 11
/* GPIO is hogged */
#define FLAG_IS_HOGGED 11
/* GPIO is hogged */
#define FLAG_TRANSITORY 12
/* GPIO may lose value in sleep or reset */
#define FLAG_TRANSITORY 12
/* GPIO may lose value in sleep or reset */
#define FLAG_PULL_UP 13
/* GPIO has pull up enabled */
#define FLAG_PULL_DOWN 14
/* GPIO has pull down enabled */
/* Connection label */
/* Connection label */
const
char
*
label
;
const
char
*
label
;
...
...
include/dt-bindings/gpio/gpio.h
View file @
92de6bc3
...
@@ -33,4 +33,10 @@
...
@@ -33,4 +33,10 @@
#define GPIO_PERSISTENT 0
#define GPIO_PERSISTENT 0
#define GPIO_TRANSITORY 8
#define GPIO_TRANSITORY 8
/* Bit 4 express pull up */
#define GPIO_PULL_UP 16
/* Bit 5 express pull down */
#define GPIO_PULL_DOWN 32
#endif
#endif
include/linux/gpio/machine.h
View file @
92de6bc3
...
@@ -12,6 +12,8 @@ enum gpio_lookup_flags {
...
@@ -12,6 +12,8 @@ enum gpio_lookup_flags {
GPIO_OPEN_SOURCE
=
(
1
<<
2
),
GPIO_OPEN_SOURCE
=
(
1
<<
2
),
GPIO_PERSISTENT
=
(
0
<<
3
),
GPIO_PERSISTENT
=
(
0
<<
3
),
GPIO_TRANSITORY
=
(
1
<<
3
),
GPIO_TRANSITORY
=
(
1
<<
3
),
GPIO_PULL_UP
=
(
1
<<
4
),
GPIO_PULL_DOWN
=
(
1
<<
5
),
};
};
/**
/**
...
...
include/linux/of_gpio.h
View file @
92de6bc3
...
@@ -28,6 +28,8 @@ enum of_gpio_flags {
...
@@ -28,6 +28,8 @@ enum of_gpio_flags {
OF_GPIO_SINGLE_ENDED
=
0x2
,
OF_GPIO_SINGLE_ENDED
=
0x2
,
OF_GPIO_OPEN_DRAIN
=
0x4
,
OF_GPIO_OPEN_DRAIN
=
0x4
,
OF_GPIO_TRANSITORY
=
0x8
,
OF_GPIO_TRANSITORY
=
0x8
,
OF_GPIO_PULL_UP
=
0x10
,
OF_GPIO_PULL_DOWN
=
0x20
,
};
};
#ifdef CONFIG_OF_GPIO
#ifdef CONFIG_OF_GPIO
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment