mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 22:40:54 -04:00
bos0614_mmi: added features
Added the following features:
1) BOS0614 registers dump sysfs
2) reading device tree and applying default config
in case of power cut
Change-Id: I53f1b7069ea4d74aa8b02ac525765951fe29bcce
Signed-off-by: Konstantin Makariev <hcv867@motorola.com>
Reviewed-on: https://gerrit.mot.com/1889879
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Reviewed-by: Ling Jin <lingjin@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
parent
9d0fdf76ee
commit
dc86c37e42
9 changed files with 384 additions and 4374 deletions
|
|
@ -21,6 +21,10 @@
|
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
#define pr_fmt(fmt) "bos0614: %s: " fmt, __func__
|
||||
|
||||
#define DEBUG
|
||||
//#undef DEBUG
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
|
|
@ -34,62 +38,12 @@
|
|||
#include "libs/dk-core/src/bsp/drivers/i2c/i2c.h"
|
||||
#include "libs/dk-core/src/bsp/drivers/haptic/bos0614Driver.h"
|
||||
|
||||
enum {
|
||||
PARAM_UCHAR8 = 1,
|
||||
PARAM_INT16,
|
||||
PARAM_UINT16,
|
||||
PARAM_INT32,
|
||||
PARAM_UINT32
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int tid;
|
||||
void *data_ptr;
|
||||
} ParamsLst;
|
||||
|
||||
#define PARAM_ADD(t, v) {\
|
||||
params[numP].tid = t;\
|
||||
params[numP].data_ptr = v;\
|
||||
numP++;\
|
||||
}
|
||||
|
||||
static int process_params(ParamsLst *params, int numP, const char *buffer)
|
||||
{
|
||||
char *arg, *buf, *p;
|
||||
int n, err;
|
||||
|
||||
buf = kstrdup(buffer, GFP_KERNEL);
|
||||
for (n = 0; n < numP && p && *p; n++, params++) {
|
||||
arg = strsep(&p, " ");
|
||||
if (!arg || !*arg)
|
||||
break;
|
||||
|
||||
switch (params->tid) {
|
||||
case PARAM_UCHAR8:
|
||||
err = kstrtou8(arg, 0, params->data_ptr);
|
||||
break;
|
||||
case PARAM_INT16:
|
||||
err = kstrtos16(arg, 0, params->data_ptr);
|
||||
break;
|
||||
case PARAM_UINT16:
|
||||
err = kstrtou16(arg, 0, params->data_ptr);
|
||||
break;
|
||||
case PARAM_INT32:
|
||||
err = kstrtoint(arg, 0, params->data_ptr);
|
||||
break;
|
||||
case PARAM_UINT32:
|
||||
err = kstrtouint(arg, 0, params->data_ptr);
|
||||
break;
|
||||
}
|
||||
|
||||
if (err) {
|
||||
n = err;
|
||||
break;
|
||||
}
|
||||
}
|
||||
kfree(buf);
|
||||
return n;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
#undef pr_debug
|
||||
#define pr_debug pr_err
|
||||
#undef dev_dbg
|
||||
#define dev_dbg dev_info
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
|
@ -132,6 +86,40 @@ static ssize_t getChipId(struct device *dev,
|
|||
|
||||
static DEVICE_ATTR(chip_id, 0440, getChipId, NULL);
|
||||
|
||||
static ssize_t getRegsDump(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
Context *ctx = dev_get_drvdata(dev);
|
||||
ssize_t blen = 0;
|
||||
(void) attr;
|
||||
|
||||
if (ctx != NULL)
|
||||
{
|
||||
mutex_lock(&ctx->lock);
|
||||
|
||||
if (ctx->hapticDriver != NULL)
|
||||
{
|
||||
bool res;
|
||||
u16 r, rval;
|
||||
/* dump first 42 registers */
|
||||
for (r = 0; r < ADDRESS_BOS0614_BIST_REG; r++) {
|
||||
rval = 0x2bad;
|
||||
res = ctx->hapticDriver->getRegister(ctx->hapticDriver, r, &rval);
|
||||
blen += snprintf(buf + blen, PAGE_SIZE - blen,
|
||||
"%02X: 0x%02X 0x%02X\n", r,
|
||||
(rval & 0xFF00) >> 8,
|
||||
(rval & 0x00FF));
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&ctx->lock);
|
||||
}
|
||||
|
||||
return blen;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(regs, 0440, getRegsDump, NULL);
|
||||
|
||||
static bool hasError(BOSError *errors, size_t length, BOSError errorType)
|
||||
{
|
||||
size_t index;
|
||||
|
|
@ -161,18 +149,19 @@ static ssize_t getIcErrors(struct device *dev,
|
|||
|
||||
if (ctx != NULL && ctx->hapticDriver != NULL)
|
||||
{
|
||||
HapticDriver *driver = ctx->hapticDriver;
|
||||
size_t nbrErros;
|
||||
BOSError *errors;
|
||||
|
||||
errors = kzalloc(sizeof(BOSError) * BOSERROR_Length, GFP_KERNEL);
|
||||
if (!errors)
|
||||
return res;
|
||||
|
||||
mutex_lock(&ctx->lock);
|
||||
|
||||
errors = kzalloc(sizeof(BOSError) * BOSERROR_Length, GFP_KERNEL);
|
||||
nbrErros = driver->getError(driver, errors, BOSERROR_Length);
|
||||
|
||||
if (errors != NULL)
|
||||
{
|
||||
HapticDriver *driver = ctx->hapticDriver;
|
||||
size_t nbrErros = driver->getError(driver, errors, BOSERROR_Length);
|
||||
|
||||
res = snprintf(buf, PAGE_SIZE, "SC: %d UVLO: %d IDAC: %d MAX_POWER: %d OVT: %d OVV: %d\n",
|
||||
res = snprintf(buf, PAGE_SIZE, "SC: %d UVLO: %d IDAC: %d MAX_POWER: %d OVT: %d OVV: %d\n",
|
||||
hasError(errors, nbrErros, BOSERROR_SHORT_CIRCUIT),
|
||||
hasError(errors, nbrErros, BOSERROR_UVLO),
|
||||
hasError(errors, nbrErros, BOSERROR_IDAC),
|
||||
|
|
@ -180,9 +169,7 @@ static ssize_t getIcErrors(struct device *dev,
|
|||
hasError(errors, nbrErros, BOSERROR_OVT),
|
||||
hasError(errors, nbrErros, BOSERROR_OVV));
|
||||
|
||||
kfree(errors);
|
||||
}
|
||||
|
||||
kfree(errors);
|
||||
|
||||
mutex_unlock(&ctx->lock);
|
||||
}
|
||||
|
|
@ -202,6 +189,7 @@ static ssize_t setSynthWaveform(struct device *dev,
|
|||
|
||||
if (ctx != NULL && ctx->hapticDriver != NULL)
|
||||
{
|
||||
HapticDriver *driver = ctx->hapticDriver;
|
||||
WaveformId id = 0;
|
||||
uint8_t startSliceId = 0;
|
||||
size_t nbrOfSlices = 0;
|
||||
|
|
@ -209,7 +197,7 @@ static ssize_t setSynthWaveform(struct device *dev,
|
|||
uint8_t outputChannel = 0;
|
||||
size_t paramLength = 0;
|
||||
int numP = 0;
|
||||
ParamsLst params[5];
|
||||
ParamsLst params[SET_WAVEFORM_PARAM_LENGTH];
|
||||
|
||||
PARAM_ADD(PARAM_UCHAR8, &id);
|
||||
PARAM_ADD(PARAM_UCHAR8, &startSliceId);
|
||||
|
|
@ -217,27 +205,20 @@ static ssize_t setSynthWaveform(struct device *dev,
|
|||
PARAM_ADD(PARAM_UINT16, &cycle);
|
||||
PARAM_ADD(PARAM_UCHAR8, &outputChannel);
|
||||
|
||||
mutex_lock(&ctx->lock);
|
||||
|
||||
paramLength = process_params(params, numP, buf);
|
||||
if (paramLength < 0) {
|
||||
mutex_unlock(&ctx->lock);
|
||||
if (paramLength != SET_WAVEFORM_PARAM_LENGTH) {
|
||||
return (ssize_t)paramLength;
|
||||
}
|
||||
//paramLength = sscanf(buf, "%hh %hi %zi %hi %hi", &id, &startSliceId,
|
||||
// &nbrOfSlices, &cycle, &outputChannel);
|
||||
|
||||
dev_dbg(ctx->dev,
|
||||
"[Set Synth Waveform] Waveform Id: %d Start Slice Id: %d Nbr Of Slices: %zu Cycle: %d Output Channel: %d\n",
|
||||
id, startSliceId, nbrOfSlices, cycle, outputChannel);
|
||||
|
||||
if (paramLength == SET_WAVEFORM_PARAM_LENGTH)
|
||||
{
|
||||
HapticDriver *driver = ctx->hapticDriver;
|
||||
mutex_lock(&ctx->lock);
|
||||
|
||||
if (driver->synthSetWaveform(driver, id, startSliceId, nbrOfSlices, cycle, outputChannel))
|
||||
{
|
||||
res = count;
|
||||
}
|
||||
if (driver->synthSetWaveform(driver, id, startSliceId, nbrOfSlices, cycle, outputChannel))
|
||||
{
|
||||
res = count;
|
||||
}
|
||||
|
||||
mutex_unlock(&ctx->lock);
|
||||
|
|
@ -258,35 +239,31 @@ static ssize_t setSynthSlice(struct device *dev,
|
|||
|
||||
if (ctx != NULL && ctx->hapticDriver != NULL)
|
||||
{
|
||||
HapticDriver *driver;
|
||||
HapticDriver *driver = ctx->hapticDriver;
|
||||
SynthSlice slice;
|
||||
uint8_t outputChannel = 0;
|
||||
size_t paramLength = 0;
|
||||
int numP = 0;
|
||||
ParamsLst params[4];
|
||||
ParamsLst params[SET_SLICE_PARAM_LENGTH];
|
||||
|
||||
PARAM_ADD(PARAM_UINT32, &slice.sliceId);
|
||||
PARAM_ADD(PARAM_INT32, &slice.mVAmp);
|
||||
PARAM_ADD(PARAM_UINT32, &slice.mHzFreq);
|
||||
PARAM_ADD(PARAM_UINT32, &slice.cycle);
|
||||
PARAM_ADD(PARAM_UCHAR8, &outputChannel);
|
||||
|
||||
mutex_lock(&ctx->lock);
|
||||
|
||||
driver = ctx->hapticDriver;
|
||||
|
||||
paramLength = process_params(params, numP, buf);
|
||||
if (paramLength < 0) {
|
||||
mutex_unlock(&ctx->lock);
|
||||
if (paramLength != SET_SLICE_PARAM_LENGTH) {
|
||||
return (ssize_t)paramLength;
|
||||
}
|
||||
//paramLength = sscanf(buf, "%d %d %d %d %d", &slice.sliceId, &slice.mVAmp,
|
||||
// &slice.mHzFreq, &slice.cycle, &outputChannel);
|
||||
|
||||
dev_dbg(ctx->dev,
|
||||
"[Set Slice] Slice Id: %d Amplitude: %d mV Frequency: %d milliHertz Cycle: %d Output Channel: %d\n",
|
||||
slice.sliceId, slice.mVAmp, slice.mHzFreq, slice.cycle, outputChannel);
|
||||
|
||||
if (paramLength == SET_SLICE_PARAM_LENGTH &&
|
||||
driver->synthSetSlice(driver, (const SynthSlice *) &slice, outputChannel))
|
||||
mutex_lock(&ctx->lock);
|
||||
|
||||
if (driver->synthSetSlice(driver, (const SynthSlice *) &slice, outputChannel))
|
||||
{
|
||||
res = count;
|
||||
}
|
||||
|
|
@ -310,26 +287,24 @@ static ssize_t synthPlay(struct device *dev,
|
|||
|
||||
if (ctx != NULL && ctx->hapticDriver != NULL)
|
||||
{
|
||||
HapticDriver *driver;
|
||||
HapticDriver *driver = ctx->hapticDriver;
|
||||
WaveformId start = 0;
|
||||
WaveformId stop = 0;
|
||||
size_t paramLength = 0;
|
||||
int numP = 0;
|
||||
ParamsLst params[2];
|
||||
ParamsLst params[SYNTH_PLAY_PARAM_LENGTH];
|
||||
|
||||
PARAM_ADD(PARAM_UCHAR8, &start);
|
||||
PARAM_ADD(PARAM_UCHAR8, &stop);
|
||||
|
||||
driver = ctx->hapticDriver;
|
||||
|
||||
paramLength = process_params(params, numP, buf);
|
||||
if (paramLength < 0) {
|
||||
mutex_unlock(&ctx->lock);
|
||||
if (paramLength != SYNTH_PLAY_PARAM_LENGTH) {
|
||||
return (ssize_t)paramLength;
|
||||
}
|
||||
//paramLength = sscanf(buf, "%hi %hi", &start, &stop);
|
||||
|
||||
if (paramLength == SYNTH_PLAY_PARAM_LENGTH && driver->wfsPlay(driver, start, stop))
|
||||
mutex_lock(&ctx->lock);
|
||||
|
||||
if (driver->wfsPlay(driver, start, stop))
|
||||
{
|
||||
res = count;
|
||||
}
|
||||
|
|
@ -352,27 +327,25 @@ static ssize_t setOutput(struct device *dev,
|
|||
|
||||
if (ctx != NULL && ctx->hapticDriver != NULL)
|
||||
{
|
||||
HapticDriver *driver;
|
||||
HapticDriver *driver = ctx->hapticDriver;
|
||||
int outputState = 0;
|
||||
size_t paramLength = 0;
|
||||
bool bOutputState = outputState > 0 ? true : false;
|
||||
bool bOutputState;
|
||||
int numP = 0;
|
||||
ParamsLst params[1];
|
||||
ParamsLst params[CTRL_OUTPUT_PARAM_LENGTH];
|
||||
|
||||
PARAM_ADD(PARAM_INT32, &outputState);
|
||||
|
||||
mutex_lock(&ctx->lock);
|
||||
driver = ctx->hapticDriver;
|
||||
|
||||
paramLength = process_params(params, numP, buf);
|
||||
if (paramLength < 0) {
|
||||
mutex_unlock(&ctx->lock);
|
||||
if (paramLength != CTRL_OUTPUT_PARAM_LENGTH) {
|
||||
return (ssize_t)paramLength;
|
||||
}
|
||||
//paramLength = sscanf(buf, "%d", &outputState);
|
||||
|
||||
if (paramLength == CTRL_OUTPUT_PARAM_LENGTH &&
|
||||
driver->ctrlOutput(driver, bOutputState))
|
||||
bOutputState = outputState > 0 ? true : false;
|
||||
|
||||
mutex_lock(&ctx->lock);
|
||||
|
||||
if (driver->ctrlOutput(driver, bOutputState))
|
||||
{
|
||||
dev_dbg(ctx->dev,
|
||||
"[Set Output] State: %d \n", bOutputState);
|
||||
|
|
@ -440,37 +413,33 @@ static ssize_t setSensingConfig(struct device *dev,
|
|||
|
||||
if (ctx != NULL && ctx->hapticDriver != NULL)
|
||||
{
|
||||
HapticDriver *driver;
|
||||
HapticDriver *driver = ctx->hapticDriver;
|
||||
SensingConfig config;
|
||||
ChannelId channelId = 0;
|
||||
size_t paramLength = 0;
|
||||
const char *directionS = getSensingDirection(config.direction);
|
||||
const char *modeS = getSensingDetectionMode(config.mode);
|
||||
const char *directionS;
|
||||
const char *modeS;
|
||||
int numP = 0;
|
||||
ParamsLst params[6];
|
||||
ParamsLst params[SENSING_CONFIG_PARAM_LENGTH];
|
||||
|
||||
PARAM_ADD(PARAM_UCHAR8, &channelId);
|
||||
PARAM_ADD(PARAM_UCHAR8, &config.mode);
|
||||
PARAM_ADD(PARAM_UCHAR8, &config.direction);
|
||||
PARAM_ADD(PARAM_UINT16, &config.debounceUs);
|
||||
PARAM_ADD(PARAM_UINT16, &config.thresholdMv);
|
||||
PARAM_ADD(PARAM_INT16, &config.thresholdMv);
|
||||
PARAM_ADD(PARAM_UCHAR8, &config.stabilisationMs);
|
||||
|
||||
mutex_lock(&ctx->lock);
|
||||
driver = ctx->hapticDriver;
|
||||
|
||||
paramLength = process_params(params, numP, buf);
|
||||
if (paramLength < 0) {
|
||||
mutex_unlock(&ctx->lock);
|
||||
if (paramLength != SENSING_CONFIG_PARAM_LENGTH) {
|
||||
return (ssize_t)paramLength;
|
||||
}
|
||||
//paramLength = sscanf(buf, "%hhu %d %d %hd %hd %s", &channelId, &config.mode,
|
||||
// &config.direction, &config.debounceUs,
|
||||
// &config.thresholdMv, &config.stabilisationMs);
|
||||
|
||||
if (paramLength == SENSING_CONFIG_PARAM_LENGTH &&
|
||||
directionS != NULL &&
|
||||
modeS != NULL &&
|
||||
directionS = getSensingDirection(config.direction);
|
||||
modeS = getSensingDetectionMode(config.mode);
|
||||
|
||||
mutex_lock(&ctx->lock);
|
||||
|
||||
if (directionS != NULL && modeS != NULL &&
|
||||
driver->configSensing(driver, channelId, config) &&
|
||||
ctx->hapticDriver->configGPO(ctx->hapticDriver, channelId, GPO_ButtonState))
|
||||
{
|
||||
|
|
@ -499,32 +468,29 @@ static ssize_t setSensingAutoPlay(struct device *dev,
|
|||
|
||||
if (ctx != NULL && ctx->hapticDriver != NULL)
|
||||
{
|
||||
HapticDriver *driver;
|
||||
HapticDriver *driver = ctx->hapticDriver;
|
||||
ChannelId channelId = 0;
|
||||
WaveformId id = 0;
|
||||
SensingDirection direction = 0;
|
||||
size_t paramLength = 0;
|
||||
const char *directionS;
|
||||
int numP = 0;
|
||||
ParamsLst params[3];
|
||||
ParamsLst params[SENSING_AUTO_FEEDBACK_PARAM_LENGTH];
|
||||
|
||||
PARAM_ADD(PARAM_UCHAR8, &channelId);
|
||||
PARAM_ADD(PARAM_UCHAR8, &id);
|
||||
PARAM_ADD(PARAM_UCHAR8, &direction);
|
||||
|
||||
paramLength = process_params(params, numP, buf);
|
||||
if (paramLength < 0) {
|
||||
if (paramLength != SENSING_AUTO_FEEDBACK_PARAM_LENGTH) {
|
||||
return (ssize_t)paramLength;
|
||||
}
|
||||
//paramLength = sscanf(buf, "%d %d %d", &channelId, &id, &direction);
|
||||
|
||||
directionS = getSensingDirection(direction);
|
||||
|
||||
mutex_lock(&ctx->lock);
|
||||
driver = ctx->hapticDriver;
|
||||
|
||||
if (paramLength == SENSING_AUTO_FEEDBACK_PARAM_LENGTH &&
|
||||
directionS != NULL &&
|
||||
if (directionS != NULL &&
|
||||
driver->sensingAutoPlayWave(driver, channelId, id, direction))
|
||||
{
|
||||
dev_dbg(ctx->dev, "[Set Sensing Automatic Feedback] Channel #: %d Waveform #: %d Direction: %s", channelId,
|
||||
|
|
@ -551,29 +517,27 @@ static ssize_t stopSensing(struct device *dev,
|
|||
|
||||
if (ctx != NULL && ctx->hapticDriver != NULL)
|
||||
{
|
||||
HapticDriver *driver;
|
||||
HapticDriver *driver = ctx->hapticDriver;
|
||||
ChannelId channelId = 0;
|
||||
SensingDirection direction = 0;
|
||||
const char *directionS;
|
||||
size_t paramLength = 0;
|
||||
int numP = 0;
|
||||
ParamsLst params[2];
|
||||
ParamsLst params[STOP_SENSING_PARAM_LENGTH];
|
||||
|
||||
PARAM_ADD(PARAM_UCHAR8, &channelId);
|
||||
PARAM_ADD(PARAM_UCHAR8, &direction);
|
||||
|
||||
paramLength = process_params(params, numP, buf);
|
||||
if (paramLength < 0) {
|
||||
if (paramLength != STOP_SENSING_PARAM_LENGTH) {
|
||||
return (ssize_t)paramLength;
|
||||
}
|
||||
//paramLength = sscanf(buf, "%d %d", &channelId, &direction);
|
||||
|
||||
directionS = getSensingDirection(direction);
|
||||
|
||||
mutex_lock(&ctx->lock);
|
||||
driver = ctx->hapticDriver;
|
||||
|
||||
if (paramLength == STOP_SENSING_PARAM_LENGTH &&
|
||||
directionS != NULL &&
|
||||
if (directionS != NULL &&
|
||||
driver->stopSensing(driver, channelId, direction))
|
||||
{
|
||||
dev_dbg(ctx->dev, "[Remove Sensing Profile] Channel #: %d Direction: %s", channelId, directionS);
|
||||
|
|
@ -592,6 +556,7 @@ static DEVICE_ATTR(sensing_stop, 0220, NULL, stopSensing);
|
|||
|
||||
static struct attribute *bosDriverAttrs[] = {
|
||||
&dev_attr_chip_id.attr,
|
||||
&dev_attr_regs.attr,
|
||||
&dev_attr_set_waveform.attr,
|
||||
&dev_attr_set_slice.attr,
|
||||
&dev_attr_synth_play.attr,
|
||||
|
|
@ -666,6 +631,8 @@ static int bosDriverI2cProbe(struct i2c_client *client,
|
|||
resource.i2c = ctx->i2c;
|
||||
ctx->hapticDriver = bos0614DriverI2cInit(resource);
|
||||
|
||||
pr_debug("i2c: %p, driver: %p\n", ctx->i2c, ctx->hapticDriver);
|
||||
|
||||
if (ctx->i2c == NULL || ctx->hapticDriver == NULL)
|
||||
{
|
||||
dev_err(&client->dev, "Failed to instantiate BOS0614 driver\n");
|
||||
|
|
@ -757,13 +724,13 @@ static struct i2c_driver bosDriverI2c = {
|
|||
#ifdef CONFIG_OF
|
||||
static int __init bosDriver_init(void)
|
||||
{
|
||||
pr_info("%s: loading driver\n", __func__);
|
||||
pr_debug("loading driver\n");
|
||||
return i2c_add_driver(&bosDriverI2c);
|
||||
}
|
||||
|
||||
static void __exit bosDriver_exit(void)
|
||||
{
|
||||
pr_info("%s: removing driver\n", __func__);
|
||||
pr_debug("removing driver\n");
|
||||
i2c_del_driver(&bosDriverI2c);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,11 @@
|
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
#define pr_fmt(fmt) "bos0614: %s: " fmt, __func__
|
||||
|
||||
#define DEBUG
|
||||
//#undef DEBUG
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
|
|
@ -28,6 +33,13 @@
|
|||
|
||||
#include "i2cLinux.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#undef pr_debug
|
||||
#define pr_debug pr_err
|
||||
#undef dev_dbg
|
||||
#define dev_dbg dev_err
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
I2c driver;
|
||||
|
|
@ -39,6 +51,124 @@ static void initDriverFct(Context *ctx);
|
|||
#define NBR_CHAR_PER_BYTE (5)
|
||||
#define ESCAPE_CHAR (1)
|
||||
|
||||
int process_params(ParamsLst *params, int numP, const char *buffer)
|
||||
{
|
||||
char *arg, *buf, *p;
|
||||
int n, err;
|
||||
unsigned int value;
|
||||
|
||||
p = buf = kstrdup(buffer, GFP_KERNEL);
|
||||
for (n = 0; n < numP && p && *p; n++, params++) {
|
||||
arg = strsep(&p, " ");
|
||||
if (!arg || !*arg)
|
||||
break;
|
||||
|
||||
pr_debug("arg=[%s] rest=[%s]\n", arg, p);
|
||||
|
||||
switch (params->tid) {
|
||||
case PARAM_UCHAR8:
|
||||
err = kstrtou8(arg, 0, params->data_ptr);
|
||||
value = (unsigned int)*(unsigned char *)params->data_ptr;
|
||||
break;
|
||||
case PARAM_INT16:
|
||||
err = kstrtos16(arg, 0, params->data_ptr);
|
||||
value = (unsigned int)*(short *)params->data_ptr;
|
||||
break;
|
||||
case PARAM_UINT16:
|
||||
err = kstrtou16(arg, 0, params->data_ptr);
|
||||
value = (unsigned int)*(unsigned short *)params->data_ptr;
|
||||
break;
|
||||
case PARAM_INT32:
|
||||
err = kstrtoint(arg, 0, params->data_ptr);
|
||||
value = (unsigned int)*(int *)params->data_ptr;
|
||||
break;
|
||||
case PARAM_UINT32:
|
||||
err = kstrtouint(arg, 0, params->data_ptr);
|
||||
value = *(unsigned int *)params->data_ptr;
|
||||
break;
|
||||
}
|
||||
|
||||
if (err) {
|
||||
n = err;
|
||||
break;
|
||||
} else
|
||||
pr_debug("[%d]=%u\n", n, value);
|
||||
}
|
||||
kfree(buf);
|
||||
pr_debug("processed %d input parameters\n", n);
|
||||
return n;
|
||||
}
|
||||
#if 0
|
||||
static int readRegsConfig(Context *ctx, struct device_node *parent, const char *suffix)
|
||||
{
|
||||
Bos0614RegisterStruct *config = getAllRegsPtr();
|
||||
struct device_node *node;
|
||||
char node_name[64];
|
||||
u32 *temp, length = 0;
|
||||
int npairs, i, index, ret = -EIO;
|
||||
|
||||
scnprintf(node_name, 63, "config-%s", suffix);
|
||||
node = of_find_node_by_name(parent, node_name);
|
||||
if (!node)
|
||||
return -ENODEV;
|
||||
|
||||
if (!of_find_property(node, "config-data", &length)) {
|
||||
dev_err(&ctx->client->dev, "(config-%s) prop config-data not found\n", suffix);
|
||||
goto out;
|
||||
}
|
||||
|
||||
npairs = length / 2;
|
||||
dev_info(&ctx->client->dev, "(config-%s) array size %d\n", suffix, npairs);
|
||||
|
||||
temp = kzalloc(length, GFP_KERNEL);
|
||||
if (!temp)
|
||||
goto out;
|
||||
|
||||
ret = of_property_read_u32_array(node, "config-data", temp, sizeof(u32) * npairs * 2);
|
||||
if (ret) {
|
||||
dev_err(&ctx->client->dev, "error reading config-data (config-%s)\n", suffix);
|
||||
goto release_mem;
|
||||
}
|
||||
|
||||
for (i = 0; i < npairs; i++) {
|
||||
index =(uint16_t)*temp++;
|
||||
config[index].value = (uint16_t)*temp++;
|
||||
dev_info(&ctx->client->dev, "[%d] addr=0x%02x, val=0x%04x\n",
|
||||
i, config[index].addr, config[index].value);
|
||||
}
|
||||
|
||||
release_mem:
|
||||
kfree(temp);
|
||||
out:
|
||||
of_node_put(node);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int readDevTree(Context *ctx)
|
||||
{
|
||||
int ret, verno;
|
||||
struct device_node *np = ctx->client->dev.of_node;
|
||||
struct device_node *config_np;
|
||||
|
||||
config_np = of_find_node_by_name(np, "configs");
|
||||
if (!config_np) {
|
||||
dev_info(&ctx->client->dev, "does not support configs\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!of_property_read_u32(config_np, "config-ver", &verno))
|
||||
dev_info(&ctx->client->dev, "dt config Rev.%u\n", verno);
|
||||
|
||||
ret = readRegsConfig(ctx, config_np, "default");
|
||||
if (ret > 0)
|
||||
dev_info(&ctx->client->dev, "has default config\n");
|
||||
|
||||
of_node_put(config_np);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
static void logBuffer(const char *message, const void *data, size_t length)
|
||||
{
|
||||
size_t bufferLength = length * NBR_CHAR_PER_BYTE + ESCAPE_CHAR;
|
||||
|
|
@ -57,15 +187,13 @@ static void logBuffer(const char *message, const void *data, size_t length)
|
|||
ptr += sprintf(ptr, index < (length - 1) ? "0x%02x " : "0x%02x", _data[index]);
|
||||
}
|
||||
|
||||
//printk("%s length: %zu [%s]\n", message, length, buf, bufferLength, ptr, end);
|
||||
printk("%s length: %zu [%s]\n", message, length, buf);
|
||||
pr_debug("%s length: %zu [%s]\n", message, length, buf);
|
||||
|
||||
kfree(buf);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Private Section
|
||||
*/
|
||||
|
|
@ -142,16 +270,20 @@ I2c *i2cBoreasLinuxInit(struct i2c_client *client)
|
|||
{
|
||||
Context *ctx = kzalloc(sizeof(Context), GFP_KERNEL);
|
||||
|
||||
printk("[PF-Debug] I2C Client %p", client);
|
||||
|
||||
if (ctx != NULL)
|
||||
{
|
||||
ctx->client = client;
|
||||
initDriverFct(ctx);
|
||||
driver = &ctx->driver;
|
||||
#if 0
|
||||
if (ctx->client->dev.of_node)
|
||||
readDevTree(ctx);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
pr_debug("I2C client: %p, driver: %p\n", client, driver);
|
||||
|
||||
return driver;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,8 +25,31 @@
|
|||
#ifndef BOREAS_HAPTIC_DRIVER_LINUX_I2CLINUX_H
|
||||
#define BOREAS_HAPTIC_DRIVER_LINUX_I2CLINUX_H
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/i2c.h>
|
||||
#include "libs/dk-core/src/bsp/drivers/i2c/i2c.h"
|
||||
#include "libs/dk-core/src/bsp/drivers/haptic/bos0614Driver.h"
|
||||
|
||||
enum {
|
||||
PARAM_UCHAR8 = 1,
|
||||
PARAM_INT16,
|
||||
PARAM_UINT16,
|
||||
PARAM_INT32,
|
||||
PARAM_UINT32
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int tid;
|
||||
void *data_ptr;
|
||||
} ParamsLst;
|
||||
|
||||
#define PARAM_ADD(t, v) {\
|
||||
params[numP].tid = t;\
|
||||
params[numP].data_ptr = v;\
|
||||
numP++;\
|
||||
}
|
||||
|
||||
int process_params(ParamsLst *params, int numP, const char *buffer);
|
||||
|
||||
I2c *i2cBoreasLinuxInit(struct i2c_client *client);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
# Set the default behavior, in case people don't have core.autocrlf set.
|
||||
* text=auto
|
||||
# Explicitly declare text files you want to always be normalized and converted
|
||||
# to native line endings on checkout.
|
||||
*.c text
|
||||
*.h text
|
||||
*.txt text
|
||||
*.xsd text
|
||||
*.pdsc text
|
||||
*.svd text
|
||||
*.bat text
|
||||
# Declare files that will always have CRLF line endings on checkout.
|
||||
*.uvproj text eol=crlf
|
||||
*.uvproj text eol=crlf
|
||||
# Denote all files that are truly binary and should not be modified.
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
*.a filter=lfs diff=lfs merge=lfs -text
|
||||
*.lib filter=lfs diff=lfs merge=lfs -text
|
||||
*.exe filter=lfs diff=lfs merge=lfs -text
|
||||
CMSIS/Utilities/Linux-gcc-*/* filter=lfs diff=lfs merge=lfs -text
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
*.breadcrumb
|
||||
*.junit
|
||||
**/__pycache__
|
||||
Local_Release/
|
||||
CMSIS/Documentation/
|
||||
CMSIS/RTOS2/RTX/Library/ARM/MDK/RTX_CM.uvguix.*
|
||||
CMSIS/CoreValidation/Tests/build
|
||||
CMSIS/CoreValidation/Tests/bootloader/build
|
||||
*.uvguix.*
|
||||
*.uvmpw.uvgui.*
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,50 +0,0 @@
|
|||
pdsc: ARM.CMSIS.pdsc
|
||||
preproc:
|
||||
- clean: CMSIS/Documentation/(Core,Core_A,DAP,Driver,DSP,NN,General,Pack,RTOS,RTOS2,SVD,Zone)
|
||||
- doxygen: CMSIS/DoxyGen/Core/core.dxy
|
||||
- doxygen: CMSIS/DoxyGen/Core_A/core_A.dxy
|
||||
- doxygen: CMSIS/DoxyGen/DAP/dap.dxy
|
||||
- doxygen: CMSIS/DoxyGen/Driver/Driver.dxy
|
||||
- doxygen: CMSIS/DoxyGen/DSP/dsp.dxy
|
||||
- doxygen: CMSIS/DoxyGen/General/general.dxy
|
||||
- doxygen: CMSIS/DoxyGen/NN/nn.dxy
|
||||
- doxygen: CMSIS/DoxyGen/Pack/Pack.dxy
|
||||
- doxygen: CMSIS/DoxyGen/RTOS/rtos.dxy
|
||||
- doxygen: CMSIS/DoxyGen/RTOS2/rtos.dxy
|
||||
- doxygen: CMSIS/DoxyGen/SVD/svd.dxy
|
||||
- doxygen: CMSIS/DoxyGen/Zone/zone.dxy
|
||||
glob:
|
||||
- LICENSE.txt
|
||||
- Device/**/*
|
||||
- CMSIS/Core/Include/**/*
|
||||
- CMSIS/Core/Include/**/*: CMSIS/Include/
|
||||
- CMSIS/Core/Template/**/*
|
||||
- CMSIS/Core_A/**/*
|
||||
- CMSIS/DAP/**/*
|
||||
- CMSIS/Driver/**/*
|
||||
- CMSIS/DSP/Include/**/*
|
||||
- CMSIS/DSP/Source/**/*
|
||||
- CMSIS/DSP/Projects/**/*
|
||||
- CMSIS/DSP/Examples/**/*
|
||||
- CMSIS/DSP/Include/**/*: CMSIS/Include/
|
||||
- CMSIS/DSP/Lib/**/*
|
||||
- CMSIS/NN/**/*
|
||||
- CMSIS/Pack/**/*
|
||||
- CMSIS/RTOS/**/*
|
||||
- CMSIS/RTOS2/**/*
|
||||
- CMSIS/Utilities/ARM_Example.*: CMSIS/SVD/ARM_Example.
|
||||
- CMSIS/Utilities/CMSIS-SVD.xsd
|
||||
- CMSIS/Utilities/PACK.xsd
|
||||
- CMSIS/Utilities/PackIndex.xsd
|
||||
- CMSIS/Utilities/Win32/**/*
|
||||
- CMSIS/Utilities/Linux-gcc-4.4.4/**/*
|
||||
- CMSIS/Utilities/Linux-gcc-4.8.3/**/*
|
||||
- CMSIS/Documentation/**/*
|
||||
- CMSIS/DoxyGen/Doxygen_Templates/search.css: CMSIS/Documentation/Core/html/search/search.css
|
||||
- CMSIS/DoxyGen/Doxygen_Templates/search.css: CMSIS/Documentation/Core_A/html/search/search.css
|
||||
- CMSIS/DoxyGen/Doxygen_Templates/search.css: CMSIS/Documentation/Driver/html/search/search.css
|
||||
- CMSIS/DoxyGen/Doxygen_Templates/search.css: CMSIS/Documentation/Pack/html/search/search.css
|
||||
- CMSIS/DoxyGen/Doxygen_Templates/search.css: CMSIS/Documentation/DSP/html/search/search.css
|
||||
- CMSIS/DoxyGen/Doxygen_Templates/search.css: CMSIS/Documentation/DAP/html/search/search.css
|
||||
- CMSIS/DoxyGen/Doxygen_Templates/search.css: CMSIS/Documentation/NN/html/search/search.css
|
||||
- CMSIS/DoxyGen/Zone/genmodel/**/*: CMSIS/Documentation/Zone/genmodel/
|
||||
|
|
@ -23,6 +23,9 @@
|
|||
//
|
||||
#define pr_fmt(fmt) "bos0614: %s: " fmt, __func__
|
||||
|
||||
#define DEBUG
|
||||
//#undef DEBUG
|
||||
|
||||
#include <linux/string.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
|
|
@ -31,8 +34,15 @@
|
|||
|
||||
#include "bsp/boards/boreasTime.h"
|
||||
#include "bsp/drivers/i2c/i2c.h"
|
||||
#include "bsp/drivers/haptic/bos0614Driver.h"
|
||||
#include "bsp/drivers/haptic/bos0614Register.h"
|
||||
#include "bsp/drivers/haptic/bos0614Driver.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#undef pr_debug
|
||||
#define pr_debug pr_info
|
||||
#undef dev_dbg
|
||||
#define dev_dbg dev_info
|
||||
#endif
|
||||
|
||||
#define BOS0614_CHIP_ID (0x0D)
|
||||
#define BOS0614_I2C_ADDRESS (0x2c)
|
||||
|
|
@ -182,6 +192,7 @@ static bool resetSoftware(Context *ctx)
|
|||
{
|
||||
bool res;
|
||||
|
||||
pr_debug("enter\n");
|
||||
ctx->reg.CONFIG_0614.bit.RST = 0x1;
|
||||
|
||||
res = writeReg(ctx, &ctx->reg.CONFIG_0614.reg);
|
||||
|
|
@ -622,6 +633,8 @@ static bool validateIcWorking(Context *ctx)
|
|||
res = res && readRegister(ctx, &ctx->reg.CONFIG_0614.reg);
|
||||
res = res && ctx->reg.CONFIG_0614.bit.PLAY == bos0614SamplingRate_512Ksps;
|
||||
|
||||
pr_debug("ic is%s working!!!\n", res ? "" : " NOT");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -1780,78 +1793,85 @@ static BOS0614_REGS bOS0614Regs =
|
|||
.REG47_0614.reg.generic.addr = ADDRESS_BOS0614_REG47_REG,
|
||||
};
|
||||
|
||||
static uint8_t regAddrToRead[] = {ADDRESS_BOS0614_REFERENCE_REG,
|
||||
ADDRESS_BOS0614_IC_STATUS_REG,
|
||||
ADDRESS_BOS0614_READ_REG,
|
||||
ADDRESS_BOS0614_GPIOX_REG,
|
||||
ADDRESS_BOS0614_TC_REG,
|
||||
ADDRESS_BOS0614_CONFIG_REG,
|
||||
ADDRESS_BOS0614_SENSECONFIG_REG,
|
||||
ADDRESS_BOS0614_SENSE0_REG,
|
||||
ADDRESS_BOS0614_SENSE0P_REG,
|
||||
ADDRESS_BOS0614_SENSE0R_REG,
|
||||
ADDRESS_BOS0614_SENSE0S_REG,
|
||||
ADDRESS_BOS0614_SENSE1_REG,
|
||||
ADDRESS_BOS0614_SENSE1P_REG,
|
||||
ADDRESS_BOS0614_SENSE1R_REG,
|
||||
ADDRESS_BOS0614_SENSE1S_REG,
|
||||
ADDRESS_BOS0614_SENSE2_REG,
|
||||
ADDRESS_BOS0614_SENSE2P_REG,
|
||||
ADDRESS_BOS0614_SENSE2R_REG,
|
||||
ADDRESS_BOS0614_SENSE2S_REG,
|
||||
ADDRESS_BOS0614_SENSE3_REG,
|
||||
ADDRESS_BOS0614_SENSE3P_REG,
|
||||
ADDRESS_BOS0614_SENSE3R_REG,
|
||||
ADDRESS_BOS0614_SENSE3S_REG,
|
||||
ADDRESS_BOS0614_SENSESTATUS_REG,
|
||||
ADDRESS_BOS0614_SENSEDATA0_REG,
|
||||
ADDRESS_BOS0614_SENSEDATA1_REG,
|
||||
ADDRESS_BOS0614_SENSEDATA2_REG,
|
||||
ADDRESS_BOS0614_SENSEDATA3_REG,
|
||||
ADDRESS_BOS0614_SENSERAW0_REG,
|
||||
ADDRESS_BOS0614_SENSERAW1_REG,
|
||||
ADDRESS_BOS0614_SENSERAW2_REG,
|
||||
ADDRESS_BOS0614_SENSERAW3_REG,
|
||||
ADDRESS_BOS0614_KPA_REG,
|
||||
ADDRESS_BOS0614_KP_KI_REG,
|
||||
ADDRESS_BOS0614_DEADTIME_REG,
|
||||
ADDRESS_BOS0614_PARCAP_REG,
|
||||
ADDRESS_BOS0614_SUP_RISE_REG,
|
||||
ADDRESS_BOS0614_TRIM_REG,
|
||||
ADDRESS_BOS0614_CHIP_ID_REG,
|
||||
ADDRESS_BOS0614_VFEEDBACK_REG,
|
||||
ADDRESS_BOS0614_FIFO_STATE_REG,
|
||||
ADDRESS_BOS0614_AUTO_STATE_REG,
|
||||
ADDRESS_BOS0614_BIST_REG,
|
||||
ADDRESS_BOS0614_BISTRES_REG,
|
||||
ADDRESS_BOS0614_DEBUG_REG,
|
||||
ADDRESS_BOS0614_THRESH_REG,
|
||||
ADDRESS_BOS0614_REG38_REG,
|
||||
ADDRESS_BOS0614_REG39_REG,
|
||||
ADDRESS_BOS0614_CALIB_DATA_REG,
|
||||
ADDRESS_BOS0614_REG3B_REG,
|
||||
ADDRESS_BOS0614_REG3C_REG,
|
||||
ADDRESS_BOS0614_REG3D_REG,
|
||||
ADDRESS_BOS0614_REG3E_REG,
|
||||
ADDRESS_BOS0614_REG3F_REG,
|
||||
ADDRESS_BOS0614_REG40_REG,
|
||||
ADDRESS_BOS0614_REG41_REG,
|
||||
ADDRESS_BOS0614_REG42_REG,
|
||||
ADDRESS_BOS0614_REG43_REG,
|
||||
ADDRESS_BOS0614_REG44_REG,
|
||||
ADDRESS_BOS0614_REG45_REG,
|
||||
ADDRESS_BOS0614_REG46_REG,
|
||||
ADDRESS_BOS0614_REG47_REG};
|
||||
static Bos0614RegisterStruct regToRead[] = {
|
||||
{.addr = ADDRESS_BOS0614_REFERENCE_REG,},
|
||||
{.addr = ADDRESS_BOS0614_IC_STATUS_REG,},
|
||||
{.addr = ADDRESS_BOS0614_READ_REG,},
|
||||
{.addr = ADDRESS_BOS0614_GPIOX_REG,},
|
||||
{.addr = ADDRESS_BOS0614_TC_REG,},
|
||||
{.addr = ADDRESS_BOS0614_CONFIG_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSECONFIG_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSE0_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSE0P_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSE0R_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSE0S_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSE1_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSE1P_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSE1R_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSE1S_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSE2_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSE2P_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSE2R_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSE2S_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSE3_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSE3P_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSE3R_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSE3S_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSESTATUS_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSEDATA0_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSEDATA1_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSEDATA2_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSEDATA3_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSERAW0_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSERAW1_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSERAW2_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SENSERAW3_REG,},
|
||||
{.addr = ADDRESS_BOS0614_KPA_REG,},
|
||||
{.addr = ADDRESS_BOS0614_KP_KI_REG,},
|
||||
{.addr = ADDRESS_BOS0614_DEADTIME_REG,},
|
||||
{.addr = ADDRESS_BOS0614_PARCAP_REG,},
|
||||
{.addr = ADDRESS_BOS0614_SUP_RISE_REG,},
|
||||
{.addr = ADDRESS_BOS0614_TRIM_REG,},
|
||||
{.addr = ADDRESS_BOS0614_CHIP_ID_REG,},
|
||||
{.addr = ADDRESS_BOS0614_VFEEDBACK_REG,},
|
||||
{.addr = ADDRESS_BOS0614_FIFO_STATE_REG,},
|
||||
{.addr = ADDRESS_BOS0614_AUTO_STATE_REG,},
|
||||
{.addr = ADDRESS_BOS0614_BIST_REG,},
|
||||
{.addr = ADDRESS_BOS0614_BISTRES_REG,},
|
||||
{.addr = ADDRESS_BOS0614_DEBUG_REG,},
|
||||
{.addr = ADDRESS_BOS0614_THRESH_REG,},
|
||||
{.addr = ADDRESS_BOS0614_REG38_REG,},
|
||||
{.addr = ADDRESS_BOS0614_REG39_REG,},
|
||||
{.addr = ADDRESS_BOS0614_CALIB_DATA_REG,},
|
||||
{.addr = ADDRESS_BOS0614_REG3B_REG,},
|
||||
{.addr = ADDRESS_BOS0614_REG3C_REG,},
|
||||
{.addr = ADDRESS_BOS0614_REG3D_REG,},
|
||||
{.addr = ADDRESS_BOS0614_REG3E_REG,},
|
||||
{.addr = ADDRESS_BOS0614_REG3F_REG,},
|
||||
{.addr = ADDRESS_BOS0614_REG40_REG,},
|
||||
{.addr = ADDRESS_BOS0614_REG41_REG,},
|
||||
{.addr = ADDRESS_BOS0614_REG42_REG,},
|
||||
{.addr = ADDRESS_BOS0614_REG43_REG,},
|
||||
{.addr = ADDRESS_BOS0614_REG44_REG,},
|
||||
{.addr = ADDRESS_BOS0614_REG45_REG,},
|
||||
{.addr = ADDRESS_BOS0614_REG46_REG,},
|
||||
{.addr = ADDRESS_BOS0614_REG47_REG,},
|
||||
};
|
||||
|
||||
Bos0614RegisterStruct *getAllRegsPtr(void)
|
||||
{
|
||||
return regToRead;
|
||||
}
|
||||
|
||||
static bool readAllRegister(Context *ctx)
|
||||
{
|
||||
uint32_t index;
|
||||
bool res = true;
|
||||
|
||||
for (index = 0; index < DATA_ARRAY_LENGTH(regAddrToRead) && res; index++)
|
||||
for (index = 0; index < DATA_ARRAY_LENGTH(regToRead) && res; index++)
|
||||
{
|
||||
uint16_t dummy;
|
||||
res = bos0614GetRegister(&ctx->hDriver, regAddrToRead[index], &dummy);
|
||||
res = bos0614GetRegister(&ctx->hDriver, regToRead[index].addr, &dummy);
|
||||
}
|
||||
|
||||
return res;
|
||||
|
|
@ -1861,10 +1881,22 @@ static bool setDefaultConfig(Context *ctx)
|
|||
{
|
||||
bool res = true;
|
||||
|
||||
//Reset configuration of the register;
|
||||
pr_debug("enter\n");
|
||||
|
||||
//No need to copy registers again here!!!
|
||||
memcpy(&ctx->reg, &bOS0614Regs, sizeof(bOS0614Regs));
|
||||
//Why do we need to do a dummy read???
|
||||
res = readAllRegister(ctx);
|
||||
|
||||
//bosDriverI2cProbe calls i2cBoreasLinuxInit
|
||||
// i2cBoreasLinuxInit calls readDeviceTree
|
||||
// readDeviceTree populates regToRead with default configuration
|
||||
//
|
||||
//Read SENSECONFIG to determine whether power cut occurred
|
||||
//and necessary to apply default config provided in device tree
|
||||
res = readRegister(ctx, &ctx->reg.SENSECONFIG_0614.reg);
|
||||
res = res && ctx->reg.SENSECONFIG_0614.reg.generic.value == regToRead[ADDRESS_BOS0614_SENSECONFIG_REG].value;
|
||||
|
||||
ctx->reg.SENSECONFIG_0614.bit.CH0 = BOS0614_DISABLE;
|
||||
ctx->reg.SENSECONFIG_0614.bit.CH1 = BOS0614_DISABLE;
|
||||
ctx->reg.SENSECONFIG_0614.bit.CH2 = BOS0614_DISABLE;
|
||||
|
|
@ -1875,12 +1907,21 @@ static bool setDefaultConfig(Context *ctx)
|
|||
ctx->reg.SENSECONFIG_0614.reg.generic.addr,
|
||||
ctx->reg.SENSECONFIG_0614.reg.generic.value);
|
||||
|
||||
// Bos0614Register *reg[] = {&ctx->reg.SENSECONFIG_0614.reg};
|
||||
// for (uint32_t index = 0; index < DATA_ARRAY_LENGTH(reg); index++)
|
||||
// {
|
||||
// res = res && ctx->hDriver.setRegister(&ctx->hDriver, reg[index]->generic.addr,
|
||||
// reg[index]->generic.value);
|
||||
// }
|
||||
//This happens when SENSECONFIG register value from IC
|
||||
//won't match config from device tree
|
||||
if (res == false)
|
||||
{
|
||||
uint32_t index;
|
||||
res = true;
|
||||
for (index = 0; index < DATA_ARRAY_LENGTH(regToRead); index++)
|
||||
{
|
||||
if (regToRead[index].value != 0)
|
||||
res = res && ctx->hDriver.setRegister(&ctx->hDriver,
|
||||
regToRead[index].addr,
|
||||
regToRead[index].value);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,5 +45,6 @@ HapticDriver *bos0614DriverI2cInit(Bos0614Resource resources);
|
|||
|
||||
HapticDriver *bos0614DriverSpiInit(Spi *spi, Gpio *gpioA, Gpio *gpioD);
|
||||
|
||||
Bos0614RegisterStruct *getAllRegsPtr(void);
|
||||
|
||||
#endif //DKCORE_BOS0614DRIVER_H
|
||||
|
|
|
|||
Loading…
Reference in a new issue