154 lines
4.6 KiB
C
154 lines
4.6 KiB
C
/* Copyright (c) 2013-2015, 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 __MFD_CORE_RESOURCE_H__
|
|
#define __MFD_CORE_RESOURCE_H__
|
|
|
|
#include <linux/types.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/pm_qos.h>
|
|
|
|
#define WCD9XXX_MAX_IRQ_REGS 4
|
|
#define WCD9XXX_MAX_NUM_IRQS (WCD9XXX_MAX_IRQ_REGS * 8)
|
|
|
|
struct intr_data {
|
|
int intr_num;
|
|
bool clear_first;
|
|
};
|
|
|
|
enum wcd9xxx_pm_state {
|
|
WCD9XXX_PM_SLEEPABLE,
|
|
WCD9XXX_PM_AWAKE,
|
|
WCD9XXX_PM_ASLEEP,
|
|
};
|
|
|
|
enum {
|
|
WCD9XXX_INTR_STATUS_BASE = 0,
|
|
WCD9XXX_INTR_CLEAR_BASE,
|
|
WCD9XXX_INTR_MASK_BASE,
|
|
WCD9XXX_INTR_LEVEL_BASE,
|
|
WCD9XXX_INTR_CLR_COMMIT,
|
|
WCD9XXX_INTR_REG_MAX,
|
|
};
|
|
|
|
enum wcd9xxx_intf_status {
|
|
WCD9XXX_INTERFACE_TYPE_PROBING,
|
|
WCD9XXX_INTERFACE_TYPE_SLIMBUS,
|
|
WCD9XXX_INTERFACE_TYPE_I2C,
|
|
};
|
|
|
|
struct wcd9xxx_core_resource {
|
|
struct mutex irq_lock;
|
|
struct mutex nested_irq_lock;
|
|
|
|
enum wcd9xxx_pm_state pm_state;
|
|
struct mutex pm_lock;
|
|
/* pm_wq notifies change of pm_state */
|
|
wait_queue_head_t pm_wq;
|
|
struct pm_qos_request pm_qos_req;
|
|
int wlock_holders;
|
|
|
|
|
|
/* holds the table of interrupts per codec */
|
|
const struct intr_data *intr_table;
|
|
int intr_table_size;
|
|
unsigned int irq_base;
|
|
unsigned int irq;
|
|
u8 irq_masks_cur[WCD9XXX_MAX_IRQ_REGS];
|
|
u8 irq_masks_cache[WCD9XXX_MAX_IRQ_REGS];
|
|
bool irq_level_high[WCD9XXX_MAX_NUM_IRQS];
|
|
int num_irqs;
|
|
int num_irq_regs;
|
|
u16 intr_reg[WCD9XXX_INTR_REG_MAX];
|
|
|
|
/* Callback functions to read/write codec registers */
|
|
int (*codec_reg_read) (struct wcd9xxx_core_resource *,
|
|
unsigned short);
|
|
int (*codec_reg_write) (struct wcd9xxx_core_resource *,
|
|
unsigned short, u8);
|
|
int (*codec_bulk_read) (struct wcd9xxx_core_resource *,
|
|
unsigned short, int, u8 *);
|
|
int (*codec_bulk_write) (struct wcd9xxx_core_resource *,
|
|
unsigned short, int, u8 *);
|
|
|
|
/* Pointer to parent container data structure */
|
|
void *parent;
|
|
|
|
struct device *dev;
|
|
};
|
|
|
|
extern int wcd9xxx_core_res_init(
|
|
struct wcd9xxx_core_resource*,
|
|
int, int,
|
|
int (*codec_read)(struct wcd9xxx_core_resource *, unsigned short),
|
|
int (*codec_write)(struct wcd9xxx_core_resource *, unsigned short, u8),
|
|
int (*codec_bulk_read) (struct wcd9xxx_core_resource *, unsigned short,
|
|
int, u8 *),
|
|
int (*codec_bulk_write) (struct wcd9xxx_core_resource *, unsigned short,
|
|
int, u8 *));
|
|
|
|
extern void wcd9xxx_core_res_deinit(
|
|
struct wcd9xxx_core_resource *);
|
|
|
|
extern int wcd9xxx_core_res_suspend(
|
|
struct wcd9xxx_core_resource *,
|
|
pm_message_t);
|
|
|
|
extern int wcd9xxx_core_res_resume(
|
|
struct wcd9xxx_core_resource *);
|
|
|
|
extern int wcd9xxx_core_irq_init(
|
|
struct wcd9xxx_core_resource*);
|
|
|
|
extern int wcd9xxx_initialize_irq(
|
|
struct wcd9xxx_core_resource*,
|
|
unsigned int,
|
|
unsigned int);
|
|
|
|
enum wcd9xxx_intf_status wcd9xxx_get_intf_type(void);
|
|
void wcd9xxx_set_intf_type(enum wcd9xxx_intf_status);
|
|
|
|
bool wcd9xxx_lock_sleep(struct wcd9xxx_core_resource *);
|
|
void wcd9xxx_unlock_sleep(struct wcd9xxx_core_resource *);
|
|
void wcd9xxx_nested_irq_lock(struct wcd9xxx_core_resource *);
|
|
void wcd9xxx_nested_irq_unlock(struct wcd9xxx_core_resource *);
|
|
enum wcd9xxx_pm_state wcd9xxx_pm_cmpxchg(
|
|
struct wcd9xxx_core_resource *,
|
|
enum wcd9xxx_pm_state,
|
|
enum wcd9xxx_pm_state);
|
|
|
|
int wcd9xxx_request_irq(struct wcd9xxx_core_resource *, int,
|
|
irq_handler_t, const char *, void *);
|
|
|
|
void wcd9xxx_free_irq(struct wcd9xxx_core_resource *, int, void*);
|
|
void wcd9xxx_enable_irq(struct wcd9xxx_core_resource *, int);
|
|
void wcd9xxx_disable_irq(struct wcd9xxx_core_resource *, int);
|
|
void wcd9xxx_disable_irq_sync(struct wcd9xxx_core_resource *, int);
|
|
int wcd9xxx_reg_read(struct wcd9xxx_core_resource *,
|
|
unsigned short);
|
|
int wcd9xxx_reg_write(struct wcd9xxx_core_resource *,
|
|
unsigned short, u8);
|
|
int wcd9xxx_bulk_read(struct wcd9xxx_core_resource *,
|
|
unsigned short, int, u8 *);
|
|
int wcd9xxx_bulk_write(struct wcd9xxx_core_resource*,
|
|
unsigned short, int, u8*);
|
|
int wcd9xxx_reg_update_bits(struct wcd9xxx_core_resource *core_res,
|
|
unsigned short reg, u8 mask, u8 val);
|
|
int wcd9xxx_irq_init(struct wcd9xxx_core_resource *);
|
|
void wcd9xxx_irq_exit(struct wcd9xxx_core_resource *);
|
|
int wcd9xxx_core_res_resume(
|
|
struct wcd9xxx_core_resource *);
|
|
int wcd9xxx_core_res_suspend(
|
|
struct wcd9xxx_core_resource *,
|
|
pm_message_t);
|
|
#endif
|