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:
parent
77dd355971
commit
6221f73cda
12 changed files with 7225 additions and 0 deletions
|
@ -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/
|
||||
|
|
560
Documentation/bif-framework.txt
Normal file
560
Documentation/bif-framework.txt
Normal 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.
|
22
Documentation/devicetree/bindings/bif/bif.txt
Normal file
22
Documentation/devicetree/bindings/bif/bif.txt
Normal 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>;
|
||||
};
|
93
Documentation/devicetree/bindings/bif/qpnp-bsi.txt
Normal file
93
Documentation/devicetree/bindings/bif/qpnp-bsi.txt
Normal 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>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -200,4 +200,6 @@ source "drivers/hwtracing/intel_th/Kconfig"
|
|||
|
||||
source "drivers/fpga/Kconfig"
|
||||
|
||||
source "drivers/bif/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -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
26
drivers/bif/Kconfig
Normal 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
5
drivers/bif/Makefile
Normal 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
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
1783
drivers/bif/qpnp-bsi.c
Normal file
File diff suppressed because it is too large
Load diff
728
include/linux/bif/consumer.h
Normal file
728
include/linux/bif/consumer.h
Normal 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
161
include/linux/bif/driver.h
Normal 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
|
Loading…
Add table
Reference in a new issue