/* * Copyright (c) 2012-2014, Motorola, Inc. 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 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. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #ifndef __M4SENSORHUB_H__ #define __M4SENSORHUB_H__ #include #include #include #include #include #ifdef __KERNEL__ extern char m4sensorhub_debug; #define M4SENSORHUB_DRIVER_NAME "m4sensorhub" #define M4SENSORHUB_I2C_ADDR 0x18 #define KDEBUG(i, format, s...) \ do { \ if (m4sensorhub_debug >= i) \ pr_crit(format, ##s); \ } while (0) enum m4sensorhub_debug_level { M4SH_NODEBUG = 0x0, M4SH_CRITICAL, M4SH_ERROR, M4SH_WARNING, M4SH_NOTICE, M4SH_INFO, M4SH_DEBUG, M4SH_VERBOSE_DEBUG }; enum m4sensorhub_mode { UNINITIALIZED, BOOTMODE, NORMALMODE }; enum m4sensorhub_bootmode { BOOTMODE00, BOOTMODE01, BOOTMODE10, BOOTMODE11, }; /* This enum is used to register M4 panic callback * The sequence of this enum is also the sequence of calling * i.e. it will be called follow this enum 0, 1, 2 ... max */ enum m4sensorhub_panichdl_index { PANICHDL_DISPLAY_RESTORE, PANICHDL_HEARTRATE_RESTORE, PANICHDL_PASSIVE_RESTORE, PANICHDL_FUSION_RESTORE, PANICHDL_ALS_RESTORE, PANICHDL_MPU9150_RESTORE, PANICHDL_PEDOMETER_RESTORE, /* * Please add enum before PANICHDL_IRQ_RESTORE * to make sure IRQ restore will be called last. * * Also, add your debug string name to * m4sensorhub-panic.c. */ PANICHDL_IRQ_RESTORE, /* Keep it as the last one */ PANICHDL_MAX = PANICHDL_IRQ_RESTORE+1 }; struct m4sensorhub_hwconfig { int irq_gpio; int reset_gpio; int wake_gpio; int boot0_gpio; int boot1_gpio; int mpu_9150_en_gpio; }; struct m4sensorhub_irq_dbg { unsigned char suspend; /* 1 - Suspended, 0 - Normal */ }; struct m4sensorhub_data { struct i2c_client *i2c_client; void *irqdata; void *panicdata; enum m4sensorhub_mode mode; struct m4sensorhub_hwconfig hwconfig; struct m4sensorhub_irq_dbg irq_dbg; char *filename; u16 fw_version; }; struct init_calldata { struct m4sensorhub_data *p_m4sensorhub_data; /* M4 pointer */ void *p_data; /* Driver data */ }; /* Global (kernel) functions */ /* Client devices */ struct m4sensorhub_data *m4sensorhub_client_get_drvdata(void); /* Register access */ /* m4sensorhub_reg_read() Read a register from the M4 sensor hub. Returns number of bytes read on success. Returns negative error code on failure m4sensorhub - pointer to the main m4sensorhub data struct reg - Register to be read value - array to return data. Needs to be at least register's size */ #define m4sensorhub_reg_read(m4sensorhub, reg, value) \ m4sensorhub_reg_read_n(m4sensorhub, reg, value, \ m4sensorhub_reg_getsize(m4sensorhub, reg)) /* m4sensorhub_reg_write() Read a register from the M4 sensor hub. Returns number of bytes write on success. Returns negative error code on failure m4sensorhub - pointer to the main m4sensorhub data struct reg - Register to be write value - array to return data. Needs to be at least register's size mask - mask representing which bits to change in register. If all bits are to be changed, then &m4sh_no_mask can be passed here. */ #define m4sensorhub_reg_write(m4sensorhub, reg, value, mask) \ m4sensorhub_reg_write_n(m4sensorhub, reg, value, mask, \ m4sensorhub_reg_getsize(m4sensorhub, reg)) int m4sensorhub_reg_init(struct m4sensorhub_data *m4sensorhub); int m4sensorhub_reg_shutdown(struct m4sensorhub_data *m4sensorhub); int m4sensorhub_reg_read_n(struct m4sensorhub_data *m4sensorhub, enum m4sensorhub_reg reg, unsigned char *value, short num); int m4sensorhub_reg_write_n(struct m4sensorhub_data *m4sensorhub, enum m4sensorhub_reg reg, unsigned char *value, unsigned char *mask, short num); int m4sensorhub_reg_write_1byte(struct m4sensorhub_data *m4sensorhub, enum m4sensorhub_reg reg, unsigned char value, unsigned char mask); int m4sensorhub_reg_getsize(struct m4sensorhub_data *m4sensorhub, enum m4sensorhub_reg reg); void m4sensorhub_reg_access_lock(void); void m4sensorhub_reg_access_unlock(void); int m4sensorhub_i2c_write_read(struct m4sensorhub_data *m4sensorhub, u8 *buf, int writelen, int readlen); /* * Functions for re-initializing M4 * * In general, only m4sensorhub_test_m4_reboot() should ever * be called directly. */ int m4sensorhub_test_m4_reboot(struct m4sensorhub_data *m4, bool reboot_first); int m4sensorhub_load_firmware(struct m4sensorhub_data *m4sensorhub, unsigned short force_upgrade, const struct firmware *firmware); int m4sensorhub_401_load_firmware(struct m4sensorhub_data *m4sensorhub, unsigned short force_upgrade, const struct firmware *fm); void m4sensorhub_hw_reset(struct m4sensorhub_data *m4sensorhub); /* Interrupt handler */ int m4sensorhub_irq_init(struct m4sensorhub_data *m4sensorhub); void m4sensorhub_irq_shutdown(struct m4sensorhub_data *m4sensorhub); int m4sensorhub_irq_register(struct m4sensorhub_data *m4sensorhub, enum m4sensorhub_irqs irq, void (*cb_func) (enum m4sensorhub_irqs, void *), void *data, uint8_t enable_timed_wakelock); int m4sensorhub_irq_unregister(struct m4sensorhub_data *m4sensorhub, enum m4sensorhub_irqs irq); int m4sensorhub_irq_disable(struct m4sensorhub_data *m4sensorhub, enum m4sensorhub_irqs irq); int m4sensorhub_irq_enable(struct m4sensorhub_data *m4sensorhub, enum m4sensorhub_irqs irq); int m4sensorhub_irq_enable_get(struct m4sensorhub_data *m4sensorhub, enum m4sensorhub_irqs irq); /* M4 Panic Calls */ int m4sensorhub_panic_init(struct m4sensorhub_data *m4sensorhub); void m4sensorhub_panic_shutdown(struct m4sensorhub_data *m4sensorhub); int m4sensorhub_panic_register(struct m4sensorhub_data *m4sensorhub, enum m4sensorhub_panichdl_index index, void (*cb_func)(struct m4sensorhub_data *, void *), void *data); int m4sensorhub_panic_unregister(struct m4sensorhub_data *m4sensorhub, enum m4sensorhub_panichdl_index index); void m4sensorhub_panic_process(struct m4sensorhub_data *m4sensorhub); /* all M4 based drivers need to register an init call with the core, this callback will be executed once M4 core has properly set up FW on M4. For registration, a callback and a void* is passed in. When the callback is executed, the client provided void* is passed back as part of (init_calldata).p_data */ int m4sensorhub_register_initcall(int(*initfunc)(struct init_calldata *), void *pdata); void m4sensorhub_unregister_initcall( int(*initfunc)(struct init_calldata *)); /* * Some M4 drivers (e.g., RTC) require reading data on boot, even if M4 * needs a firmware update. These functions allow drivers to register * callbacks with the core to take care of small maintenance tasks before * M4 is reflashed (e.g., caching the system time). * * NOTE: Drivers should not rely on this call for normal operation. * Reflashing M4 is an uncommon event, and most of the time, * especially in production, these callbacks will never be used. */ int m4sensorhub_register_preflash_callback( int(*initfunc)(struct init_calldata *), void *pdata); void m4sensorhub_unregister_preflash_callback( int(*initfunc)(struct init_calldata *)); void m4sensorhub_call_preflash_callbacks(void); /* For FW flash core */ bool m4sensorhub_preflash_callbacks_exist(void); /* For FW flash core */ int m4sensorhub_irq_disable_all(struct m4sensorhub_data *m4sensorhub); #endif /* __KERNEL__ */ #endif /* __M4SENSORHUB_H__ */