You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
242 lines
5.8 KiB
242 lines
5.8 KiB
/*
|
|
* Copyright (C) 2014 NXP Semiconductors, 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.
|
|
*
|
|
*/
|
|
|
|
#ifndef __TFA9XXX_INC__
|
|
#define __TFA9XXX_INC__
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/types.h>
|
|
#include <linux/list.h>
|
|
#include <linux/i2c.h>
|
|
#include <linux/clk.h>
|
|
#include <linux/leds.h>
|
|
#include <sound/pcm.h>
|
|
#include <linux/regulator/consumer.h>
|
|
|
|
#include "tfa2_dev.h"
|
|
#include "tfa2_container.h"
|
|
#include "tfa2_haptic.h"
|
|
#include "tfa2_dsp_fw.h"
|
|
#include "tfa_haptic_fw_defs.h"
|
|
|
|
#define TFA9XXX_MAX_REGISTER 0xff
|
|
|
|
#define TFA9XXX_FLAG_SKIP_INTERRUPTS (1 << 0)
|
|
#define TFA9XXX_FLAG_REMOVE_PLOP_NOISE (1 << 1)
|
|
#define TFA9XXX_FLAG_LP_MODES (1 << 2)
|
|
|
|
#if defined(TFA_NO_SND_FORMAT_CHECK)
|
|
#define TFA9XXX_NUM_RATES 14
|
|
#else
|
|
#define TFA9XXX_NUM_RATES 9
|
|
#endif
|
|
|
|
#define FIXED_MCLK_RATE 19200000 /* 19.2 MHz */
|
|
#define MAX_LEN_VIB_TYPE 32
|
|
|
|
#define TFA9XXX_INDEX_PBQ 0x0000FFFE /*trigger queue cmd*/
|
|
|
|
#define TFA9XXX_PBQ_SEG_LEN_MAX 10
|
|
#define TFA9XXX_PBQ_DEPTH_MAX 256
|
|
#define TFA9XXX_PBQ_SCALE_MAX 100
|
|
#define TFA9XXX_PBQ_DELAY_MAX 10000
|
|
#define TFA9XXX_PBQ_REPEAT_MAX 32
|
|
|
|
#define TFA9XXX_PBQ_TAG_START 0x8000
|
|
#define TFA9XXX_PBQ_TAG_STOP 0x8001
|
|
#define TFA9XXX_PBQ_TAG_SILENCE 0x8002
|
|
|
|
#define DEBUG_PRINT_PLAYBACK_QUEUE 40
|
|
|
|
enum pbq_hap_state {
|
|
TFA_PBQ_STATE_IDLE,
|
|
TFA_PBQ_STATE_TIMEOUT
|
|
};
|
|
|
|
/* DSP init status */
|
|
enum tfa9xxx_dsp_init_state {
|
|
TFA9XXX_DSP_INIT_STOPPED, /* DSP not running */
|
|
TFA9XXX_DSP_INIT_RECOVER, /* DSP error detected at runtime */
|
|
TFA9XXX_DSP_INIT_FAIL, /* DSP init failed */
|
|
TFA9XXX_DSP_INIT_PENDING, /* DSP start requested */
|
|
TFA9XXX_DSP_INIT_DONE, /* DSP running */
|
|
TFA9XXX_DSP_INIT_INVALIDATED, /* DSP was running, requires re-init */
|
|
};
|
|
|
|
enum tfa9xxx_dsp_fw_state {
|
|
TFA9XXX_DSP_FW_NONE = 0,
|
|
TFA9XXX_DSP_FW_PENDING,
|
|
TFA9XXX_DSP_FW_FAIL,
|
|
TFA9XXX_DSP_FW_OK,
|
|
};
|
|
|
|
struct tfa9xxx_firmware {
|
|
void *base;
|
|
struct tfa9xxx_device *dev;
|
|
char name[9]; /* TODO get length from tfa parameter defs */
|
|
};
|
|
|
|
struct tfa9xxx_baseprofile {
|
|
char basename[MAX_CONTROL_NAME]; /* profile basename */
|
|
int len; /* profile length */
|
|
int item_id; /* profile id */
|
|
int sr_rate_sup[TFA9XXX_NUM_RATES]; /* sample rates for profile */
|
|
struct list_head list; /* list of all profiles */
|
|
};
|
|
|
|
enum tfa_haptic_state {
|
|
STATE_STOP = 0,
|
|
STATE_START,
|
|
STATE_RESTART
|
|
};
|
|
|
|
struct tfa9xxx_pbq_pair {
|
|
unsigned int tag;
|
|
unsigned int mag;
|
|
unsigned int repeat;
|
|
unsigned int remain;
|
|
};
|
|
|
|
struct drv_object {
|
|
enum tfa_haptic_object_type type;
|
|
struct work_struct update_work;
|
|
struct hrtimer active_timer;
|
|
enum tfa_haptic_state state;
|
|
int index;
|
|
};
|
|
|
|
struct tfa9xxx {
|
|
struct regmap *regmap;
|
|
struct i2c_client *i2c;
|
|
struct clk *mclk;
|
|
#if defined(TFA_FORCED_POR)
|
|
struct regulator *vddd;
|
|
#endif
|
|
struct snd_soc_codec *codec;
|
|
struct workqueue_struct *tfa9xxx_wq;
|
|
struct delayed_work init_work;
|
|
struct delayed_work monitor_work;
|
|
#if defined(TFA_ENABLE_INTERRUPT)
|
|
struct delayed_work interrupt_work;
|
|
#endif
|
|
struct mutex dsp_lock;
|
|
int dsp_init;
|
|
int dsp_fw_state;
|
|
int sysclk;
|
|
u16 rev;
|
|
struct tfa9xxx_firmware fw;
|
|
char *fw_name;
|
|
int rate;
|
|
wait_queue_head_t wq;
|
|
struct device *dev;
|
|
int pstream;
|
|
int cstream;
|
|
int trg_pstream;
|
|
int trg_cstream;
|
|
bool enable_monitor;
|
|
|
|
/* index queue */
|
|
unsigned int pbq_depth;
|
|
unsigned int pbq_index;
|
|
unsigned int pbq_state;
|
|
int pbq_repeat;
|
|
int pbq_remain;
|
|
|
|
struct tfa9xxx_pbq_pair pbq_pairs[TFA9XXX_PBQ_DEPTH_MAX];
|
|
struct hrtimer pbq_timer;
|
|
struct work_struct vibe_pbq_work;
|
|
wait_queue_head_t waitq_pbq;
|
|
|
|
unsigned int rate_constraint_list[TFA9XXX_NUM_RATES];
|
|
struct snd_pcm_hw_constraint_list rate_constraint;
|
|
|
|
int reset_gpio;
|
|
int power_gpio;
|
|
int irq_gpio;
|
|
#if defined(TFA_USE_GPIO_FOR_MCLK)
|
|
int mclk_gpio;
|
|
#endif
|
|
|
|
struct list_head list;
|
|
struct tfa2_device *tfa;
|
|
int vstep;
|
|
int profile;
|
|
#ifdef VOLUME_FIXED
|
|
/* store vstep per profile (single device) */
|
|
int prof_vsteps[TFACONT_MAXPROFS];
|
|
#endif
|
|
|
|
#ifdef CONFIG_DEBUG_FS
|
|
struct dentry *dbg_dir;
|
|
#endif
|
|
char *rpc_buffer;
|
|
int rpc_buffer_size; /* amount of valid data in rpc_buffer */
|
|
u8 reg;
|
|
unsigned int flags;
|
|
|
|
bool haptic_mode;
|
|
|
|
/* Haptic */
|
|
struct led_classdev led_dev;
|
|
struct workqueue_struct *tfa9xxx_hap_wq;
|
|
struct class *to_class;
|
|
struct device *to_dev;
|
|
struct delayed_work pll_off_work;
|
|
struct drv_object tone_object;
|
|
#ifdef PARALLEL_OBJECTS
|
|
struct drv_object wave_object;
|
|
#endif
|
|
int timeout; /* max value */
|
|
int intensity;
|
|
u32 tfa2_fw_intensity_max;
|
|
char vib_type[MAX_LEN_VIB_TYPE];
|
|
unsigned int cp_trigger_index;
|
|
bool is_index_triggered;
|
|
bool update_object_index;
|
|
int object_index;
|
|
bool update_object_intensity;
|
|
int object_intensity;
|
|
int object_duration;
|
|
int running_index;
|
|
int clk_users;
|
|
int pattern_duration;
|
|
int f0_trc_users;
|
|
unsigned int pll_off_delay;
|
|
bool patch_loaded;
|
|
bool bck_running;
|
|
};
|
|
|
|
/* tfa9xxx_haptic.c */
|
|
int __init tfa9xxx_haptic_init(void);
|
|
void __exit tfa9xxx_haptic_exit(void);
|
|
int tfa9xxx_haptic_probe(struct tfa9xxx *drv);
|
|
int tfa9xxx_haptic_remove(struct tfa9xxx *drv);
|
|
int tfa9xxx_bck_starts(struct tfa9xxx *drv);
|
|
int tfa9xxx_bck_stops(struct tfa9xxx *drv);
|
|
int tfa9xxx_disable_f0_tracking(struct tfa9xxx *drv, bool disable);
|
|
int tfa9xxx_haptic_dump_objs(struct seq_file *f, void *p);
|
|
|
|
/* mclk control */
|
|
int tfa9xxx_mclk_open(struct tfa9xxx *drv);
|
|
int tfa9xxx_mclk_enable(struct tfa9xxx *drv);
|
|
int tfa9xxx_mclk_disable(struct tfa9xxx *drv);
|
|
int tfa9xxx_mclk_close(struct tfa9xxx *drv);
|
|
|
|
/* calibration */
|
|
enum tfa_cal_type {
|
|
RDC_CAL = 0,
|
|
F0_CAL
|
|
};
|
|
|
|
int tfa2_run_calibrate(enum tfa_cal_type type, uint16_t *val);
|
|
int tfa2_read_calibrate(enum tfa_cal_type type, uint16_t *val);
|
|
int tfa2_read_cal_temp(uint16_t *val);
|
|
|
|
#endif /* __TFA9XXX_INC__ */
|
|
|
|
|