// SPDX-License-Identifier: GPL-2.0-only /* * Common code for Freescale MMA955x Intelligent Sensor Platform drivers * Copyright (c) 2014, Intel Corporation. */ #include <linux/module.h> #include <linux/i2c.h> #include <linux/delay.h> #include <linux/iio/iio.h> #include <linux/pm_runtime.h> #include "mma9551_core.h" /* Command masks for mailbox write command */ #define MMA9551_CMD_READ_VERSION_INFO … #define MMA9551_CMD_READ_CONFIG … #define MMA9551_CMD_WRITE_CONFIG … #define MMA9551_CMD_READ_STATUS … /* Mailbox read command */ #define MMA9551_RESPONSE_COCO … /* Error-Status codes returned in mailbox read command */ #define MMA9551_MCI_ERROR_NONE … #define MMA9551_MCI_ERROR_PARAM … #define MMA9551_MCI_INVALID_COUNT … #define MMA9551_MCI_ERROR_COMMAND … #define MMA9551_MCI_ERROR_INVALID_LENGTH … #define MMA9551_MCI_ERROR_FIFO_BUSY … #define MMA9551_MCI_ERROR_FIFO_ALLOCATED … #define MMA9551_MCI_ERROR_FIFO_OVERSIZE … /* GPIO Application */ #define MMA9551_GPIO_POL_MSB … #define MMA9551_GPIO_POL_LSB … /* Sleep/Wake application */ #define MMA9551_SLEEP_CFG … #define MMA9551_SLEEP_CFG_SNCEN … #define MMA9551_SLEEP_CFG_FLEEN … #define MMA9551_SLEEP_CFG_SCHEN … /* AFE application */ #define MMA9551_AFE_X_ACCEL_REG … #define MMA9551_AFE_Y_ACCEL_REG … #define MMA9551_AFE_Z_ACCEL_REG … /* Reset/Suspend/Clear application */ #define MMA9551_RSC_RESET … #define MMA9551_RSC_OFFSET(mask) … #define MMA9551_RSC_VAL(mask) … /* * A response is composed of: * - control registers: MB0-3 * - data registers: MB4-31 * * A request is composed of: * - mbox to write to (always 0) * - control registers: MB1-4 * - data registers: MB5-31 */ #define MMA9551_MAILBOX_CTRL_REGS … #define MMA9551_MAX_MAILBOX_DATA_REGS … #define MMA9551_MAILBOX_REGS … #define MMA9551_I2C_READ_RETRIES … #define MMA9551_I2C_READ_DELAY … struct mma9551_mbox_request { … } __packed; struct mma9551_mbox_response { … } __packed; struct mma9551_version_info { … }; static int mma9551_transfer(struct i2c_client *client, u8 app_id, u8 command, u16 offset, u8 *inbytes, int num_inbytes, u8 *outbytes, int num_outbytes) { … } /** * mma9551_read_config_byte() - read 1 configuration byte * @client: I2C client * @app_id: Application ID * @reg: Application register * @val: Pointer to store value read * * Read one configuration byte from the device using MMA955xL command format. * Commands to the MMA955xL platform consist of a write followed * by one or more reads. * * Locking note: This function must be called with the device lock held. * Locking is not handled inside the function. Callers should ensure they * serialize access to the HW. * * Returns: 0 on success, negative value on failure. */ int mma9551_read_config_byte(struct i2c_client *client, u8 app_id, u16 reg, u8 *val) { … } EXPORT_SYMBOL_NS(…); /** * mma9551_write_config_byte() - write 1 configuration byte * @client: I2C client * @app_id: Application ID * @reg: Application register * @val: Value to write * * Write one configuration byte from the device using MMA955xL command format. * Commands to the MMA955xL platform consist of a write followed by one or * more reads. * * Locking note: This function must be called with the device lock held. * Locking is not handled inside the function. Callers should ensure they * serialize access to the HW. * * Returns: 0 on success, negative value on failure. */ int mma9551_write_config_byte(struct i2c_client *client, u8 app_id, u16 reg, u8 val) { … } EXPORT_SYMBOL_NS(…); /** * mma9551_read_status_byte() - read 1 status byte * @client: I2C client * @app_id: Application ID * @reg: Application register * @val: Pointer to store value read * * Read one status byte from the device using MMA955xL command format. * Commands to the MMA955xL platform consist of a write followed by one or * more reads. * * Locking note: This function must be called with the device lock held. * Locking is not handled inside the function. Callers should ensure they * serialize access to the HW. * * Returns: 0 on success, negative value on failure. */ int mma9551_read_status_byte(struct i2c_client *client, u8 app_id, u16 reg, u8 *val) { … } EXPORT_SYMBOL_NS(…); /** * mma9551_read_config_word() - read 1 config word * @client: I2C client * @app_id: Application ID * @reg: Application register * @val: Pointer to store value read * * Read one configuration word from the device using MMA955xL command format. * Commands to the MMA955xL platform consist of a write followed by one or * more reads. * * Locking note: This function must be called with the device lock held. * Locking is not handled inside the function. Callers should ensure they * serialize access to the HW. * * Returns: 0 on success, negative value on failure. */ int mma9551_read_config_word(struct i2c_client *client, u8 app_id, u16 reg, u16 *val) { … } EXPORT_SYMBOL_NS(…); /** * mma9551_write_config_word() - write 1 config word * @client: I2C client * @app_id: Application ID * @reg: Application register * @val: Value to write * * Write one configuration word from the device using MMA955xL command format. * Commands to the MMA955xL platform consist of a write followed by one or * more reads. * * Locking note: This function must be called with the device lock held. * Locking is not handled inside the function. Callers should ensure they * serialize access to the HW. * * Returns: 0 on success, negative value on failure. */ int mma9551_write_config_word(struct i2c_client *client, u8 app_id, u16 reg, u16 val) { … } EXPORT_SYMBOL_NS(…); /** * mma9551_read_status_word() - read 1 status word * @client: I2C client * @app_id: Application ID * @reg: Application register * @val: Pointer to store value read * * Read one status word from the device using MMA955xL command format. * Commands to the MMA955xL platform consist of a write followed by one or * more reads. * * Locking note: This function must be called with the device lock held. * Locking is not handled inside the function. Callers should ensure they * serialize access to the HW. * * Returns: 0 on success, negative value on failure. */ int mma9551_read_status_word(struct i2c_client *client, u8 app_id, u16 reg, u16 *val) { … } EXPORT_SYMBOL_NS(…); /** * mma9551_read_config_words() - read multiple config words * @client: I2C client * @app_id: Application ID * @reg: Application register * @len: Length of array to read (in words) * @buf: Array of words to read * * Read multiple configuration registers (word-sized registers). * * Locking note: This function must be called with the device lock held. * Locking is not handled inside the function. Callers should ensure they * serialize access to the HW. * * Returns: 0 on success, negative value on failure. */ int mma9551_read_config_words(struct i2c_client *client, u8 app_id, u16 reg, u8 len, u16 *buf) { … } EXPORT_SYMBOL_NS(…); /** * mma9551_read_status_words() - read multiple status words * @client: I2C client * @app_id: Application ID * @reg: Application register * @len: Length of array to read (in words) * @buf: Array of words to read * * Read multiple status registers (word-sized registers). * * Locking note: This function must be called with the device lock held. * Locking is not handled inside the function. Callers should ensure they * serialize access to the HW. * * Returns: 0 on success, negative value on failure. */ int mma9551_read_status_words(struct i2c_client *client, u8 app_id, u16 reg, u8 len, u16 *buf) { … } EXPORT_SYMBOL_NS(…); /** * mma9551_write_config_words() - write multiple config words * @client: I2C client * @app_id: Application ID * @reg: Application register * @len: Length of array to write (in words) * @buf: Array of words to write * * Write multiple configuration registers (word-sized registers). * * Locking note: This function must be called with the device lock held. * Locking is not handled inside the function. Callers should ensure they * serialize access to the HW. * * Returns: 0 on success, negative value on failure. */ int mma9551_write_config_words(struct i2c_client *client, u8 app_id, u16 reg, u8 len, u16 *buf) { … } EXPORT_SYMBOL_NS(…); /** * mma9551_update_config_bits() - update bits in register * @client: I2C client * @app_id: Application ID * @reg: Application register * @mask: Mask for the bits to update * @val: Value of the bits to update * * Update bits in the given register using a bit mask. * * Locking note: This function must be called with the device lock held. * Locking is not handled inside the function. Callers should ensure they * serialize access to the HW. * * Returns: 0 on success, negative value on failure. */ int mma9551_update_config_bits(struct i2c_client *client, u8 app_id, u16 reg, u8 mask, u8 val) { … } EXPORT_SYMBOL_NS(…); /** * mma9551_gpio_config() - configure gpio * @client: I2C client * @pin: GPIO pin to configure * @app_id: Application ID * @bitnum: Bit number of status register being assigned to the GPIO pin. * @polarity: The polarity parameter is described in section 6.2.2, page 66, * of the Software Reference Manual. Basically, polarity=0 means * the interrupt line has the same value as the selected bit, * while polarity=1 means the line is inverted. * * Assign a bit from an application’s status register to a specific GPIO pin. * * Locking note: This function must be called with the device lock held. * Locking is not handled inside the function. Callers should ensure they * serialize access to the HW. * * Returns: 0 on success, negative value on failure. */ int mma9551_gpio_config(struct i2c_client *client, enum mma9551_gpio_pin pin, u8 app_id, u8 bitnum, int polarity) { … } EXPORT_SYMBOL_NS(…); /** * mma9551_read_version() - read device version information * @client: I2C client * * Read version information and print device id and firmware version. * * Locking note: This function must be called with the device lock held. * Locking is not handled inside the function. Callers should ensure they * serialize access to the HW. * * Returns: 0 on success, negative value on failure. */ int mma9551_read_version(struct i2c_client *client) { … } EXPORT_SYMBOL_NS(…); /** * mma9551_set_device_state() - sets HW power mode * @client: I2C client * @enable: Use true to power on device, false to cause the device * to enter sleep. * * Set power on/off for device using the Sleep/Wake Application. * When enable is true, power on chip and enable doze mode. * When enable is false, enter sleep mode (device remains in the * lowest-power mode). * * Locking note: This function must be called with the device lock held. * Locking is not handled inside the function. Callers should ensure they * serialize access to the HW. * * Returns: 0 on success, negative value on failure. */ int mma9551_set_device_state(struct i2c_client *client, bool enable) { … } EXPORT_SYMBOL_NS(…); /** * mma9551_set_power_state() - sets runtime PM state * @client: I2C client * @on: Use true to power on device, false to power off * * Resume or suspend the device using Runtime PM. * The device will suspend after the autosuspend delay. * * Returns: 0 on success, negative value on failure. */ int mma9551_set_power_state(struct i2c_client *client, bool on) { … } EXPORT_SYMBOL_NS(…); /** * mma9551_sleep() - sleep * @freq: Application frequency * * Firmware applications run at a certain frequency on the * device. Sleep for one application cycle to make sure the * application had time to run once and initialize set values. */ void mma9551_sleep(int freq) { … } EXPORT_SYMBOL_NS(…); /** * mma9551_read_accel_chan() - read accelerometer channel * @client: I2C client * @chan: IIO channel * @val: Pointer to the accelerometer value read * @val2: Unused * * Read accelerometer value for the specified channel. * * Locking note: This function must be called with the device lock held. * Locking is not handled inside the function. Callers should ensure they * serialize access to the HW. * * Returns: IIO_VAL_INT on success, negative value on failure. */ int mma9551_read_accel_chan(struct i2c_client *client, const struct iio_chan_spec *chan, int *val, int *val2) { … } EXPORT_SYMBOL_NS(…); /** * mma9551_read_accel_scale() - read accelerometer scale * @val: Pointer to the accelerometer scale (int value) * @val2: Pointer to the accelerometer scale (micro value) * * Read accelerometer scale. * * Returns: IIO_VAL_INT_PLUS_MICRO. */ int mma9551_read_accel_scale(int *val, int *val2) { … } EXPORT_SYMBOL_NS(…); /** * mma9551_app_reset() - reset application * @client: I2C client * @app_mask: Application to reset * * Reset the given application (using the Reset/Suspend/Clear * Control Application) * * Returns: 0 on success, negative value on failure. */ int mma9551_app_reset(struct i2c_client *client, u32 app_mask) { … } EXPORT_SYMBOL_NS(…); MODULE_AUTHOR(…) …; MODULE_AUTHOR(…) …; MODULE_LICENSE(…) …; MODULE_DESCRIPTION(…) …;