mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-09-05 16:07:46 -04:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
311
Documentation/fmc/carrier.txt
Normal file
311
Documentation/fmc/carrier.txt
Normal file
|
@ -0,0 +1,311 @@
|
|||
FMC Device
|
||||
**********
|
||||
|
||||
Within the Linux bus framework, the FMC device is created and
|
||||
registered by the carrier driver. For example, the PCI driver for the
|
||||
SPEC card fills a data structure for each SPEC that it drives, and
|
||||
registers an associated FMC device for each card. The SVEC driver can
|
||||
do exactly the same for the VME carrier (actually, it should do it
|
||||
twice, because the SVEC carries two FMC mezzanines). Similarly, an
|
||||
Etherbone driver will be able to register its own FMC devices, offering
|
||||
communication primitives through frame exchange.
|
||||
|
||||
The contents of the EEPROM within the FMC are used for identification
|
||||
purposes, i.e. for matching the device with its own driver. For this
|
||||
reason the device structure includes a complete copy of the EEPROM
|
||||
(actually, the carrier driver may choose whether or not to return it -
|
||||
for example we most likely won't have the whole EEPROM available for
|
||||
Etherbone devices.
|
||||
|
||||
The following listing shows the current structure defining a device.
|
||||
Please note that all the machinery is in place but some details may
|
||||
still change in the future. For this reason, there is a version field
|
||||
at the beginning of the structure. As usual, the minor number will
|
||||
change for compatible changes (like a new flag) and the major number
|
||||
will increase when an incompatible change happens (for example, a
|
||||
change in layout of some fmc data structures). Device writers should
|
||||
just set it to the value FMC_VERSION, and be ready to get back -EINVAL
|
||||
at registration time.
|
||||
|
||||
struct fmc_device {
|
||||
unsigned long version;
|
||||
unsigned long flags;
|
||||
struct module *owner; /* char device must pin it */
|
||||
struct fmc_fru_id id; /* for EEPROM-based match */
|
||||
struct fmc_operations *op; /* carrier-provided */
|
||||
int irq; /* according to host bus. 0 == none */
|
||||
int eeprom_len; /* Usually 8kB, may be less */
|
||||
int eeprom_addr; /* 0x50, 0x52 etc */
|
||||
uint8_t *eeprom; /* Full contents or leading part */
|
||||
char *carrier_name; /* "SPEC" or similar, for special use */
|
||||
void *carrier_data; /* "struct spec *" or equivalent */
|
||||
__iomem void *fpga_base; /* May be NULL (Etherbone) */
|
||||
__iomem void *slot_base; /* Set by the driver */
|
||||
struct fmc_device **devarray; /* Allocated by the bus */
|
||||
int slot_id; /* Index in the slot array */
|
||||
int nr_slots; /* Number of slots in this carrier */
|
||||
unsigned long memlen; /* Used for the char device */
|
||||
struct device dev; /* For Linux use */
|
||||
struct device *hwdev; /* The underlying hardware device */
|
||||
unsigned long sdbfs_entry;
|
||||
struct sdb_array *sdb;
|
||||
uint32_t device_id; /* Filled by the device */
|
||||
char *mezzanine_name; /* Defaults to ``fmc'' */
|
||||
void *mezzanine_data;
|
||||
};
|
||||
|
||||
The meaning of most fields is summarized in the code comment above.
|
||||
|
||||
The following fields must be filled by the carrier driver before
|
||||
registration:
|
||||
|
||||
* version: must be set to FMC_VERSION.
|
||||
|
||||
* owner: set to MODULE_OWNER.
|
||||
|
||||
* op: the operations to act on the device.
|
||||
|
||||
* irq: number for the mezzanine; may be zero.
|
||||
|
||||
* eeprom_len: length of the following array.
|
||||
|
||||
* eeprom_addr: 0x50 for first mezzanine and so on.
|
||||
|
||||
* eeprom: the full content of the I2C EEPROM.
|
||||
|
||||
* carrier_name.
|
||||
|
||||
* carrier_data: a unique pointer for the carrier.
|
||||
|
||||
* fpga_base: the I/O memory address (may be NULL).
|
||||
|
||||
* slot_id: the index of this slot (starting from zero).
|
||||
|
||||
* memlen: if fpga_base is valid, the length of I/O memory.
|
||||
|
||||
* hwdev: to be used in some dev_err() calls.
|
||||
|
||||
* device_id: a slot-specific unique integer number.
|
||||
|
||||
|
||||
Please note that the carrier should read its own EEPROM memory before
|
||||
registering the device, as well as fill all other fields listed above.
|
||||
|
||||
The following fields should not be assigned, because they are filled
|
||||
later by either the bus or the device driver:
|
||||
|
||||
* flags.
|
||||
|
||||
* fru_id: filled by the bus, parsing the eeprom.
|
||||
|
||||
* slot_base: filled and used by the driver, if useful to it.
|
||||
|
||||
* devarray: an array og all mezzanines driven by a singe FPGA.
|
||||
|
||||
* nr_slots: set by the core at registration time.
|
||||
|
||||
* dev: used by Linux.
|
||||
|
||||
* sdb: FPGA contents, scanned according to driver's directions.
|
||||
|
||||
* sdbfs_entry: SDB entry point in EEPROM: autodetected.
|
||||
|
||||
* mezzanine_data: available for the driver.
|
||||
|
||||
* mezzanine_name: filled by fmc-bus during identification.
|
||||
|
||||
|
||||
Note: mezzanine_data may be redundant, because Linux offers the drvdata
|
||||
approach, so the field may be removed in later versions of this bus
|
||||
implementation.
|
||||
|
||||
As I write this, she SPEC carrier is already completely functional in
|
||||
the fmc-bus environment, and is a good reference to look at.
|
||||
|
||||
|
||||
The API Offered by Carriers
|
||||
===========================
|
||||
|
||||
The carrier provides a number of methods by means of the
|
||||
`fmc_operations' structure, which currently is defined like this
|
||||
(again, it is a moving target, please refer to the header rather than
|
||||
this document):
|
||||
|
||||
struct fmc_operations {
|
||||
uint32_t (*readl)(struct fmc_device *fmc, int offset);
|
||||
void (*writel)(struct fmc_device *fmc, uint32_t value, int offset);
|
||||
int (*reprogram)(struct fmc_device *f, struct fmc_driver *d, char *gw);
|
||||
int (*validate)(struct fmc_device *fmc, struct fmc_driver *drv);
|
||||
int (*irq_request)(struct fmc_device *fmc, irq_handler_t h,
|
||||
char *name, int flags);
|
||||
void (*irq_ack)(struct fmc_device *fmc);
|
||||
int (*irq_free)(struct fmc_device *fmc);
|
||||
int (*gpio_config)(struct fmc_device *fmc, struct fmc_gpio *gpio,
|
||||
int ngpio);
|
||||
int (*read_ee)(struct fmc_device *fmc, int pos, void *d, int l);
|
||||
int (*write_ee)(struct fmc_device *fmc, int pos, const void *d, int l);
|
||||
};
|
||||
|
||||
The individual methods perform the following tasks:
|
||||
|
||||
`readl'
|
||||
`writel'
|
||||
These functions access FPGA registers by whatever means the
|
||||
carrier offers. They are not expected to fail, and most of the time
|
||||
they will just make a memory access to the host bus. If the
|
||||
carrier provides a fpga_base pointer, the driver may use direct
|
||||
access through that pointer. For this reason the header offers the
|
||||
inline functions fmc_readl and fmc_writel that access fpga_base if
|
||||
the respective method is NULL. A driver that wants to be portable
|
||||
and efficient should use fmc_readl and fmc_writel. For Etherbone,
|
||||
or other non-local carriers, error-management is still to be
|
||||
defined.
|
||||
|
||||
`validate'
|
||||
Module parameters are used to manage different applications for
|
||||
two or more boards of the same kind. Validation is based on the
|
||||
busid module parameter, if provided, and returns the matching
|
||||
index in the associated array. See *note Module Parameters:: in in
|
||||
doubt. If no match is found, `-ENOENT' is returned; if the user
|
||||
didn't pass `busid=', all devices will pass validation. The value
|
||||
returned by the validate method can be used as index into other
|
||||
parameters (for example, some drivers use the `lm32=' parameter in
|
||||
this way). Such "generic parameters" are documented in *note
|
||||
Module Parameters::, below. The validate method is used by
|
||||
`fmc-trivial.ko', described in *note fmc-trivial::.
|
||||
|
||||
`reprogram'
|
||||
The carrier enumerates FMC devices by loading a standard (or
|
||||
golden) FPGA binary that allows EEPROM access. Each driver, then,
|
||||
will need to reprogram the FPGA by calling this function. If the
|
||||
name argument is NULL, the carrier should reprogram the golden
|
||||
binary. If the gateware name has been overridden through module
|
||||
parameters (in a carrier-specific way) the file loaded will match
|
||||
the parameters. Per-device gateware names can be specified using
|
||||
the `gateware=' parameter, see *note Module Parameters::. Note:
|
||||
Clients should call rhe new helper, fmc_reprogram, which both
|
||||
calls this method and parse the SDB tree of the FPGA.
|
||||
|
||||
`irq_request'
|
||||
`irq_ack'
|
||||
`irq_free'
|
||||
Interrupt management is carrier-specific, so it is abstracted as
|
||||
operations. The interrupt number is listed in the device
|
||||
structure, and for the mezzanine driver the number is only
|
||||
informative. The handler will receive the fmc pointer as dev_id;
|
||||
the flags argument is passed to the Linux request_irq function,
|
||||
but fmc-specific flags may be added in the future. You'll most
|
||||
likely want to pass the `IRQF_SHARED' flag.
|
||||
|
||||
`gpio_config'
|
||||
The method allows to configure a GPIO pin in the carrier, and read
|
||||
its current value if it is configured as input. See *note The GPIO
|
||||
Abstraction:: for details.
|
||||
|
||||
`read_ee'
|
||||
`write_ee'
|
||||
Read or write the EEPROM. The functions are expected to be only
|
||||
called before reprogramming and the carrier should refuse them
|
||||
with `ENODEV' after reprogramming. The offset is expected to be
|
||||
within 8kB (the current size), but addresses up to 1MB are
|
||||
reserved to fit bigger I2C devices in the future. Carriers may
|
||||
offer access to other internal flash memories using these same
|
||||
methods: for example the SPEC driver may define that its carrier
|
||||
I2C memory is seen at offset 1M and the internal SPI flash is seen
|
||||
at offset 16M. This multiplexing of several flash memories in the
|
||||
same address space is carrier-specific and should only be used
|
||||
by a driver that has verified the `carrier_name' field.
|
||||
|
||||
|
||||
|
||||
The GPIO Abstraction
|
||||
====================
|
||||
|
||||
Support for GPIO pins in the fmc-bus environment is not very
|
||||
straightforward and deserves special discussion.
|
||||
|
||||
While the general idea of a carrier-independent driver seems to fly,
|
||||
configuration of specific signals within the carrier needs at least
|
||||
some knowledge of the carrier itself. For this reason, the specific
|
||||
driver can request to configure carrier-specific GPIO pins, numbered
|
||||
from 0 to at most 4095. Configuration is performed by passing a
|
||||
pointer to an array of struct fmc_gpio items, as well as the length of
|
||||
the array. This is the data structure:
|
||||
|
||||
struct fmc_gpio {
|
||||
char *carrier_name;
|
||||
int gpio;
|
||||
int _gpio; /* internal use by the carrier */
|
||||
int mode; /* GPIOF_DIR_OUT etc, from <linux/gpio.h> */
|
||||
int irqmode; /* IRQF_TRIGGER_LOW and so on */
|
||||
};
|
||||
|
||||
By specifying a carrier_name for each pin, the driver may access
|
||||
different pins in different carriers. The gpio_config method is
|
||||
expected to return the number of pins successfully configured, ignoring
|
||||
requests for other carriers. However, if no pin is configured (because
|
||||
no structure at all refers to the current carrier_name), the operation
|
||||
returns an error so the caller will know that it is running under a
|
||||
yet-unsupported carrier.
|
||||
|
||||
So, for example, a driver that has been developed and tested on both
|
||||
the SPEC and the SVEC may request configuration of two different GPIO
|
||||
pins, and expect one such configuration to succeed - if none succeeds
|
||||
it most likely means that the current carrier is a still-unknown one.
|
||||
|
||||
If, however, your GPIO pin has a specific known role, you can pass a
|
||||
special number in the gpio field, using one of the following macros:
|
||||
|
||||
#define FMC_GPIO_RAW(x) (x) /* 4096 of them */
|
||||
#define FMC_GPIO_IRQ(x) ((x) + 0x1000) /* 256 of them */
|
||||
#define FMC_GPIO_LED(x) ((x) + 0x1100) /* 256 of them */
|
||||
#define FMC_GPIO_KEY(x) ((x) + 0x1200) /* 256 of them */
|
||||
#define FMC_GPIO_TP(x) ((x) + 0x1300) /* 256 of them */
|
||||
#define FMC_GPIO_USER(x) ((x) + 0x1400) /* 256 of them */
|
||||
|
||||
Use of virtual GPIO numbers (anything but FMC_GPIO_RAW) is allowed
|
||||
provided the carrier_name field in the data structure is left
|
||||
unspecified (NULL). Each carrier is responsible for providing a mapping
|
||||
between virtual and physical GPIO numbers. The carrier may then use the
|
||||
_gpio field to cache the result of this mapping.
|
||||
|
||||
All carriers must map their I/O lines to the sets above starting from
|
||||
zero. The SPEC, for example, maps interrupt pins 0 and 1, and test
|
||||
points 0 through 3 (even if the test points on the PCB are called
|
||||
5,6,7,8).
|
||||
|
||||
If, for example, a driver requires a free LED and a test point (for a
|
||||
scope probe to be plugged at some point during development) it may ask
|
||||
for FMC_GPIO_LED(0) and FMC_GPIO_TP(0). Each carrier will provide
|
||||
suitable GPIO pins. Clearly, the person running the drivers will know
|
||||
the order used by the specific carrier driver in assigning leds and
|
||||
testpoints, so to make a carrier-dependent use of the diagnostic tools.
|
||||
|
||||
In theory, some form of autodetection should be possible: a driver like
|
||||
the wr-nic (which uses IRQ(1) on the SPEC card) should configure
|
||||
IRQ(0), make a test with software-generated interrupts and configure
|
||||
IRQ(1) if the test fails. This probing step should be used because even
|
||||
if the wr-nic gateware is known to use IRQ1 on the SPEC, the driver
|
||||
should be carrier-independent and thus use IRQ(0) as a first bet -
|
||||
actually, the knowledge that IRQ0 may fail is carrier-dependent
|
||||
information, but using it doesn't make the driver unsuitable for other
|
||||
carriers.
|
||||
|
||||
The return value of gpio_config is defined as follows:
|
||||
|
||||
* If no pin in the array can be used by the carrier, `-ENODEV'.
|
||||
|
||||
* If at least one virtual GPIO number cannot be mapped, `-ENOENT'.
|
||||
|
||||
* On success, 0 or positive. The value returned is the number of
|
||||
high input bits (if no input is configured, the value for success
|
||||
is 0).
|
||||
|
||||
While I admit the procedure is not completely straightforward, it
|
||||
allows configuration, input and output with a single carrier operation.
|
||||
Given the typical use case of FMC devices, GPIO operations are not
|
||||
expected to ever by in hot paths, and GPIO access so fare has only been
|
||||
used to configure the interrupt pin, mode and polarity. Especially
|
||||
reading inputs is not expected to be common. If your device has GPIO
|
||||
capabilities in the hot path, you should consider using the kernel's
|
||||
GPIO mechanisms.
|
Loading…
Add table
Add a link
Reference in a new issue