bif: Add snapshot of bif-core framework and qpnp-bsi driver

This snapshot is taken as of msm-3.18 commit

bd4743e (Merge "ARM: dts: msm: Add display
configuration for msmgold")

Change-Id: I6f9c2fb7bcede6196da26a49dbd6aab598a0b5a9
Signed-off-by: Osvaldo Banuelos <osvaldob@codeaurora.org>
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
This commit is contained in:
Osvaldo Banuelos 2015-05-01 15:33:09 -07:00 committed by Rohit Vaswani
parent 77dd355971
commit 6221f73cda
12 changed files with 7225 additions and 0 deletions

View file

@ -91,6 +91,8 @@ basic_profiling.txt
- basic instructions for those who wants to profile Linux kernel.
bcache.txt
- Block-layer cache on fast SSDs to improve slow (raid) I/O performance.
bif-framework.txt
- information about MIPI-BIF support in the Linux kernel.
binfmt_misc.txt
- info on the kernel support for extra binary formats.
blackfin/

View file

@ -0,0 +1,560 @@
Introduction
============
BIF (Battery Interface) is a MIPI (Mobile Industry Processor Interface)
Alliance specification for a serial interface between a host device and a
battery pack. It provides a means to handle smart battery packs which can
communicate over BIF as well as low cost battery packs which provide no
serial communication interface.
The BIF bus supports 1 master and up to 256 slaves. It supports data rates
up to 250 kbps. The master is in charge of initiating all bus
communications. Slaves may only respond asynchronously when they need to
signal the master that they have an interrupt pending and when the bus is
configured for interrupt mode.
The BIF framework consists of a core into which BIF controller drivers
register. At runtime, consumers are notified of various events (e.g. battery
insertion and battery removal) via a notifier. Various framework functions are
available for consumers to read and write slave registers as well as to send
arbitrary BIF commands on the bus.
Hardware description
====================
The BIF bus is a 1-wire wired-or interface. The bus signal is referred to as
the battery communication line (BCL). The BCL is pulled high by a resistor on
the host side and is driven low when the master or one of the slaves is
communicating. Additionally, there is a pull down resistor in the battery
pack which is used to identify whether or not the battery pack has BIF slaves.
Battery removal detection is achieved by comparing the analog voltage of the BCL
when idle to the host side reference voltage. If these voltages are within a
certain threshold, then a battery pack is not present.
Slaves are addressed on the BIF bus using an 8-bit device address (DEV_ADR).
Notably, it is possible for no slaves to have defined DEV_ADR. In this case,
slave addressing is achieved via the always present unique ID (UID). The UID
of a slave is 80 bits long and guaranteed to be globally unique. A UID search
algorithm can be followed in order determine the UID of all slaves on the bus.
BIF slaves come in two varieties: primary and secondary. A single primary
slave may be present on the battery pack and a single primary slave may be
present on the host. A battery pack primary slave has DEV_ADR=0x01. The
DEV_ADR of a host primary slave is set by the manufacturer. A given primary
slave contains a list of the UIDs of all secondary slaves in the same
subsystem. This provides a fast mechanism to determine the address of all
slaves without having to resort to the lengthy UID search algorithm.
Each slave has a 64 kB address space. Part of this address space consists of
generic DDB L1 and L2 data structures at known addresses. This allows for
runtime discovery of supported battery properties and functions of a given
smart battery pack.
System Diagram:
+-------------------------------+ +---------------------------------+
| Host | | Smart Battery Pack |
| | | |
| Vbat-<+>-------<+>----------------------------+ |
| | | | |
| +--------------+ | | +--------------+ | |
| | Master BIF<+>-+---------<+>--BCL--<+>------+-<+>BIF Primary | | |
| | | | | | | | Slave | | |
| +--------------+ | | | | +--------------+ | |
| | | | | | |
| + - - - - - - -+ | | | | + - - - - - - -+ | |
| | Primary BIF<+>-+ | | +-<+>BIF Secondary| | |
| | Slave | | | | | | Slave | | |
| +- - - - - - - + | | | | +-- - - - - - -+ | |
| | | | | | |
| + - - - - - - -+ | | | | + - - - - - - -+ | |
| |Secondary BIF<+>-+ | | +-<+>BIF Secondary| | |
| |Slave | | | | | | Slave | | |
| +- - - - - - - + | | | | +-- - - - - - -+ | |
| / | | / | |
| Vref \ Rpu | | Rid \ ---- |
| ___ / | | / Battery -- |
| | \ | | \ Cell ---- |
| +-------+ | | | -- |
| | | | | |
| GND-<+>-------<+>------+---------------------+ |
| | | |
+-------------------------------+ +---------------------------------+
An overview of BIF is available at:
http://mipi.org/specifications/battery-interface
Software description
====================
A given BIF hardware interface driver registers as a BIF controller in the
BIF framework during its probe function. The controller specifies a set of
callback functions which are used by the BIF framework to initiate bus
transactions (e.g. register read, register write, wait for slave interrupt)
and to configure the bus. The framework exposes a small API to controllers
which is used to notify the framework about asynchronous events such as
battery pack insertion/removal and slave interrupts.
A given BIF consumer is linked to a BIF controller by specifying a property
in the consumer's device tree node which takes as its value the phandle of
the BIF controller's device tree node.
A consumer driver calls a get function during its probe function with its
device pointer in order to get a handle to the BIF controller if it has probed.
If it hasn't, then ERR_PTR(-EPROBE_DEFER) is returned. The controller handle
can be used directly by the consumer to issue raw bus transactions if needed.
The controller handle can then be used to query which slaves are currently
present on the bus, if any. Handles to these slaves may be used by a consumer
driver in high level framework APIs such as register read and register write
which are slave oriented. All BIF framework API functions are synchronous,
blocking, and can sleep.
Consumer drivers may also register a notifier function which is called when
certain bus activities occur such as battery pack insertion and removal.
Additionally, consumer drivers may register a notifier function which is called
when a specified slave interrupt fires.
The framework maintains several linked-lists. One list contains all controllers
that have been registered. A second list contains all slaves that have been
seen since the system booted as well as a flag to indicate if they are currently
present or not. This scheme is used to avoid issues with slave handles existing
after a slave is removed and also so that function and object values do not have
to be searched when a slave is reinserted in the system since slaves are
globally unique and these features are read-only. Two further lists are
maintained inside slave device structures which contain BIF functions and
objects found in the slave. API functions are provided so that consumers can
find functions supported by slaves.
Design
======
Design Goals:
One major goal of the BIF framework is to provide a uniform API for BIF
consumers to communicate with battery packs. This ensures that consumers are
unaffected by changes in the controller driver which actually interfaces with
the BCL at a hardware level.
Another goal of the framework is to ensure the BIF bus can be shared between
multiple consumers in a simple and functionally correct way. Locking is used
inside of the framework to provide mutual exclusion on the bus.
The framework also exposes features that almost all consumers will need, such
as BIF slave identification and BIF function enumeration within a given slave.
The framework allows consumers to issue very specific bus commands which may
not be used within high level APIs. This provides maximum flexibility so
that consumers can make use of manufacturer defined bus commands which cannot be
handled in a generic fashion.
Design Trade-offs:
The choice to not treat BIF like a traditional Linux bus was made because
there is nothing within BIF that naturally maps to a device on the bus for a
driver to manage. Slave devices would be a good candidate except that
consumers will not be managing slaves so much as functions exposed within
slaves. Bus matching could then instead be made at a BIF slave function
level. Unfortunately, the BIF specification allows for manufacturer specific
features to reside at any non-defined addresses. Additionally, consumers may
wish only to read and make policy decisions based on BIF non-volatile memory
(NVM) objects read out of memory. Thus, there are use-cases that require
consumers to utilize the bus without having a particular function to match to.
Another trade-off was the choice to use custom interrupt handling functions
instead of the Linux interrupt framework. This choice was made because there is
no obvious way to handle IRQ chip registration given the dynamic nature of BIF
slaves (i.e. slaves may come and go at runtime if battery packs are swapped).
Software layering:
BIF controller drivers register a set of callback functions with the BIF
framework which implement various BIF transaction primitives. These
callbacks ensure that tight timing constraints are met such as when receiving
a bus query response immediately after issuing a command. Such actions
cannot be carried out at the framework level as timing requirements are on
the order of 32 us when using the maximum data rate.
The BIF framework provides easy access to standard BIF features such as
slave, functions, and interrupts. The framework also ensures mutual exclusion
between different BIF consumers.
BIF consumer drivers make use of the API exposed by the framework in order
utilize functionality found on smart battery packs. One example of a
consumer driver is a temperature monitoring driver which reads the
temperature reported by the BIF temperature function on a BIF slave and
reports it to the Linux thermal framework.
Power Management
================
The framework does not perform any special actions during system suspend and
resume. Controller drivers may choose to enter low power states during
suspend if they wish as long as it does not affect the logical state of the
bus.
SMP/multi-core
==============
Various linked lists are maintained inside of the framework which are
protected by mutexes. Mutex locks are also used during transactions at a bus
level in order to ensure mutual exclusion between consumers of the bus.
Performance
===========
The BIF bus is inherently slow. Consumers should expect transactions to take
a long time to execute. Consumers are responsible for blocking suspend if
their transactions must be completed before the system enters suspend.
Interface - BIF Consumer API
============================
BIF framework structs, enums, and functions used by BIF consumers are defined in
include/linux/bif/consumer.h
Detailed descriptions of the BIF framework functions can be found in:
drivers/bif/bif-core.c
Get/put handle for a BIF controller:
------------------------------------
struct bif_ctrl *bif_ctrl_get(struct device *consumer_dev);
void bif_ctrl_put(struct bif_ctrl *ctrl);
int bif_ctrl_count(void);
struct bif_ctrl *bif_ctrl_get_by_id(unsigned int id);
The function bif_ctrl_get() is intended to be the primary way to get a consumer
BIF controller handle. It relies upon the consumer device specifying a
"qcom,bif-ctrl" property in its device tree node which points to the phandle of
the BIF controller it wishes to use.
A secondary mechanism is also provided for drivers without device tree support.
bif_ctrl_count() returns the number of BIF controllers currently registered.
bif_ctrl_get_by_id() returns a handle to the id'th controller enumerated in
registration order.
Get/put handle for a BIF slave:
-------------------------------
int bif_slave_match_count(struct bif_ctrl *ctrl,
const struct bif_match_criteria *match_criteria);
struct bif_slave *bif_slave_match_get(struct bif_ctrl *ctrl,
unsigned int id, const struct bif_match_criteria *match_criteria);
void bif_slave_put(struct bif_slave *slave);
A consumer finds a slave attached to a given BIF controller by specifying a set
of matching criteria. The criteria can include such quantities as manufacturer
ID, product ID, function type or function version. It is possible that multiple
slaves will match the criteria. bif_slave_match_count() returns how many slaves
match the specified criteria. bif_slave_match_get() returns the id'th slave
which matches the criteria in an arbitrary, but fixed order (for a constant set
of slaves). Consumer drivers need to be able to handle the case of multiple
slaves matching the criteria.
Additionally, if a battery pack is inserted or removed, then the output of
bif_slave_match_count() and bif_slave_match_get() could change. A consumer
driver can register to receive notification of battery pack insertion and
removal using the bif_ctrl_notifier_register() function listed below.
Check if slave handle is still meaningful:
------------------------------------------
int bif_slave_is_present(struct bif_slave *slave);
If a battery pack is removed, then the handles for its slaves will no longer be
meaningful. All transactions using a handle for a slave that isn't present will
fail. The function bif_slave_is_present() allows a consumer to determine if
a given slave is still physically present in the system.
Get access to the controller handle present in a slave handle:
--------------------------------------------------------------
struct bif_ctrl *bif_get_ctrl_handle(struct bif_slave *slave);
This function is useful if a consumer wishes to only store a slave handle but
also has need to call bus oriented BIF framework functions.
Get version and register offset of a BIF function if it is present in a slave:
------------------------------------------------------------------------------
int bif_slave_find_function(struct bif_slave *slave, u8 function, u8 *version,
u16 *function_pointer);
This function is used by consumers who wish to support given BIF functions
(e.g. temperature measurement, authentication, etc.) found inside of slaves.
Receive notification upon battery insertion and removal:
--------------------------------------------------------
int bif_ctrl_notifier_register(struct bif_ctrl *ctrl,
struct notifier_block *nb);
int bif_ctrl_notifier_unregister(struct bif_ctrl *ctrl,
struct notifier_block *nb);
Read or write BIF slave registers:
----------------------------------
int bif_slave_read(struct bif_slave *slave, u16 addr, u8 *buf, int len);
int bif_slave_write(struct bif_slave *slave, u16 addr, u8 *buf, int len);
BIF slave non-volatile memory manipulation:
-------------------------------------------
int bif_slave_nvm_raw_read(struct bif_slave *slave, u16 offset, u8 *buf,
int len);
int bif_slave_nvm_raw_write(struct bif_slave *slave, u16 offset, u8 *buf,
int len);
Raw NVM writing may be needed in order to intialize the NVM BIF object list.
However, its use can be dangerous as it can overwrite existing objects in the
list and make the list unparsable.
BIF object search in slave non-volatile memory:
-----------------------------------------------
int bif_object_match_count(struct bif_slave *slave,
const struct bif_obj_match_criteria *match_criteria);
struct bif_object *bif_object_match_get(struct bif_slave *slave,
unsigned int id, const struct bif_obj_match_criteria *match_criteria);
void bif_object_put(struct bif_object *object);
bif_object_match_count() and bif_object_match_get() can be used together in
order to retrieve the set of BIF objects within a slave which match certain
criteria. bif_object_put() is used to free the memory allocated by
bif_object_match_get().
BIF object manipulation in slave non-volatile memory:
-----------------------------------------------------
int bif_object_write(struct bif_slave *slave, u8 type, u8 version, u16
manufacturer_id, const u8 *data, int data_len);
int bif_object_overwrite(struct bif_slave *slave,
struct bif_object *object, u8 type, u8 version,
u16 manufacturer_id, const u8 *data, int data_len);
int bif_object_delete(struct bif_slave *slave, const struct bif_object *object);
bif_object_write() can be used to write a new BIF data object into the NVM of
a given slave. The new object is added to the end of the NVM object list.
bif_object_overwrite() can be used to overwrite an existing BIF data object
in the NVM of a slave. The new object data must be the same size as the
existing object data. bif_object_delete() can be used to delete a object from
the NVM object list and shift all of the objects after it in order to fill the
deleted object's space.
Get or set the BIF bus state or period:
---------------------------------------
int bif_ctrl_get_bus_state(struct bif_ctrl *ctrl);
int bif_ctrl_set_bus_state(struct bif_ctrl *ctrl, enum bif_bus_state state);
int bif_ctrl_get_bus_period(struct bif_ctrl *ctrl);
int bif_ctrl_set_bus_period(struct bif_ctrl *ctrl, int period_ns);
Bus states include: active for communication, active waiting for interrupt,
standby, and power down. The MIPI-BIF specification defines the allowed range
of bus periods as 2000 ns to 153000 ns. Individual controllers may further
restrict the range of allowed periods. When bif_ctrl_set_bus_period() is called
the first supported period that greater than or equal to the specified period
will be set.
Measure battery pack resistance:
--------------------------------
int bif_ctrl_measure_rid(struct bif_ctrl *ctrl);
This function returns an estimate of the battery pack resistance in ohms. If
no battery pack is connected, then the output of this function is undefined.
Utilize BIF slave tasks and interrupts:
---------------------------------------
int bif_request_irq(struct bif_slave *slave, unsigned int task,
struct notifier_block *nb);
int bif_free_irq(struct bif_slave *slave, unsigned int task,
struct notifier_block *nb);
int bif_trigger_task(struct bif_slave *slave, unsigned int task);
int bif_task_is_busy(struct bif_slave *slave, unsigned int task);
int bif_enable_auto_task(struct bif_slave *slave, unsigned int task);
int bif_disable_auto_task(struct bif_slave *slave, unsigned int task);
A consumer can request a slave interrupt and specify a notifier to call when the
interrupt is triggered. Once the interrupt is requested the consumer will need
to call bif_trigger_task() in order to start the task associated with the
interrupt (both are identified by the same index). Polling for task completion
is also supported via the bif_task_is_busy() function. Auto task triggered can
be enabled and disabled for a given task using bif_enable_auto_task() and
bif_disable_auto_task() respectively.
Raw BIF bus transactions:
-------------------------
void bif_ctrl_bus_lock(struct bif_ctrl *ctrl);
void bif_ctrl_bus_unlock(struct bif_ctrl *ctrl);
int bif_ctrl_raw_transaction(struct bif_ctrl *ctrl, int transaction, u8 data);
int bif_ctrl_raw_transaction_read(struct bif_ctrl *ctrl, int transaction,
u8 data, int *response);
int bif_ctrl_raw_transaction_query(struct bif_ctrl *ctrl, int transaction,
u8 data, bool *query_response);
int bif_slave_is_selected(struct bif_slave *slave);
int bif_slave_select(struct bif_slave *slave);
The function bif_ctrl_bus_lock() locks the BIF bus for exclusive use by the
consumer. No other transactions will be allowed on the bus including those
that would arise from battery insertion/removal or slave interrupt reception.
This lock is primarily intended to be used along with the raw transaction
functions. These functions allow a consumer to issue any BIF transaction
including manufacturer specific bus commands not handled by the BIF framework.
While performing raw transactions, features normally performed transparently by
the core, such as device selection, are not available. The functions
bif_slave_select() and bif_slave_is_selected() can be used to fill in this gap
so that raw transactions are performed on the desired slave.
Notify the BIF core that a battery has been inserted or removed:
----------------------------------------------------------------
int bif_ctrl_signal_battery_changed(struct bif_ctrl *ctrl);
This function should only be called on systems where the BIF controller driver
is architecturally unable to detect battery insertion and removal on its own.
Perform BIF object CRC using CRC-CCITT algorithm:
-------------------------------------------------
u16 bif_crc_ccitt(const u8 *buffer, int len);
Interface - BIF Controller API
==============================
BIF framework structs and functions used by BIF controllers are defined in:
include/linux/bif/driver.h
Ops found in struct bif_ctrl_ops:
---------------------------------
int (*bus_transaction) (struct bif_ctrl_dev *bdev, int transaction, u8 data);
int (*bus_transaction_query) (struct bif_ctrl_dev *bdev, int transaction,
u8 data, bool *query_response);
int (*bus_transaction_read) (struct bif_ctrl_dev *bdev, int transaction,
u8 data, int *response);
int (*read_slave_registers) (struct bif_ctrl_dev *bdev, u16 addr,
u8 *data, int len);
int (*write_slave_registers) (struct bif_ctrl_dev *bdev, u16 addr,
const u8 *data, int len);
int (*get_bus_period) (struct bif_ctrl_dev *bdev);
int (*set_bus_period) (struct bif_ctrl_dev *bdev, int period_ns);
int (*get_battery_presence) (struct bif_ctrl_dev *bdev);
int (*get_battery_rid) (struct bif_ctrl_dev *bdev);
int (*get_bus_state) (struct bif_ctrl_dev *bdev);
int (*set_bus_state) (struct bif_ctrl_dev *bdev, int state);
A BIF controller driver registers a set of call back functions which instantiate
these ops. The BIF framework then calls these functions based on internal and
consumer needs.
The ops bus_transaction(), bus_transaction_query(), and bus_transaction_read()
carry out the controller hardware specific actions to perform BIF transactions
on the BIF bus. These transactions result in no slave response, a pulse in
response, or a word in response respectively. The ops read_slave_registers()
and write_slave_registers() internally must perform all transactions necessary
to read and write to BIF slave registers. These ops exist so that burst reads
and writes can take place since these activities have very tight timing
constraints that the BIF core cannot handle.
The ops get_bus_period() and set_bus_period() return the current bus clock base
period in nanoseconds and change the period to a new value respectively. The
ops get_bus_state() and set_bus_state() allow for monitoring and controlling the
bus state (i.e. active for communication, active waiting for interrupt, standby,
or power down). The op get_battery_presence() returns if any battery pack
(smart or low cost) is currently connected to the BCL. The op get_battery_rid()
returns a best estimate of the Rid battery pack pull down ID resistance in ohms
which can be used to determine if the battery pack is smart or low cost.
Register/unregister a BIF controller:
-------------------------------------
struct bif_ctrl_dev *bif_ctrl_register(struct bif_ctrl_desc *bif_desc,
struct device *dev, void *driver_data, struct device_node *of_node);
void bif_ctrl_unregister(struct bif_ctrl_dev *bdev);
Notify the BIF framework that a battery has been inserted or removed:
---------------------------------------------------------------------
int bif_ctrl_notify_battery_changed(struct bif_ctrl_dev *bdev);
The BIF core will then call the get_battery_presence() op internally to
determine if the event is an insertion or removal.
Notify the BIF framework that a slave interrupt has been received:
------------------------------------------------------------------
int bif_ctrl_notify_slave_irq(struct bif_ctrl_dev *bdev);
Upon receiving this call, the BIF core interrogates each slave to determine
which slaves have pending interrupts. It then iterates through all interrupts
on those slaves clearing all pending interrupts and notifying any consumers
waiting for the interrupts.
Get BIF controller private data:
--------------------------------
void *bdev_get_drvdata(struct bif_ctrl_dev *bdev);
Config options
==============
CONFIG_BIF - Enables BIF framework support.
User space utilities
====================
No user space interface is provided in the BIF framework. Therefore, user
space will not be able to directly use it.
To do
=====
It is conceivable that the BIF framework should take some action during
system suspend and resume. However, it is not clear exactly what should be
done given that the BCL would still need to be active in order to detect
battery removal while suspended.
sysfs nodes could be added which describe slaves as well as functions and
objects within the slaves. However these nodes would be read-only and would
really only be useful for descriptive as opposed to control purposes.
The exact time at which slave searching, function enumeration, and object
loading takes place could be optimized in order to improve performance to
some degree. It could also be made configurable at a controller level if
needed.

View file

@ -0,0 +1,22 @@
BIF (Battery Interface) Controllers
Optional properties:
- qcom,known-device-addresses: Specifies a list of integers which correspond to
the 8-bit BIF bus device addresses of BIF slaves
found on the target.
BIF Consumers
Optional properties:
- qcom,bif-ctrl: phandle of parent BIF controller device node
Example:
foo_ctrl: foo-controller {
...
qcom,known-device-addresses = <0x80, 0x81>;
};
bar-consumer {
...
qcom,bif-ctrl = <&foo_ctrl>;
};

View file

@ -0,0 +1,93 @@
Qualcomm QPNP BSI - battery serial interface devices
qpnp-bsi is a BIF driver which supports the BSI peripheral inside of PMICs
that utilize the MSM SPMI implementation.
Required properties:
- compatible: Must be "qcom,qpnp-bsi".
- reg: Specifies the SPMI address and size for this BSI device as
well as the address of the BATT_ID status register.
- reg-names: A list of strings identifying the reg property entries. The
list must contain both "bsi-base" and "batt-id-status".
- label: A string used as a descriptive name for this BIF controller.
- interrupts: Specifies a list of four interrupts corresponding to
IRQ ERR, IRQ RX, IRQ TX, and IRQ BATT_PRESENT in any order.
- interrupt-names: Must be a list of strings containing all three of these
strings: "err", "rx", "tx", "batt-present". The ordering of
these strings must match the ordering of the interrupts in
the "interrupts" property.
Required structure:
- A qcom,qpnp-bsi node must be a child of an SPMI node that has specified the
spmi-slave-container property.
Optional properties:
- qcom,min-clock-period: This property specifies a minimum clock period for the
Tau BIF reference in nanoseconds. It can be used to
impose a minimum period which is higher (i.e. more
restrictive) than that supported by the hardware.
The BSI module supports 8 possible periods between
2080 ns and 150420 ns.
- qcom,max-clock-period: This property specifies a maximum clock period for the
Tau BIF reference in nanoseconds. It can be used to
impose a maximum period which is lower (i.e. more
restrictive) than that supported by the hardware.
The BSI module supports 8 possible periods between
2080 ns and 150420 ns.
- qcom,sample-rate: Specifies the rate at which the BIF BCL should be
sampled during communication with respect to the Tau
BIF reference rate. Supported values are 4 and 8
which represent 4x and 8x sampling rates
respectively. If this property is not specified,
then 4x sampling is assumed.
- qcom,channel-num: VADC channel number associated PMIC BATT_ID pin. If
no channel is specified, then it will not be
possible to measure the slave Rid.
- qcom,pullup-ohms: Host side pull-up resistance present on BCL in ohms.
If no value is specified, then 100000 ohms is
assumed.
- qcom,vref-microvolts: Reference voltage used for BCL divider circuit in
microvolts. If no value is specified, then
1800000 uV is assumed.
- qcom,bsi-vadc: Corresponding VADC device phandle.
All properties specified within for the BIF framework can also be used. These
properties can be found in bif.txt.
Example:
qcom,spmi@fc4c0000 {
#address-cells = <1>;
#size-cells = <0>;
interrupt-controller;
#interrupt-cells = <3>;
qcom,pm8941@1 {
spmi-slave-container;
reg = <0x1>;
#address-cells = <1>;
#size-cells = <1>;
qcom,bsi@1b00 {
compatible = "qcom,qpnp-bsi";
reg = <0x1b00 0x100>,
<0x1208 0x1>;
reg-names = "bsi-base", "batt-id-status";
label = "pm8941-bsi";
interrupts = <0x0 0x1b 0x0>,
<0x0 0x1b 0x1>,
<0x0 0x1b 0x2>,
<0x0 0x12 0x0>;
interrupt-names = "err",
"rx",
"tx",
"batt-present";
qcom,sample-rate = <8>;
qcom,min-clock-period = <15830>;
qcom,max-clock-period = <122080>;
qcom,channel-num = <0x31>;
qcom,pullup-ohms = <100000>;
qcom,vref-microvolts = <1800000>;
qcom,bsi-vadc = <&pm8941_vadc>;
};
};
};

View file

@ -200,4 +200,6 @@ source "drivers/hwtracing/intel_th/Kconfig"
source "drivers/fpga/Kconfig"
source "drivers/bif/Kconfig"
endmenu

View file

@ -173,3 +173,5 @@ obj-$(CONFIG_STM) += hwtracing/stm/
obj-$(CONFIG_ANDROID) += android/
obj-$(CONFIG_NVMEM) += nvmem/
obj-$(CONFIG_FPGA) += fpga/
obj-$(CONFIG_BIF) += bif/

26
drivers/bif/Kconfig Normal file
View file

@ -0,0 +1,26 @@
#
# BIF framework and drivers
#
menuconfig BIF
bool "MIPI-BIF support"
select CRC_CCITT
select BITREVERSE
help
MIPI-BIF (battery interface) is a one-wire serial interface between a
host master device and one or more slave devices which are located in
a battery pack or also on the host. Enabling this option allows for
BIF consumer drivers to issue transactions via BIF controller drivers.
if BIF
config BIF_QPNP
depends on SPMI || MSM_SPMI
depends on OF_SPMI
tristate "Qualcomm QPNP BIF support"
help
This driver supports the QPNP BSI peripheral found inside of Qualcomm
QPNP PMIC devices. The BSI peripheral is able to communicate using
the BIF protocol. The QPNP BSI driver hooks into the BIF framework.
Enable this option in order to provide support for BIF communication
on targets which have BSI PMIC peripherals.
endif

5
drivers/bif/Makefile Normal file
View file

@ -0,0 +1,5 @@
#
# Makefile for kernel BIF framework.
#
obj-$(CONFIG_BIF) += bif-core.o
obj-$(CONFIG_BIF_QPNP) += qpnp-bsi.o

3841
drivers/bif/bif-core.c Normal file

File diff suppressed because it is too large Load diff

1783
drivers/bif/qpnp-bsi.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,728 @@
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _LINUX_BIF_CONSUMER_H_
#define _LINUX_BIF_CONSUMER_H_
#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/notifier.h>
#define BIF_DEVICE_ID_BYTE_LENGTH 8
#define BIF_UNIQUE_ID_BYTE_LENGTH 10
#define BIF_UNIQUE_ID_BIT_LENGTH 80
#define BIF_PRIMARY_SLAVE_DEV_ADR 0x01
/**
* enum bif_transaction - BIF master bus transaction types
* %BIF_TRANS_WD: Write data
* %BIF_TRANS_ERA: Extended register address
* %BIF_TRANS_WRA: Write register address
* %BIF_TRANS_RRA: Read register address
* %BIF_TRANS_BC: Bus command
* %BIF_TRANS_EDA: Extended device address
* %BIF_TRANS_SDA: Slave device address
*
* These values correspond to BIF word bits: BCF, bit 9, bit 8.
* BCF_n bit is inserted automatically.
*/
enum bif_transaction {
BIF_TRANS_WD = 0x00,
BIF_TRANS_ERA = 0x01,
BIF_TRANS_WRA = 0x02,
BIF_TRANS_RRA = 0x03,
BIF_TRANS_BC = 0x04,
BIF_TRANS_EDA = 0x05,
BIF_TRANS_SDA = 0x06,
};
/* BIF slave response components */
#define BIF_SLAVE_RD_ACK 0x200
#define BIF_SLAVE_RD_EOT 0x100
#define BIF_SLAVE_RD_DATA 0x0FF
#define BIF_SLAVE_RD_ERR 0x0FF
#define BIF_SLAVE_TACK_ACK 0x200
#define BIF_SLAVE_TACK_WCNT 0x0FF
#define BIF_SLAVE_TACK_ERR 0x0FF
/**
* enum bif_bus_command - MIPI defined bus commands to use in BC transaction
* %BIF_CMD_BRES: Bus reset of all slaves
* %BIF_CMD_PDWN: Put all slaves into power down mode
* %BIF_CMD_STBY: Put all slaves into standby mode
* %BIF_CMD_EINT: Enable interrupts for all slaves
* %BIF_CMD_ISTS: Poll interrupt status for all slaves. Expects BQ
* response if any slave has a pending interrupt.
* %BIF_CMD_RBL: Specify the burst read length for the next read
* transaction. Bits 3 to 0 should also be ORed on in
* order to specify the number of bytes to read.
* %BIF_CMD_RBE: Specify the extended burst read length for the next read
* transaction. Bits 3 to 0 should also be ORed on in
* order to specify the number of bytes to read. The burst
* read length for RBEy and RBLx = 16 * y + x.
* %BIF_CMD_DASM: Device activation stick mode. This keeps a slave
* selected if it would otherwise become unselected by the
* next transaction.
* %BIF_CMD_DISS: UID search start
* %BIF_CMD_DILC: UID length check. Expects BQ response if all 80 UID
* bits for a given slave have been entered.
* %BIF_CMD_DIE0: UID search enter 0
* %BIF_CMD_DIE1: UID search enter 1
* %BIF_CMD_DIP0: UID search probe 0
* %BIF_CMD_DIP1: UID search probe 1
* %BIF_CMD_DRES: Device reset of selected slaves
* %BIF_CMD_TQ: Transaction query; expects TACK response
* %BIF_CMD_AIO: Address increment off for the next transaction
*
* These values correspond to BIF word bits 7 to 0.
*/
enum bif_bus_command {
BIF_CMD_BRES = 0x00,
BIF_CMD_PDWN = 0x02,
BIF_CMD_STBY = 0x03,
BIF_CMD_EINT = 0x10,
BIF_CMD_ISTS = 0x11,
BIF_CMD_RBL = 0x20,
BIF_CMD_RBE = 0x30,
BIF_CMD_DASM = 0x40,
BIF_CMD_DISS = 0x80,
BIF_CMD_DILC = 0x81,
BIF_CMD_DIE0 = 0x84,
BIF_CMD_DIE1 = 0x85,
BIF_CMD_DIP0 = 0x86,
BIF_CMD_DIP1 = 0x87,
BIF_CMD_DRES = 0xC0,
BIF_CMD_TQ = 0xC2,
BIF_CMD_AIO = 0xC4,
};
/**
* struct bif_ddb_l1_data - MIPI defined L1 DDB data structure
* @revision: DDB version; should be 0x10 for DDB v1.0
* @level: DDB level support; should be 0x03 for DDB L1 and L2
* @device_class: MIPI device class; should be 0x0800
* @manufacturer_id: Manufacturer ID number allocated by MIPI
* @product_id: Manufacturer specified product ID number
* @length: Size of L2 function directory in bytes
*/
struct bif_ddb_l1_data {
u8 revision;
u8 level;
u16 device_class;
u16 manufacturer_id;
u16 product_id;
u16 length;
};
/**
* struct bif_ddb_l2_data - MIPI defined L2 DDB function data structure
* @function_type: Defines the type of the function. The type may be
* either MIPI or manufacturer defined.
* @function_version: Defines the version of the function. The version may
* be either MIPI or manufacturer defined.
* @function_pointer: Address in BIF slave memory where the register map for
* the function begins.
*/
struct bif_ddb_l2_data {
u8 function_type;
u8 function_version;
u16 function_pointer;
};
/**
* enum bif_mipi_function_type - MIPI defined DDB L2 function types
* %BIF_FUNC_PROTOCOL: Protocol function which provides access to core
* BIF communication features.
* %BIF_FUNC_SLAVE_CONTROL: Slave control function which provides control
* for BIF slave interrupts and tasks.
* %BIF_FUNC_TEMPERATURE: Temperature sensor function which provides a
* means to accurately read the battery temperature
* in a single-shot or periodic fashion.
* %BIF_FUNC_NVM: Non-volatile memory function which provides a
* means to store data onto a BIF slave that is
* non-volatile. Secondary slave objects are also
* found through the NVM function.
* %BIF_FUNC_AUTHENTICATION: Authentication function which provides a means
* to authenticate batteries. This function does
* not have a MIPI defined implimentation. Instead
* all aspects of the authentication function are
* left to the discretion of the manufacturer.
*/
enum bif_mipi_function_type {
BIF_FUNC_PROTOCOL = 0x01,
BIF_FUNC_SLAVE_CONTROL = 0x02,
BIF_FUNC_TEMPERATURE = 0x03,
BIF_FUNC_NVM = 0x04,
BIF_FUNC_AUTHENTICATION = 0x05,
};
#define BIF_DDB_L1_BASE_ADDR 0x0000
#define BIF_DDB_L2_BASE_ADDR 0x000A
/**
* enum bif_slave_error_code - MIPI defined BIF slave error codes
* %BIF_ERR_NONE: No error occurred
* %BIF_ERR_GENERAL: An unenumerated error occurred
* %BIF_ERR_PARITY: A Hamming-15 parity check failed for a word
* sent on the bus
* %BIF_ERR_INVERSION: More than 8 bits in a word were 1
* %BIF_ERR_BAD_LENGTH: Word had more or less than 17 bits
* %BIF_ERR_TIMING: Bit timing was violated in a word
* %BIF_ERR_UNKNOWN_CMD: Bus command was unknown to the slave
* %BIF_ERR_CMD_SEQ: Commands with ordering dependency were not
* sent in the right order
* %BIF_ERR_BUS_COLLISION: BCL was already low at the beginning of a new
* transaction
* %BIF_ERR_SLAVE_BUSY: Slave is busy and cannot respond
* %BIF_ERR_FATAL: Slave is in an unrecoverable error state and
* must be reset
*
* These values are present in the ERR portion of an RD or TACK slave response
* word. These values can also be found in the ERR_CODE register of the
* protocol function.
*/
enum bif_slave_error_code {
BIF_ERR_NONE = 0x00,
BIF_ERR_GENERAL = 0x10,
BIF_ERR_PARITY = 0x11,
BIF_ERR_INVERSION = 0x12,
BIF_ERR_BAD_LENGTH = 0x13,
BIF_ERR_TIMING = 0x14,
BIF_ERR_UNKNOWN_CMD = 0x15,
BIF_ERR_CMD_SEQ = 0x16,
BIF_ERR_BUS_COLLISION = 0x1F,
BIF_ERR_SLAVE_BUSY = 0x20,
BIF_ERR_FATAL = 0x7F,
};
/**
* struct bif_protocol_function - constant data present in protocol function
* @l2_entry: Pointer to protocol function L2 DDB data struct
* @protocol_pointer: BIF slave address where protocol registers begin
* @device_id_pointer: BIF slave address where device ID begins
* @device_id: The 8-byte unique device ID in MSB to LSB order
*/
struct bif_protocol_function {
struct bif_ddb_l2_data *l2_entry;
u16 protocol_pointer;
u16 device_id_pointer;
u8 device_id[BIF_DEVICE_ID_BYTE_LENGTH]; /* Unique ID */
};
#define PROTOCOL_FUNC_DEV_ADR_ADDR(protocol_pointer) ((protocol_pointer) + 0)
#define PROTOCOL_FUNC_ERR_CODE_ADDR(protocol_pointer) ((protocol_pointer) + 2)
#define PROTOCOL_FUNC_ERR_CNT_ADDR(protocol_pointer) ((protocol_pointer) + 3)
#define PROTOCOL_FUNC_WORD_CNT_ADDR(protocol_pointer) ((protocol_pointer) + 4)
/**
* struct bif_slave_control_function - constant data present in slave control
* function as well internal software state parameters
* @l2_entry: Pointer to slave control function L2 DDB data struct
* @slave_ctrl_pointer: BIF slave address where slave control registers begin
* @task_count: Number of tasks supported by the slave
* @irq_notifier_list: List of notifiers for consumers drivers that wish to be
* notified when any given interrupt triggers. This list
* is dynamically allocated with length task_count.
*/
struct bif_slave_control_function {
struct bif_ddb_l2_data *l2_entry;
u16 slave_ctrl_pointer;
unsigned int task_count;
struct blocking_notifier_head *irq_notifier_list;
};
#define SLAVE_CTRL_TASKS_PER_SET 8
/**
* bif_slave_control_task_is_valid() - returns true if the specified task
* is supported by the slave or false if it isn't
* @func: Pointer to slave's slave control function structure
* @task: Slave task number to check
*/
static inline bool
bif_slave_control_task_is_valid(struct bif_slave_control_function *func,
unsigned int task)
{
return func ? task < func->task_count : false;
}
#define SLAVE_CTRL_FUNC_IRQ_EN_ADDR(slave_ctrl_pointer, task) \
((slave_ctrl_pointer) + 4 * ((task) / SLAVE_CTRL_TASKS_PER_SET) + 0)
#define SLAVE_CTRL_FUNC_IRQ_STATUS_ADDR(slave_ctrl_pointer, task) \
((slave_ctrl_pointer) + 4 * ((task) / SLAVE_CTRL_TASKS_PER_SET) + 1)
#define SLAVE_CTRL_FUNC_IRQ_CLEAR_ADDR(slave_ctrl_pointer, task) \
SLAVE_CTRL_FUNC_IRQ_STATUS_ADDR(slave_ctrl_pointer, task)
#define SLAVE_CTRL_FUNC_TASK_TRIGGER_ADDR(slave_ctrl_pointer, task) \
((slave_ctrl_pointer) + 4 * ((task) / SLAVE_CTRL_TASKS_PER_SET) + 2)
#define SLAVE_CTRL_FUNC_TASK_BUSY_ADDR(slave_ctrl_pointer, task) \
SLAVE_CTRL_FUNC_TASK_TRIGGER_ADDR(slave_ctrl_pointer, task)
#define SLAVE_CTRL_FUNC_TASK_AUTO_TRIGGER_ADDR(slave_ctrl_pointer, task) \
((slave_ctrl_pointer) + 4 * ((task) / SLAVE_CTRL_TASKS_PER_SET) + 3)
/**
* struct bif_temperature_function - constant data present in temperature
* sensor function
* @temperatuer_pointer: BIF slave address where temperature sensor
* control registers begin
* @slave_control_channel: Slave control channel associated with the
* temperature sensor function. This channel is
* also the task number.
* @accuracy_pointer: BIF slave address where temperature accuracy
* registers begin
*/
struct bif_temperature_function {
u16 temperature_pointer;
u8 slave_control_channel;
u16 accuracy_pointer;
};
/**
* enum bif_mipi_object_type - MIPI defined BIF object types
* %BIF_OBJ_END_OF_LIST: Indicates that the end of the object list in
* NVM has been reached
* %BIF_OBJ_SEC_SLAVE: Specifies the UIDs of secondary slaves found
* inside of the battery pack
* %BIF_OBJ_BATT_PARAM: Specifies some variety of battery parameter.
* There is no MIPI defined format for this object
* type so parsing is manufacturer specific.
*/
enum bif_mipi_object_type {
BIF_OBJ_END_OF_LIST = 0x00,
BIF_OBJ_SEC_SLAVE = 0x01,
BIF_OBJ_BATT_PARAM = 0x02,
};
/**
* struct bif_object - contains all header and data information for a slave
* data object
* @type: Object type
* @version: Object version
* @manufacturer_id: Manufacturer ID number allocated by MIPI
* @length: Length of the entire object including header and CRC;
* data length == total length - 8.
* @data: Raw byte data found in the object
* @crc: CRC of the object calculated using CRC-CCITT
* @list: Linked-list connection parameter; internal use only
* @addr: BIF slave address correspond to the start of the object
*
* manufacturer_id == 0x0000 if MIPI type and version.
*/
struct bif_object {
u8 type;
u8 version;
u16 manufacturer_id;
u16 length;
u8 *data;
u16 crc;
struct list_head list;
u16 addr;
};
/**
* struct bif_nvm_function - constant data present in non-volatile memory
* function as well internal software state
* parameters
* @nvm_pointer: BIF slave address where NVM registers begin
* @slave_control_channel: Slave control channel associated with the
* NVM function. This channel is also the task
* number.
* @write_buffer_size: Size in bytes of the NVM write buffer. 0x00
* is used to denote a 256 byte buffer.
* @nvm_base_address: BIF slave address where NVM begins
* @nvm_size: NVM size in bytes
* @nvm_lock_offset: Offset from the beginning of NVM of the first
* writable address
* @object_count: Number of BIF objects read from NVM
* @object_list: List of BIF objects read from NVM
*/
struct bif_nvm_function {
u16 nvm_pointer;
u8 slave_control_channel;
u8 write_buffer_size;
u16 nvm_base_address;
u16 nvm_size;
u16 nvm_lock_offset;
int object_count;
struct list_head object_list;
};
/**
* struct bif_ctrl - Opaque handle for a BIF controller to be used in bus
* oriented BIF function calls.
*/
struct bif_ctrl;
/**
* struct bif_slave - Opaque handle for a BIF slave to be used in slave oriented
* BIF function calls.
*/
struct bif_slave;
/**
* enum bif_bus_state - indicates the current or desired state of the BIF bus
* %BIF_BUS_STATE_MASTER_DISABLED: BIF host hardware is disabled
* %BIF_BUS_STATE_POWER_DOWN: BIF bus is in power down state and
* BCL is not being pulled high
* %BIF_BUS_STATE_STANDBY: BIF slaves are in standby state in which
* less power is drawn
* %BIF_BUS_STATE_ACTIVE: BIF slaves are ready for immediate
* communications
* %BIF_BUS_STATE_INTERRUPT: BIF bus is active, but no communication
* is possible. Instead, either one of the
* slaves or the master must transition to
* active state by pulling BCL low for 1
* tau bif period.
*/
enum bif_bus_state {
BIF_BUS_STATE_MASTER_DISABLED,
BIF_BUS_STATE_POWER_DOWN,
BIF_BUS_STATE_STANDBY,
BIF_BUS_STATE_ACTIVE,
BIF_BUS_STATE_INTERRUPT,
};
/**
* enum bif_bus_event - events that the BIF framework may send to BIF consumers
* %BIF_BUS_EVENT_BATTERY_INSERTED: Indicates that a battery was just
* inserted physically or that the BIF
* host controller for the battery just
* probed and a battery was already
* present.
* %BIF_BUS_EVENT_BATTERY_REMOVED: Indicates that a battery was just
* removed and thus its slaves are no
* longer accessible.
*/
enum bif_bus_event {
BIF_BUS_EVENT_BATTERY_INSERTED,
BIF_BUS_EVENT_BATTERY_REMOVED,
};
/* Mask values to be ORed together for use in bif_match_criteria.match_mask. */
#define BIF_MATCH_MANUFACTURER_ID BIT(0)
#define BIF_MATCH_PRODUCT_ID BIT(1)
#define BIF_MATCH_FUNCTION_TYPE BIT(2)
#define BIF_MATCH_FUNCTION_VERSION BIT(3)
#define BIF_MATCH_IGNORE_PRESENCE BIT(4)
#define BIF_MATCH_OBJ_TYPE BIT(5)
#define BIF_MATCH_OBJ_VERSION BIT(6)
#define BIF_MATCH_OBJ_MANUFACTURER_ID BIT(7)
/**
* struct bif_match_criteria - specifies the matching criteria that a BIF
* consumer uses to find an appropriate BIF slave
* @match_mask: Mask value specifying which parameters to match upon.
* This value should be some ORed combination of
* BIF_MATCH_* specified above.
* @manufacturer_id: Manufacturer ID number allocated by MIPI
* @product_id: Manufacturer specified product ID number
* @function_type: Defines the type of the function. The type may be
* either MIPI or manufacturer defined.
* @function_version: Defines the version of the function. The version may
* be either MIPI or manufacturer defined.
* @ignore_presence: If true, then slaves that are currently not present
* will be successfully matched against. By default, only
* present slaves can be matched.
* @obj_type: Defines the type of a BIF object found in the
* non-volatile memory of a slave.
* @obj_version: Defines the version of a BIF object found in the
* non-volatile memory of a slave.
* @obj_manufacturer_id: Manufacturer ID of a BIF object found in the
* non-volatile memory of a slave.
*
* If function_type and function_verion are both specified, then they must both
* match for a single BIF function. If obj_type and obj_version or
* obj_manufacturer_id are specified, then all must match for a single BIF
* object.
*/
struct bif_match_criteria {
u32 match_mask;
u16 manufacturer_id;
u16 product_id;
u8 function_type;
u8 function_version;
bool ignore_presence;
u8 obj_type;
u8 obj_version;
u16 obj_manufacturer_id;
};
/* Mask values to be ORed for use in bif_obj_match_criteria.match_mask. */
#define BIF_OBJ_MATCH_TYPE BIT(0)
#define BIF_OBJ_MATCH_VERSION BIT(1)
#define BIF_OBJ_MATCH_MANUFACTURER_ID BIT(2)
/**
* struct bif_obj_match_criteria - specifies the matching criteria that a BIF
* consumer uses to find an appropriate BIF data object
* within a slave
* @match_mask: Mask value specifying which parameters to match upon.
* This value should be some ORed combination of
* BIF_OBJ_MATCH_* specified above.
* @type: Defines the type of the object. The type may be either
* MIPI or manufacturer defined.
* @version: Defines the version of the object. The version may be
* either MIPI or manufacturer defined.
* @manufacturer_id: Manufacturer ID number allocated by MIPI.
*/
struct bif_obj_match_criteria {
u32 match_mask;
u8 type;
u8 version;
u16 manufacturer_id;
};
/**
* bif_battery_rid_ranges - MIPI-BIF defined Rid battery pack resistance ranges
* %BIF_BATT_RID_SPECIAL1_MIN: Minimum Rid for special case 1
* %BIF_BATT_RID_SPECIAL1_MAX: Maximum Rid for special case 1
* %BIF_BATT_RID_SPECIAL2_MIN: Minimum Rid for special case 2
* %BIF_BATT_RID_SPECIAL2_MAX: Maximum Rid for special case 2
* %BIF_BATT_RID_SPECIAL3_MIN: Minimum Rid for special case 3
* %BIF_BATT_RID_SPECIAL3_MAX: Maximum Rid for special case 3
* %BIF_BATT_RID_LOW_COST_MIN: Minimum Rid for a low cost battery pack
* %BIF_BATT_RID_LOW_COST_MAX: Maximum Rid for a low cost battery pack
* %BIF_BATT_RID_SMART_MIN: Minimum Rid for a smart battery pack
* %BIF_BATT_RID_SMART_MAX: Maximum Rid for a smart battery pack
*/
enum bif_battery_rid_ranges {
BIF_BATT_RID_SPECIAL1_MIN = 0,
BIF_BATT_RID_SPECIAL1_MAX = 1,
BIF_BATT_RID_SPECIAL2_MIN = 7350,
BIF_BATT_RID_SPECIAL2_MAX = 7650,
BIF_BATT_RID_SPECIAL3_MIN = 12740,
BIF_BATT_RID_SPECIAL3_MAX = 13260,
BIF_BATT_RID_LOW_COST_MIN = 19600,
BIF_BATT_RID_LOW_COST_MAX = 140000,
BIF_BATT_RID_SMART_MIN = 240000,
BIF_BATT_RID_SMART_MAX = 450000,
};
#ifdef CONFIG_BIF
int bif_request_irq(struct bif_slave *slave, unsigned int task,
struct notifier_block *nb);
int bif_free_irq(struct bif_slave *slave, unsigned int task,
struct notifier_block *nb);
int bif_trigger_task(struct bif_slave *slave, unsigned int task);
int bif_enable_auto_task(struct bif_slave *slave, unsigned int task);
int bif_disable_auto_task(struct bif_slave *slave, unsigned int task);
int bif_task_is_busy(struct bif_slave *slave, unsigned int task);
int bif_ctrl_count(void);
struct bif_ctrl *bif_ctrl_get_by_id(unsigned int id);
struct bif_ctrl *bif_ctrl_get(struct device *consumer_dev);
void bif_ctrl_put(struct bif_ctrl *ctrl);
int bif_ctrl_signal_battery_changed(struct bif_ctrl *ctrl);
int bif_slave_match_count(struct bif_ctrl *ctrl,
const struct bif_match_criteria *match_criteria);
struct bif_slave *bif_slave_match_get(struct bif_ctrl *ctrl,
unsigned int id, const struct bif_match_criteria *match_criteria);
void bif_slave_put(struct bif_slave *slave);
int bif_ctrl_notifier_register(struct bif_ctrl *ctrl,
struct notifier_block *nb);
int bif_ctrl_notifier_unregister(struct bif_ctrl *ctrl,
struct notifier_block *nb);
struct bif_ctrl *bif_get_ctrl_handle(struct bif_slave *slave);
int bif_slave_find_function(struct bif_slave *slave, u8 function, u8 *version,
u16 *function_pointer);
int bif_object_match_count(struct bif_slave *slave,
const struct bif_obj_match_criteria *match_criteria);
struct bif_object *bif_object_match_get(struct bif_slave *slave,
unsigned int id, const struct bif_obj_match_criteria *match_criteria);
void bif_object_put(struct bif_object *object);
int bif_slave_read(struct bif_slave *slave, u16 addr, u8 *buf, int len);
int bif_slave_write(struct bif_slave *slave, u16 addr, u8 *buf, int len);
int bif_slave_nvm_raw_read(struct bif_slave *slave, u16 offset, u8 *buf,
int len);
int bif_slave_nvm_raw_write(struct bif_slave *slave, u16 offset, u8 *buf,
int len);
int bif_object_write(struct bif_slave *slave, u8 type, u8 version, u16
manufacturer_id, const u8 *data, int data_len);
int bif_object_overwrite(struct bif_slave *slave,
struct bif_object *object, u8 type, u8 version,
u16 manufacturer_id, const u8 *data, int data_len);
int bif_object_delete(struct bif_slave *slave, const struct bif_object *object);
int bif_slave_is_present(struct bif_slave *slave);
int bif_slave_is_selected(struct bif_slave *slave);
int bif_slave_select(struct bif_slave *slave);
int bif_ctrl_raw_transaction(struct bif_ctrl *ctrl, int transaction, u8 data);
int bif_ctrl_raw_transaction_read(struct bif_ctrl *ctrl, int transaction,
u8 data, int *response);
int bif_ctrl_raw_transaction_query(struct bif_ctrl *ctrl, int transaction,
u8 data, bool *query_response);
void bif_ctrl_bus_lock(struct bif_ctrl *ctrl);
void bif_ctrl_bus_unlock(struct bif_ctrl *ctrl);
u16 bif_crc_ccitt(const u8 *buffer, unsigned int len);
int bif_ctrl_measure_rid(struct bif_ctrl *ctrl);
int bif_ctrl_get_bus_period(struct bif_ctrl *ctrl);
int bif_ctrl_set_bus_period(struct bif_ctrl *ctrl, int period_ns);
int bif_ctrl_get_bus_state(struct bif_ctrl *ctrl);
int bif_ctrl_set_bus_state(struct bif_ctrl *ctrl, enum bif_bus_state state);
#else
static inline int bif_request_irq(struct bif_slave *slave, unsigned int task,
struct notifier_block *nb) { return -EPERM; }
static inline int bif_free_irq(struct bif_slave *slave, unsigned int task,
struct notifier_block *nb) { return -EPERM; }
static inline int bif_trigger_task(struct bif_slave *slave, unsigned int task)
{ return -EPERM; }
static inline int bif_enable_auto_task(struct bif_slave *slave,
unsigned int task)
{ return -EPERM; }
static inline int bif_disable_auto_task(struct bif_slave *slave,
unsigned int task)
{ return -EPERM; }
static inline int bif_task_is_busy(struct bif_slave *slave, unsigned int task)
{ return -EPERM; }
static inline int bif_ctrl_count(void) { return -EPERM; }
static inline struct bif_ctrl *bif_ctrl_get_by_id(unsigned int id)
{ return ERR_PTR(-EPERM); }
struct bif_ctrl *bif_ctrl_get(struct device *consumer_dev)
{ return ERR_PTR(-EPERM); }
static inline void bif_ctrl_put(struct bif_ctrl *ctrl) { return; }
static inline int bif_ctrl_signal_battery_changed(struct bif_ctrl *ctrl)
{ return -EPERM; }
static inline int bif_slave_match_count(struct bif_ctrl *ctrl,
const struct bif_match_criteria *match_criteria)
{ return -EPERM; }
static inline struct bif_slave *bif_slave_match_get(struct bif_ctrl *ctrl,
unsigned int id, const struct bif_match_criteria *match_criteria)
{ return ERR_PTR(-EPERM); }
static inline void bif_slave_put(struct bif_slave *slave) { return; }
static inline int bif_ctrl_notifier_register(struct bif_ctrl *ctrl,
struct notifier_block *nb)
{ return -EPERM; }
static inline int bif_ctrl_notifier_unregister(struct bif_ctrl *ctrl,
struct notifier_block *nb)
{ return -EPERM; }
static inline struct bif_ctrl *bif_get_ctrl_handle(struct bif_slave *slave)
{ return ERR_PTR(-EPERM); }
static inline int bif_slave_find_function(struct bif_slave *slave, u8 function,
u8 *version, u16 *function_pointer)
{ return -EPERM; }
static inline int bif_object_match_count(struct bif_slave *slave,
const struct bif_obj_match_criteria *match_criteria)
{ return -EPERM; }
static inline struct bif_object *bif_object_match_get(struct bif_slave *slave,
unsigned int id, const struct bif_obj_match_criteria *match_criteria)
{ return ERR_PTR(-EPERM); }
static inline void bif_object_put(struct bif_object *object)
{}
static inline int bif_slave_read(struct bif_slave *slave, u16 addr, u8 *buf,
int len)
{ return -EPERM; }
static inline int bif_slave_write(struct bif_slave *slave, u16 addr, u8 *buf,
int len)
{ return -EPERM; }
static inline int bif_slave_nvm_raw_read(struct bif_slave *slave, u16 offset,
u8 *buf, int len)
{ return -EPERM; }
static inline int bif_slave_nvm_raw_write(struct bif_slave *slave, u16 offset,
u8 *buf, int len)
{ return -EPERM; }
static inline int bif_object_write(struct bif_slave *slave, u8 type, u8 version,
u16 manufacturer_id, const u8 *data, int data_len)
{ return -EPERM; }
static inline int bif_object_overwrite(struct bif_slave *slave,
struct bif_object *object, u8 type, u8 version,
u16 manufacturer_id, const u8 *data, int data_len)
{ return -EPERM; }
static inline int bif_object_delete(struct bif_slave *slave,
const struct bif_object *object)
{ return -EPERM; }
static inline int bif_slave_is_present(struct bif_slave *slave)
{ return -EPERM; }
static inline int bif_slave_is_selected(struct bif_slave *slave)
{ return -EPERM; }
static inline int bif_slave_select(struct bif_slave *slave)
{ return -EPERM; }
static inline int bif_ctrl_raw_transaction(struct bif_ctrl *ctrl,
int transaction, u8 data)
{ return -EPERM; }
static inline int bif_ctrl_raw_transaction_read(struct bif_ctrl *ctrl,
int transaction, u8 data, int *response)
{ return -EPERM; }
static inline int bif_ctrl_raw_transaction_query(struct bif_ctrl *ctrl,
int transaction, u8 data, bool *query_response)
{ return -EPERM; }
static inline void bif_ctrl_bus_lock(struct bif_ctrl *ctrl)
{ return -EPERM; }
static inline void bif_ctrl_bus_unlock(struct bif_ctrl *ctrl)
{ return -EPERM; }
static inline u16 bif_crc_ccitt(const u8 *buffer, unsigned int len)
{ return 0; }
static inline int bif_ctrl_measure_rid(struct bif_ctrl *ctrl) { return -EPERM; }
static inline int bif_ctrl_get_bus_period(struct bif_ctrl *ctrl)
{ return -EPERM; }
static inline int bif_ctrl_set_bus_period(struct bif_ctrl *ctrl, int period_ns)
{ return -EPERM; }
static inline int bif_ctrl_get_bus_state(struct bif_ctrl *ctrl)
{ return -EPERM; }
static inline int bif_ctrl_set_bus_state(struct bif_ctrl *ctrl,
enum bif_bus_state state)
{ return -EPERM; }
#endif
#endif

161
include/linux/bif/driver.h Normal file
View file

@ -0,0 +1,161 @@
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _LINUX_BIF_DRIVER_H_
#define _LINUX_BIF_DRIVER_H_
#include <linux/device.h>
#include <linux/err.h>
#include <linux/types.h>
#include <linux/bif/consumer.h>
/**
* struct bif_ctrl_dev - opaque handle used to identify a given BIF controller
* device
*/
struct bif_ctrl_dev;
/**
* struct bif_ctrl_ops - BIF operations which may be implemented by BIF
* controller drivers
* @bus_transaction: Perform the specified BIF transaction which does
* not result in any slave response.
* @bus_transaction_query: Perform the specified BIF transaction which
* expects a BQ response in the case of slave
* positive acknowledgement.
* @bus_transaction_read: Perform the specified BIF transaction which
* expects an RD or TACK response from the selected
* slave.
* @read_slave_registers: Perform all BIF transactions necessary to read
* the specified set of contiguous registers from
* the previously selected slave. This operation
* is used to optimize the common case of slave
* register reads since the a BIF controller driver
* can take advantage of BIF burst reads while the
* BIF core driver cannot due to the inherient
* tight timing requirements.
* @write_slave_registers: Perform all BIF transactions necessary to write
* the specified set of contiguous registers to
* the previously selected slave. This operation
* is used to optimize the common case of slave
* register writes since the a BIF controller
* driver can remove redundant steps when
* performing several WD commands in a row.
* @get_bus_period: Return the tau_bif BIF bus clock period in
* nanoseconds.
* @set_bus_period: Set the tau_bif BIF bus clock period in
* nanoseconds. If the exact period is not
* supported by the BIF controller hardware, then
* the next larger supported period should be used.
* @get_battery_presence: Return the current state of the battery pack.
* If a battery pack is present, then return >= 1.
* If a battery pack is not present, then return 0.
* If an error occurs during presence detection,
* then return errno.
* @get_battery_rid: Return the measured value of the Rid battery
* pack pull-down resistor in ohms.
* @get_bus_state: Return the current bus state as defined by one
* of the enum bif_bus_state values.
* @set_bus_state: Set the BIF bus state to the specified enum
* bif_bus_state value.
*
* The following operations must be defined by every BIF controller driver in
* order to ensure baseline functionality:
* bus_transaction, bus_transaction_query, get_bus_state, and set_bus_state.
*
* The BIF core driver is unaware of BIF transaction timing constraints. A
* given BIF controller driver must ensure that all timing constraints in the
* MIPI-BIF specification are met as transactions are carried out.
*
* Conversion between 11-bit and 17-bit BIF words (i.e. the insertion of BCF_n,
* parity bits, and the inversion bit) must be handled inside of the BIF
* controller driver (either in software or hardware). This guarantees maximum
* performance if hardware support is available.
*
* The bus_transaction_read operation must return -ETIMEDOUT in the case of no
* RD or TACK word received. This allows the transaction query, TQ, command
* to be used for slave selection verification.
*
* It is acceptable for the BIF bus state to be changed autonomously by a BIF
* controller driver in response to low level bus actions without a call to
* set_bus_state. One example is the case of receiving a slave interrupt
* while in interrupt state as this intrinsically causes the bus to enter the
* active communication state.
*/
struct bif_ctrl_ops {
int (*bus_transaction) (struct bif_ctrl_dev *bdev, int transaction,
u8 data);
int (*bus_transaction_query) (struct bif_ctrl_dev *bdev,
int transaction, u8 data,
bool *query_response);
int (*bus_transaction_read) (struct bif_ctrl_dev *bdev,
int transaction, u8 data,
int *response);
int (*read_slave_registers) (struct bif_ctrl_dev *bdev, u16 addr,
u8 *data, int len);
int (*write_slave_registers) (struct bif_ctrl_dev *bdev, u16 addr,
const u8 *data, int len);
int (*get_bus_period) (struct bif_ctrl_dev *bdev);
int (*set_bus_period) (struct bif_ctrl_dev *bdev, int period_ns);
int (*get_battery_presence) (struct bif_ctrl_dev *bdev);
int (*get_battery_rid) (struct bif_ctrl_dev *bdev);
int (*get_bus_state) (struct bif_ctrl_dev *bdev);
int (*set_bus_state) (struct bif_ctrl_dev *bdev, int state);
};
/**
* struct bif_ctrl_desc - BIF bus controller descriptor
* @name: Name used to identify the BIF controller
* @ops: BIF operations supported by the BIF controller
* @bus_clock_min_ns: Minimum tau_bif BIF bus clock period supported by the
* BIF controller
* @bus_clock_max_ns: Maximum tau_bif BIF bus clock period supported by the
* BIF controller
*
* Each BIF controller registered with the BIF core is described with a
* structure of this type.
*/
struct bif_ctrl_desc {
const char *name;
struct bif_ctrl_ops *ops;
int bus_clock_min_ns;
int bus_clock_max_ns;
};
#ifdef CONFIG_BIF
struct bif_ctrl_dev *bif_ctrl_register(struct bif_ctrl_desc *bif_desc,
struct device *dev, void *driver_data, struct device_node *of_node);
void bif_ctrl_unregister(struct bif_ctrl_dev *bdev);
void *bdev_get_drvdata(struct bif_ctrl_dev *bdev);
int bif_ctrl_notify_battery_changed(struct bif_ctrl_dev *bdev);
int bif_ctrl_notify_slave_irq(struct bif_ctrl_dev *bdev);
#else
static inline struct bif_ctrl_dev *bif_ctrl_register(
struct bif_ctrl_desc *bif_desc, struct device *dev, void *driver_data,
struct device_node *of_node)
{ return ERR_PTR(-EINVAL); }
static inline void bif_ctrl_unregister(struct bif_ctrl_dev *bdev) { }
static inline void *bdev_get_drvdata(struct bif_ctrl_dev *bdev) { return NULL; }
int bif_ctrl_notify_slave_irq(struct bif_ctrl_dev *bdev) { return -EINVAL; }
#endif
#endif