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
Kirill Smelkov
linux
Commits
f6d29536
Commit
f6d29536
authored
Nov 01, 2017
by
Wolfram Sang
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'i2c/sbs-manager' into i2c/for-4.15
parents
4ee045f4
4cf419a2
Changes
14
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
675 additions
and
148 deletions
+675
-148
Documentation/devicetree/bindings/i2c/i2c.txt
Documentation/devicetree/bindings/i2c/i2c.txt
+2
-2
Documentation/devicetree/bindings/power/supply/sbs,sbs-manager.txt
...tion/devicetree/bindings/power/supply/sbs,sbs-manager.txt
+66
-0
drivers/i2c/busses/i2c-parport-light.c
drivers/i2c/busses/i2c-parport-light.c
+0
-1
drivers/i2c/busses/i2c-parport.c
drivers/i2c/busses/i2c-parport.c
+0
-1
drivers/i2c/busses/i2c-thunderx-pcidrv.c
drivers/i2c/busses/i2c-thunderx-pcidrv.c
+0
-6
drivers/i2c/i2c-core-base.c
drivers/i2c/i2c-core-base.c
+9
-0
drivers/i2c/i2c-core-smbus.c
drivers/i2c/i2c-core-smbus.c
+55
-0
drivers/i2c/i2c-smbus.c
drivers/i2c/i2c-smbus.c
+25
-56
drivers/i2c/muxes/i2c-mux-pca954x.c
drivers/i2c/muxes/i2c-mux-pca954x.c
+32
-63
drivers/power/supply/Kconfig
drivers/power/supply/Kconfig
+14
-0
drivers/power/supply/Makefile
drivers/power/supply/Makefile
+1
-0
drivers/power/supply/sbs-battery.c
drivers/power/supply/sbs-battery.c
+17
-18
drivers/power/supply/sbs-manager.c
drivers/power/supply/sbs-manager.c
+445
-0
include/linux/i2c-smbus.h
include/linux/i2c-smbus.h
+9
-1
No files found.
Documentation/devicetree/bindings/i2c/i2c.txt
View file @
f6d29536
...
...
@@ -59,8 +59,8 @@ wants to support one of the below features, it should adapt the bindings below.
interrupts used by the device.
- interrupt-names
"irq"
and "wakeup" names are recognized by I2C core, other names are
left to individual drivers.
"irq"
, "wakeup" and "smbus_alert" names are recognized by I2C core,
other names are
left to individual drivers.
- host-notify
device uses SMBus host notify protocol instead of interrupt line.
...
...
Documentation/devicetree/bindings/power/supply/sbs,sbs-manager.txt
0 → 100644
View file @
f6d29536
Binding for sbs-manager
Required properties:
- compatible: "<vendor>,<part-number>", "sbs,sbs-charger" as fallback. The part
number compatible string might be used in order to take care of vendor
specific registers.
- reg: integer, i2c address of the device. Should be <0xa>.
Optional properties:
- gpio-controller: Marks the port as GPIO controller.
See "gpio-specifier" in .../devicetree/bindings/gpio/gpio.txt.
- #gpio-cells: Should be <2>. The first cell is the pin number, the second cell
is used to specify optional parameters:
See "gpio-specifier" in .../devicetree/bindings/gpio/gpio.txt.
From OS view the device is basically an i2c-mux used to communicate with up to
four smart battery devices at address 0xb. The driver actually implements this
behaviour. So standard i2c-mux nodes can be used to register up to four slave
batteries. Channels will be numerated starting from 1 to 4.
Example:
batman@a {
compatible = "lltc,ltc1760", "sbs,sbs-manager";
reg = <0x0a>;
#address-cells = <1>;
#size-cells = <0>;
gpio-controller;
#gpio-cells = <2>;
i2c@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
battery@b {
compatible = "ti,bq2060", "sbs,sbs-battery";
reg = <0x0b>;
sbs,battery-detect-gpios = <&batman 1 1>;
};
};
i2c@2 {
#address-cells = <1>;
#size-cells = <0>;
reg = <2>;
battery@b {
compatible = "ti,bq2060", "sbs,sbs-battery";
reg = <0x0b>;
sbs,battery-detect-gpios = <&batman 2 1>;
};
};
i2c@3 {
#address-cells = <1>;
#size-cells = <0>;
reg = <3>;
battery@b {
compatible = "ti,bq2060", "sbs,sbs-battery";
reg = <0x0b>;
sbs,battery-detect-gpios = <&batman 3 1>;
};
};
};
drivers/i2c/busses/i2c-parport-light.c
View file @
f6d29536
...
...
@@ -123,7 +123,6 @@ static struct i2c_adapter parport_adapter = {
/* SMBus alert support */
static
struct
i2c_smbus_alert_setup
alert_data
=
{
.
alert_edge_triggered
=
1
,
};
static
struct
i2c_client
*
ara
;
static
struct
lineop
parport_ctrl_irq
=
{
...
...
drivers/i2c/busses/i2c-parport.c
View file @
f6d29536
...
...
@@ -237,7 +237,6 @@ static void i2c_parport_attach(struct parport *port)
/* Setup SMBus alert if supported */
if
(
adapter_parm
[
type
].
smbus_alert
)
{
adapter
->
alert_data
.
alert_edge_triggered
=
1
;
adapter
->
ara
=
i2c_setup_smbus_alert
(
&
adapter
->
adapter
,
&
adapter
->
alert_data
);
if
(
adapter
->
ara
)
...
...
drivers/i2c/busses/i2c-thunderx-pcidrv.c
View file @
f6d29536
...
...
@@ -118,8 +118,6 @@ static void thunder_i2c_clock_disable(struct device *dev, struct clk *clk)
static
int
thunder_i2c_smbus_setup_of
(
struct
octeon_i2c
*
i2c
,
struct
device_node
*
node
)
{
u32
type
;
if
(
!
node
)
return
-
EINVAL
;
...
...
@@ -127,10 +125,6 @@ static int thunder_i2c_smbus_setup_of(struct octeon_i2c *i2c,
if
(
!
i2c
->
alert_data
.
irq
)
return
-
EINVAL
;
type
=
irqd_get_trigger_type
(
irq_get_irq_data
(
i2c
->
alert_data
.
irq
));
i2c
->
alert_data
.
alert_edge_triggered
=
(
type
&
IRQ_TYPE_LEVEL_MASK
)
?
1
:
0
;
i2c
->
ara
=
i2c_setup_smbus_alert
(
&
i2c
->
adap
,
&
i2c
->
alert_data
);
if
(
!
i2c
->
ara
)
return
-
ENODEV
;
...
...
drivers/i2c/i2c-core-base.c
View file @
f6d29536
...
...
@@ -29,6 +29,7 @@
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/i2c-smbus.h>
#include <linux/idr.h>
#include <linux/init.h>
#include <linux/irqflags.h>
...
...
@@ -1269,6 +1270,10 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
goto
out_list
;
}
res
=
of_i2c_setup_smbus_alert
(
adap
);
if
(
res
)
goto
out_reg
;
dev_dbg
(
&
adap
->
dev
,
"adapter [%s] registered
\n
"
,
adap
->
name
);
pm_runtime_no_callbacks
(
&
adap
->
dev
);
...
...
@@ -1300,6 +1305,10 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
return
0
;
out_reg:
init_completion
(
&
adap
->
dev_released
);
device_unregister
(
&
adap
->
dev
);
wait_for_completion
(
&
adap
->
dev_released
);
out_list:
mutex_lock
(
&
core_lock
);
idr_remove
(
&
i2c_adapter_idr
,
adap
->
nr
);
...
...
drivers/i2c/i2c-core-smbus.c
View file @
f6d29536
...
...
@@ -17,6 +17,7 @@
#include <linux/device.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/i2c-smbus.h>
#define CREATE_TRACE_POINTS
#include <trace/events/smbus.h>
...
...
@@ -592,3 +593,57 @@ s32 i2c_smbus_read_i2c_block_data_or_emulated(const struct i2c_client *client,
return
i
;
}
EXPORT_SYMBOL
(
i2c_smbus_read_i2c_block_data_or_emulated
);
/**
* i2c_setup_smbus_alert - Setup SMBus alert support
* @adapter: the target adapter
* @setup: setup data for the SMBus alert handler
* Context: can sleep
*
* Setup handling of the SMBus alert protocol on a given I2C bus segment.
*
* Handling can be done either through our IRQ handler, or by the
* adapter (from its handler, periodic polling, or whatever).
*
* NOTE that if we manage the IRQ, we *MUST* know if it's level or
* edge triggered in order to hand it to the workqueue correctly.
* If triggering the alert seems to wedge the system, you probably
* should have said it's level triggered.
*
* This returns the ara client, which should be saved for later use with
* i2c_handle_smbus_alert() and ultimately i2c_unregister_device(); or NULL
* to indicate an error.
*/
struct
i2c_client
*
i2c_setup_smbus_alert
(
struct
i2c_adapter
*
adapter
,
struct
i2c_smbus_alert_setup
*
setup
)
{
struct
i2c_board_info
ara_board_info
=
{
I2C_BOARD_INFO
(
"smbus_alert"
,
0x0c
),
.
platform_data
=
setup
,
};
return
i2c_new_device
(
adapter
,
&
ara_board_info
);
}
EXPORT_SYMBOL_GPL
(
i2c_setup_smbus_alert
);
#if IS_ENABLED(CONFIG_I2C_SMBUS) && IS_ENABLED(CONFIG_OF)
int
of_i2c_setup_smbus_alert
(
struct
i2c_adapter
*
adapter
)
{
struct
i2c_client
*
client
;
int
irq
;
irq
=
of_property_match_string
(
adapter
->
dev
.
of_node
,
"interrupt-names"
,
"smbus_alert"
);
if
(
irq
==
-
EINVAL
||
irq
==
-
ENODATA
)
return
0
;
else
if
(
irq
<
0
)
return
irq
;
client
=
i2c_setup_smbus_alert
(
adapter
,
NULL
);
if
(
!
client
)
return
-
ENODEV
;
return
0
;
}
EXPORT_SYMBOL_GPL
(
of_i2c_setup_smbus_alert
);
#endif
drivers/i2c/i2c-smbus.c
View file @
f6d29536
...
...
@@ -21,12 +21,11 @@
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_irq.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
struct
i2c_smbus_alert
{
unsigned
int
alert_edge_triggered
:
1
;
int
irq
;
struct
work_struct
alert
;
struct
i2c_client
*
ara
;
/* Alert response address */
};
...
...
@@ -72,13 +71,12 @@ static int smbus_do_alert(struct device *dev, void *addrp)
* The alert IRQ handler needs to hand work off to a task which can issue
* SMBus calls, because those sleeping calls can't be made in IRQ context.
*/
static
void
smbus_alert
(
struct
work_struct
*
work
)
static
irqreturn_t
smbus_alert
(
int
irq
,
void
*
d
)
{
struct
i2c_smbus_alert
*
alert
;
struct
i2c_smbus_alert
*
alert
=
d
;
struct
i2c_client
*
ara
;
unsigned
short
prev_addr
=
0
;
/* Not a valid address */
alert
=
container_of
(
work
,
struct
i2c_smbus_alert
,
alert
);
ara
=
alert
->
ara
;
for
(;;)
{
...
...
@@ -115,21 +113,17 @@ static void smbus_alert(struct work_struct *work)
prev_addr
=
data
.
addr
;
}
/* We handled all alerts; re-enable level-triggered IRQs */
if
(
!
alert
->
alert_edge_triggered
)
enable_irq
(
alert
->
irq
);
return
IRQ_HANDLED
;
}
static
irqreturn_t
smbalert_irq
(
int
irq
,
void
*
d
)
static
void
smbalert_work
(
struct
work_struct
*
work
)
{
struct
i2c_smbus_alert
*
alert
=
d
;
struct
i2c_smbus_alert
*
alert
;
/* Disable level-triggered IRQs until we handle them */
if
(
!
alert
->
alert_edge_triggered
)
disable_irq_nosync
(
irq
);
alert
=
container_of
(
work
,
struct
i2c_smbus_alert
,
alert
);
smbus_alert
(
0
,
alert
);
schedule_work
(
&
alert
->
alert
);
return
IRQ_HANDLED
;
}
/* Setup SMBALERT# infrastructure */
...
...
@@ -139,28 +133,35 @@ static int smbalert_probe(struct i2c_client *ara,
struct
i2c_smbus_alert_setup
*
setup
=
dev_get_platdata
(
&
ara
->
dev
);
struct
i2c_smbus_alert
*
alert
;
struct
i2c_adapter
*
adapter
=
ara
->
adapter
;
int
res
;
int
res
,
irq
;
alert
=
devm_kzalloc
(
&
ara
->
dev
,
sizeof
(
struct
i2c_smbus_alert
),
GFP_KERNEL
);
if
(
!
alert
)
return
-
ENOMEM
;
alert
->
alert_edge_triggered
=
setup
->
alert_edge_triggered
;
alert
->
irq
=
setup
->
irq
;
INIT_WORK
(
&
alert
->
alert
,
smbus_alert
);
if
(
setup
)
{
irq
=
setup
->
irq
;
}
else
{
irq
=
of_irq_get_byname
(
adapter
->
dev
.
of_node
,
"smbus_alert"
);
if
(
irq
<=
0
)
return
irq
;
}
INIT_WORK
(
&
alert
->
alert
,
smbalert_work
);
alert
->
ara
=
ara
;
if
(
setup
->
irq
>
0
)
{
res
=
devm_request_irq
(
&
ara
->
dev
,
setup
->
irq
,
smbalert_irq
,
0
,
"smbus_alert"
,
alert
);
if
(
irq
>
0
)
{
res
=
devm_request_threaded_irq
(
&
ara
->
dev
,
irq
,
NULL
,
smbus_alert
,
IRQF_SHARED
|
IRQF_ONESHOT
,
"smbus_alert"
,
alert
);
if
(
res
)
return
res
;
}
i2c_set_clientdata
(
ara
,
alert
);
dev_info
(
&
adapter
->
dev
,
"supports SMBALERT#, %s trigger
\n
"
,
setup
->
alert_edge_triggered
?
"edge"
:
"level"
);
dev_info
(
&
adapter
->
dev
,
"supports SMBALERT#
\n
"
);
return
0
;
}
...
...
@@ -189,38 +190,6 @@ static struct i2c_driver smbalert_driver = {
.
id_table
=
smbalert_ids
,
};
/**
* i2c_setup_smbus_alert - Setup SMBus alert support
* @adapter: the target adapter
* @setup: setup data for the SMBus alert handler
* Context: can sleep
*
* Setup handling of the SMBus alert protocol on a given I2C bus segment.
*
* Handling can be done either through our IRQ handler, or by the
* adapter (from its handler, periodic polling, or whatever).
*
* NOTE that if we manage the IRQ, we *MUST* know if it's level or
* edge triggered in order to hand it to the workqueue correctly.
* If triggering the alert seems to wedge the system, you probably
* should have said it's level triggered.
*
* This returns the ara client, which should be saved for later use with
* i2c_handle_smbus_alert() and ultimately i2c_unregister_device(); or NULL
* to indicate an error.
*/
struct
i2c_client
*
i2c_setup_smbus_alert
(
struct
i2c_adapter
*
adapter
,
struct
i2c_smbus_alert_setup
*
setup
)
{
struct
i2c_board_info
ara_board_info
=
{
I2C_BOARD_INFO
(
"smbus_alert"
,
0x0c
),
.
platform_data
=
setup
,
};
return
i2c_new_device
(
adapter
,
&
ara_board_info
);
}
EXPORT_SYMBOL_GPL
(
i2c_setup_smbus_alert
);
/**
* i2c_handle_smbus_alert - Handle an SMBus alert
* @ara: the ARA client on the relevant adapter
...
...
drivers/i2c/muxes/i2c-mux-pca954x.c
View file @
f6d29536
...
...
@@ -246,36 +246,6 @@ static irqreturn_t pca954x_irq_handler(int irq, void *dev_id)
return
handled
?
IRQ_HANDLED
:
IRQ_NONE
;
}
static
void
pca954x_irq_mask
(
struct
irq_data
*
idata
)
{
struct
pca954x
*
data
=
irq_data_get_irq_chip_data
(
idata
);
unsigned
int
pos
=
idata
->
hwirq
;
unsigned
long
flags
;
raw_spin_lock_irqsave
(
&
data
->
lock
,
flags
);
data
->
irq_mask
&=
~
BIT
(
pos
);
if
(
!
data
->
irq_mask
)
disable_irq
(
data
->
client
->
irq
);
raw_spin_unlock_irqrestore
(
&
data
->
lock
,
flags
);
}
static
void
pca954x_irq_unmask
(
struct
irq_data
*
idata
)
{
struct
pca954x
*
data
=
irq_data_get_irq_chip_data
(
idata
);
unsigned
int
pos
=
idata
->
hwirq
;
unsigned
long
flags
;
raw_spin_lock_irqsave
(
&
data
->
lock
,
flags
);
if
(
!
data
->
irq_mask
)
enable_irq
(
data
->
client
->
irq
);
data
->
irq_mask
|=
BIT
(
pos
);
raw_spin_unlock_irqrestore
(
&
data
->
lock
,
flags
);
}
static
int
pca954x_irq_set_type
(
struct
irq_data
*
idata
,
unsigned
int
type
)
{
if
((
type
&
IRQ_TYPE_SENSE_MASK
)
!=
IRQ_TYPE_LEVEL_LOW
)
...
...
@@ -285,8 +255,6 @@ static int pca954x_irq_set_type(struct irq_data *idata, unsigned int type)
static
struct
irq_chip
pca954x_irq_chip
=
{
.
name
=
"i2c-mux-pca954x"
,
.
irq_mask
=
pca954x_irq_mask
,
.
irq_unmask
=
pca954x_irq_unmask
,
.
irq_set_type
=
pca954x_irq_set_type
,
};
...
...
@@ -294,7 +262,7 @@ static int pca954x_irq_setup(struct i2c_mux_core *muxc)
{
struct
pca954x
*
data
=
i2c_mux_priv
(
muxc
);
struct
i2c_client
*
client
=
data
->
client
;
int
c
,
err
,
irq
;
int
c
,
irq
;
if
(
!
data
->
chip
->
has_irq
||
client
->
irq
<=
0
)
return
0
;
...
...
@@ -309,29 +277,31 @@ static int pca954x_irq_setup(struct i2c_mux_core *muxc)
for
(
c
=
0
;
c
<
data
->
chip
->
nchans
;
c
++
)
{
irq
=
irq_create_mapping
(
data
->
irq
,
c
);
if
(
!
irq
)
{
dev_err
(
&
client
->
dev
,
"failed irq create map
\n
"
);
return
-
EINVAL
;
}
irq_set_chip_data
(
irq
,
data
);
irq_set_chip_and_handler
(
irq
,
&
pca954x_irq_chip
,
handle_simple_irq
);
}
err
=
devm_request_threaded_irq
(
&
client
->
dev
,
data
->
client
->
irq
,
NULL
,
pca954x_irq_handler
,
IRQF_ONESHOT
|
IRQF_SHARED
,
"pca954x"
,
data
);
if
(
err
)
goto
err_req_irq
;
return
0
;
}
disable_irq
(
data
->
client
->
irq
);
static
void
pca954x_cleanup
(
struct
i2c_mux_core
*
muxc
)
{
struct
pca954x
*
data
=
i2c_mux_priv
(
muxc
);
int
c
,
irq
;
return
0
;
err_req_irq:
for
(
c
=
0
;
c
<
data
->
chip
->
nchans
;
c
++
)
{
irq
=
irq_find_mapping
(
data
->
irq
,
c
);
irq_dispose_mapping
(
irq
);
if
(
data
->
irq
)
{
for
(
c
=
0
;
c
<
data
->
chip
->
nchans
;
c
++
)
{
irq
=
irq_find_mapping
(
data
->
irq
,
c
);
irq_dispose_mapping
(
irq
);
}
irq_domain_remove
(
data
->
irq
);
}
irq_domain_remove
(
data
->
irq
);
return
err
;
i2c_mux_del_adapters
(
muxc
);
}
/*
...
...
@@ -391,7 +361,7 @@ static int pca954x_probe(struct i2c_client *client,
ret
=
pca954x_irq_setup
(
muxc
);
if
(
ret
)
goto
fail_
del_adapters
;
goto
fail_
cleanup
;
/* Now create an adapter for each channel */
for
(
num
=
0
;
num
<
data
->
chip
->
nchans
;
num
++
)
{
...
...
@@ -414,7 +384,16 @@ static int pca954x_probe(struct i2c_client *client,
ret
=
i2c_mux_add_adapter
(
muxc
,
force
,
num
,
class
);
if
(
ret
)
goto
fail_del_adapters
;
goto
fail_cleanup
;
}
if
(
data
->
irq
)
{
ret
=
devm_request_threaded_irq
(
&
client
->
dev
,
data
->
client
->
irq
,
NULL
,
pca954x_irq_handler
,
IRQF_ONESHOT
|
IRQF_SHARED
,
"pca954x"
,
data
);
if
(
ret
)
goto
fail_cleanup
;
}
dev_info
(
&
client
->
dev
,
...
...
@@ -424,26 +403,16 @@ static int pca954x_probe(struct i2c_client *client,
return
0
;
fail_
del_adapters
:
i2c_mux_del_adapters
(
muxc
);
fail_
cleanup
:
pca954x_cleanup
(
muxc
);
return
ret
;
}
static
int
pca954x_remove
(
struct
i2c_client
*
client
)
{
struct
i2c_mux_core
*
muxc
=
i2c_get_clientdata
(
client
);
struct
pca954x
*
data
=
i2c_mux_priv
(
muxc
);
int
c
,
irq
;
if
(
data
->
irq
)
{
for
(
c
=
0
;
c
<
data
->
chip
->
nchans
;
c
++
)
{
irq
=
irq_find_mapping
(
data
->
irq
,
c
);
irq_dispose_mapping
(
irq
);
}
irq_domain_remove
(
data
->
irq
);
}
i2c_mux_del_adapters
(
muxc
);
pca954x_cleanup
(
muxc
);
return
0
;
}
...
...
drivers/power/supply/Kconfig
View file @
f6d29536
...
...
@@ -184,6 +184,20 @@ config CHARGER_SBS
help
Say Y to include support for SBS compilant battery chargers.
config MANAGER_SBS
tristate "Smart Battery System Manager"
depends on I2C && I2C_MUX && GPIOLIB
select I2C_SMBUS
help
Say Y here to include support for Smart Battery System Manager
ICs. The driver reports online and charging status via sysfs.
It presents itself also as I2C mux which allows to bind
smart battery driver to its ports.
Supported is for example LTC1760.
This driver can also be built as a module. If so, the module will be
called sbs-manager.
config BATTERY_BQ27XXX
tristate "BQ27xxx battery driver"
help
...
...
drivers/power/supply/Makefile
View file @
f6d29536
...
...
@@ -36,6 +36,7 @@ obj-$(CONFIG_BATTERY_IPAQ_MICRO) += ipaq_micro_battery.o
obj-$(CONFIG_BATTERY_WM97XX)
+=
wm97xx_battery.o
obj-$(CONFIG_BATTERY_SBS)
+=
sbs-battery.o
obj-$(CONFIG_CHARGER_SBS)
+=
sbs-charger.o
obj-$(CONFIG_MANAGER_SBS)
+=
sbs-manager.o
obj-$(CONFIG_BATTERY_BQ27XXX)
+=
bq27xxx_battery.o
obj-$(CONFIG_BATTERY_BQ27XXX_I2C)
+=
bq27xxx_battery_i2c.o
obj-$(CONFIG_BATTERY_BQ27XXX_HDQ)
+=
bq27xxx_battery_hdq.o
...
...
drivers/power/supply/sbs-battery.c
View file @
f6d29536
...
...
@@ -177,10 +177,8 @@ static bool force_load;
static
int
sbs_read_word_data
(
struct
i2c_client
*
client
,
u8
address
)
{
struct
sbs_info
*
chip
=
i2c_get_clientdata
(
client
);
int
retries
=
chip
->
i2c_retry_count
;
s32
ret
=
0
;
int
retries
=
1
;
retries
=
chip
->
i2c_retry_count
;
while
(
retries
>
0
)
{
ret
=
i2c_smbus_read_word_data
(
client
,
address
);
...
...
@@ -204,7 +202,7 @@ static int sbs_read_string_data(struct i2c_client *client, u8 address,
{
struct
sbs_info
*
chip
=
i2c_get_clientdata
(
client
);
s32
ret
=
0
,
block_length
=
0
;
int
retries_length
=
1
,
retries_block
=
1
;
int
retries_length
,
retries_block
;
u8
block_buffer
[
I2C_SMBUS_BLOCK_MAX
+
1
];
retries_length
=
chip
->
i2c_retry_count
;
...
...
@@ -269,10 +267,8 @@ static int sbs_write_word_data(struct i2c_client *client, u8 address,
u16
value
)
{
struct
sbs_info
*
chip
=
i2c_get_clientdata
(
client
);
int
retries
=
chip
->
i2c_retry_count
;
s32
ret
=
0
;
int
retries
=
1
;
retries
=
chip
->
i2c_retry_count
;
while
(
retries
>
0
)
{
ret
=
i2c_smbus_write_word_data
(
client
,
address
,
value
);
...
...
@@ -321,16 +317,6 @@ static int sbs_get_battery_presence_and_health(
union
power_supply_propval
*
val
)
{
s32
ret
;
struct
sbs_info
*
chip
=
i2c_get_clientdata
(
client
);
if
(
psp
==
POWER_SUPPLY_PROP_PRESENT
&&
chip
->
gpio_detect
)
{
ret
=
gpiod_get_value_cansleep
(
chip
->
gpio_detect
);
if
(
ret
<
0
)
return
ret
;
val
->
intval
=
ret
;
chip
->
is_present
=
val
->
intval
;
return
ret
;
}
/*
* Write to ManufacturerAccess with ManufacturerAccess command
...
...
@@ -570,7 +556,7 @@ static int sbs_get_battery_serial_number(struct i2c_client *client,
if
(
ret
<
0
)
return
ret
;
ret
=
sprintf
(
sbs_serial
,
"%04x"
,
ret
);
sprintf
(
sbs_serial
,
"%04x"
,
ret
);
val
->
strval
=
sbs_serial
;
return
0
;
...
...
@@ -598,6 +584,19 @@ static int sbs_get_property(struct power_supply *psy,
struct
sbs_info
*
chip
=
power_supply_get_drvdata
(
psy
);
struct
i2c_client
*
client
=
chip
->
client
;
if
(
chip
->
gpio_detect
)
{
ret
=
gpiod_get_value_cansleep
(
chip
->
gpio_detect
);
if
(
ret
<
0
)
return
ret
;
if
(
psp
==
POWER_SUPPLY_PROP_PRESENT
)
{
val
->
intval
=
ret
;
chip
->
is_present
=
val
->
intval
;
return
0
;
}
if
(
ret
==
0
)
return
-
ENODATA
;
}
switch
(
psp
)
{
case
POWER_SUPPLY_PROP_PRESENT
:
case
POWER_SUPPLY_PROP_HEALTH
:
...
...
drivers/power/supply/sbs-manager.c
0 → 100644
View file @
f6d29536
This diff is collapsed.
Click to expand it.
include/linux/i2c-smbus.h
View file @
f6d29536
...
...
@@ -42,7 +42,6 @@
* properly set.
*/
struct
i2c_smbus_alert_setup
{
unsigned
int
alert_edge_triggered
:
1
;
int
irq
;
};
...
...
@@ -50,4 +49,13 @@ struct i2c_client *i2c_setup_smbus_alert(struct i2c_adapter *adapter,
struct
i2c_smbus_alert_setup
*
setup
);
int
i2c_handle_smbus_alert
(
struct
i2c_client
*
ara
);
#if IS_ENABLED(CONFIG_I2C_SMBUS) && IS_ENABLED(CONFIG_OF)
int
of_i2c_setup_smbus_alert
(
struct
i2c_adapter
*
adap
);
#else
static
inline
int
of_i2c_setup_smbus_alert
(
struct
i2c_adapter
*
adap
)
{
return
0
;
}
#endif
#endif
/* _LINUX_I2C_SMBUS_H */
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