diff --git a/drivers/input/misc/bos0614_mmi/bosDriver.c b/drivers/input/misc/bos0614_mmi/bosDriver.c index f873ddfdc6ec..8b43d72ef6df 100644 --- a/drivers/input/misc/bos0614_mmi/bosDriver.c +++ b/drivers/input/misc/bos0614_mmi/bosDriver.c @@ -82,6 +82,7 @@ typedef struct #define SET_WAVEFORM_PARAM_LENGTH (5) #define SET_SLICE_PARAM_LENGTH (5) +#define SET_SHAPED_SLICE_PARAM_LENGTH (6) #define SYNTH_PLAY_PARAM_LENGTH (2) #define CTRL_OUTPUT_PARAM_LENGTH (1) #define SENSING_CONFIG_PARAM_LENGTH (6) @@ -209,6 +210,29 @@ static ssize_t getIcErrors(struct device *dev, static DEVICE_ATTR(ic_errors, 0440, getIcErrors, NULL); +static ssize_t getIcSensingState(struct device *dev, + struct device_attribute *attr, char *buf) +{ + Context *ctx = dev_get_drvdata(dev); + ssize_t res = -EIO; + + if (ctx != NULL && ctx->hapticDriver != NULL) + { + HapticDriver *driver = ctx->hapticDriver; + uint16_t regVal = 0; + + mutex_lock(&ctx->lock); + driver->getRegister(driver, ADDRESS_BOS0614_SENSECONFIG_REG, ®Val); + mutex_unlock(&ctx->lock); + + res = snprintf(buf, PAGE_SIZE, "%d\n", (regVal & 0x000F) ? 1 : 0); + } + + return res; +} + +static DEVICE_ATTR(is_sensing, 0444, getIcSensingState, NULL); + static ssize_t setSynthWaveform(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -273,27 +297,30 @@ static ssize_t setSynthSlice(struct device *dev, SynthSlice slice; uint8_t outputChannel = 0; size_t paramLength = 0; - int numP = 0; - ParamsLst params[SET_SLICE_PARAM_LENGTH]; + uint8_t shape = 0; + int numP = 0; + ParamsLst params[SET_SHAPED_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); + 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); + PARAM_ADD(PARAM_UCHAR8, &shape); - paramLength = process_params(params, numP, buf); - if (paramLength != SET_SLICE_PARAM_LENGTH) { - return (ssize_t)paramLength; - } + paramLength = process_params(params, numP, buf); + if (paramLength != SET_SLICE_PARAM_LENGTH && + paramLength != SET_SHAPED_SLICE_PARAM_LENGTH) { + return (ssize_t)paramLength; + } 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); + "[Set Slice] Slice Id: %d Amplitude: %d mV Frequency: %d milliHertz Cycle: %d Shape: %d Output Channel: %d\n", + slice.sliceId, slice.mVAmp, slice.mHzFreq, slice.cycle, shape, outputChannel); mutex_lock(&ctx->lock); - if (driver->synthSetSlice(driver, (const SynthSlice *) &slice, outputChannel)) + if (driver->synthSetSlice(driver, (const SynthSlice *) &slice, shape, outputChannel)) { res = count; } @@ -753,7 +780,8 @@ static bool applyingFeedbackButtonConf(Context* ctx, HwButtonFeedback* feedbacks //Slice configuration for (sliceId = 0; sliceId < feedbacks->nbrSlice; sliceId++) { - res = res && driver->synthSetSlice(driver, &feedbacks->slice[sliceId], IGNORE_OUPUT_CHANNEL); + res = res && driver->synthSetSlice(driver, &feedbacks->slice[sliceId], SHAPE_NO_SHAPE, IGNORE_OUPUT_CHANNEL); + pr_debug("set_slice: %d\n", sliceId); } res = res && driver->synthSetWaveform(driver, waveformId, feedbacks->slice->sliceId, feedbacks->nbrSlice, 1, @@ -774,6 +802,7 @@ static bool applyButtonSensingConfiguration(Context* ctx, uint buttonId, Sensing HapticDriver* driver = ctx->hapticDriver; + pr_debug("enter\n"); res = res && driver->buttonSensing(driver, buttonId, *conf); res = res && driver->sensingAutoPlayWave(driver, buttonId, waveformId, conf->direction); @@ -790,9 +819,9 @@ static bool applyDefaultConfiguration(Context* ctx) uint buttonId; bool res = applyingFeedbackButtonConf(ctx, &ctx->defaultButtonConfig.feedback[SENSING_DIRECTION_PRESS], DEFAULT_PRESS_WAVEFORM_ID); + pr_debug("enter\n"); res = res && applyingFeedbackButtonConf(ctx, &ctx->defaultButtonConfig.feedback[SENSING_DIRECTION_RELEASE], DEFAULT_RELEASE_WAVEFORM_ID); - for (buttonId = 0; buttonId < ARRAY_SIZE(ctx->defaultButtonConfig.channel) && res; buttonId++) { if (ctx->defaultButtonConfig.channel[buttonId].present) @@ -826,6 +855,7 @@ static struct attribute *bosDriverAttrs[] = { &dev_attr_sensing_config.attr, &dev_attr_sensing_autoplay.attr, &dev_attr_sensing_stop.attr, + &dev_attr_is_sensing.attr, NULL, }; @@ -916,7 +946,8 @@ static int bosDriverI2cProbe(struct i2c_client *client, dev_err(&client->dev, "Failed to decode DT configuration\n"); goto bosDriverProbeError; } - } + } else + pr_info("cannot find matching device tree\n"); mutex_init(&ctx->lock); diff --git a/drivers/input/misc/bos0614_mmi/i2cLinux.c b/drivers/input/misc/bos0614_mmi/i2cLinux.c index 62d14453c528..94c35bdcab73 100644 --- a/drivers/input/misc/bos0614_mmi/i2cLinux.c +++ b/drivers/input/misc/bos0614_mmi/i2cLinux.c @@ -55,11 +55,13 @@ int process_params(ParamsLst *params, int numP, const char *buffer) { char *arg, *buf, *p; int n, err; - unsigned int valueUI = 0; - int valueI = 0; + unsigned int valueUI; + int valueI; p = buf = kstrdup(buffer, GFP_KERNEL); for (n = 0; n < numP && p && *p; n++, params++) { + valueI = INT16_MIN; + valueUI = UINT16_MAX; arg = strsep(&p, " "); if (!arg || !*arg) break; @@ -92,89 +94,18 @@ int process_params(ParamsLst *params, int numP, const char *buffer) if (err) { n = err; break; - } else if (valueUI != 0) { - pr_debug("[%d]=%u\n", n, valueUI); - } else if (valueI != 0) - pr_debug("[%d]=%d\n", n, valueI); + } - valueI = 0; - valueUI = 0; + if (valueUI != UINT16_MAX) + pr_debug("[%d]=%u\n", n, valueUI); + else if (valueI != INT16_MIN) + pr_debug("[%d]=%d\n", n, valueI); } 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(struct i2c_client* client, const char* message, uint8_t addr, const void* data, size_t length) { diff --git a/drivers/input/misc/bos0614_mmi/libs/dk-core/src/bsp/drivers/haptic/bos0614Driver.c b/drivers/input/misc/bos0614_mmi/libs/dk-core/src/bsp/drivers/haptic/bos0614Driver.c index dc137c61cc80..d96541d0c63a 100644 --- a/drivers/input/misc/bos0614_mmi/libs/dk-core/src/bsp/drivers/haptic/bos0614Driver.c +++ b/drivers/input/misc/bos0614_mmi/libs/dk-core/src/bsp/drivers/haptic/bos0614Driver.c @@ -545,12 +545,41 @@ static bool burstWriteRam(Context *driver, WSFBank bank, uint16_t address, uint1 return res; } +#if 0 +static void hexDump(char* message, uint8_t *data, size_t length) +{ + size_t bufferLength = length * 5 + 5; + char *buf = kzalloc(bufferLength, GFP_KERNEL); + if (buf != NULL) + { + size_t index; + char *ptr = buf; + char *end = buf + bufferLength; + + uint8_t *_data = (uint8_t *) data; + + for (index = 0; index < length && ptr < end; index++) + { + ptr += sprintf(ptr, index < (length - 1) ? "0x%02x " : "0x%02x", _data[index]); + } + + pr_debug("%s [%s]\n", message, buf); + + kfree(buf); + } + +} +#endif static bool writeRam(Context *driver, WSFBank bank, uint16_t *data, size_t length) { int i; bool res = false; - +#if 0 + char buffer[64]; + snprintf(buffer, sizeof(buffer) - 1, "Bank: %d, length=%zu", bank, length); + hexDump(buffer, (uint8_t *)data, length * 2); +#endif memset(driver->txBuffer, 0, sizeof(driver->txBuffer)); driver->txBuffer[I2C_ADDRESS_INDEX] = ADDRESS_BOS0614_REFERENCE_REG; // [0] Main register map address htoBe16(bank, &driver->txBuffer[WRITE_RAM_BANK_INDEX]); // [1-2] WFS bank address @@ -586,12 +615,13 @@ static bool writeRam(Context *driver, WSFBank bank, uint16_t *data, size_t lengt #define VOLT_TO_MILLI_VOLT (1000) static bool setSlice(Context *driver, SynthSlice const *slice, - uint8_t outputChannel) + SliceShape shape, uint8_t outputChannel) { uint16_t buffer[SLICE_LENGTH + RAM_ADDRESS_LENGTH]; uint32_t amplitude_computed = (slice->mVAmp * AMPLITUDE_MAX_VALUE) / (AMPLITUDE_MAX_VALUE_VOLT * VOLT_TO_MILLI_VOLT); uint8_t channel_computed = outputChannel; + uint16_t setShape; uint32_t freq_computed_den = FREQUENCY_RESOLUTION_HZ * Hz_In_MilliHz; uint16_t freq = (uint16_t) (slice->mHzFreq / freq_computed_den); @@ -601,7 +631,26 @@ static bool setSlice(Context *driver, SynthSlice const *slice, buffer[SLICE_AMPLITUDE_INDEX] = (uint16_t) ((channel_computed << 12) | amplitude_computed); buffer[SLICE_FREQ_CYCLE_INDEX] = (uint16_t) freq; buffer[SLICE_FREQ_CYCLE_INDEX] |= (0xFF & slice->cycle) << SLICE_CYCLE_SHIFT; - buffer[SLICE_SHAPE_INDEX] = SLICE_NO_SHAPE; + + switch(shape) { + case SHAPE_SAW: + setShape = 0x0020; /* 64ms shapeUp only */ + break; + case SHAPE_TRIANGLE: + setShape = 0x0022; /* 64ms both ways */ + break; + case SHAPE_SLOW_RISE: + setShape = 0x0042; /* 128ms shapeUp and 64ms shapeDn */ + break; + case SHAPE_SLOW_DROP: + setShape = 0x0024; /* 64ms shapeUp and 128ms shapeDn */ + break; + default: + setShape = SLICE_NO_SHAPE; + break; + } + buffer[SLICE_SHAPE_INDEX] = setShape; + pr_debug("Shape = 0x%04x\n", setShape); return writeRam(driver, WSFBank_Ram, buffer, sizeof(buffer)); } @@ -1311,7 +1360,7 @@ bool bos0614CtrlOutput(HapticDriver *driver, bool activate) } bool -bos0614SetSlice(HapticDriver *driver, const SynthSlice *slice, const uint8_t outputChannel) +bos0614SetSlice(HapticDriver *driver, const SynthSlice *slice, SliceShape shape, const uint8_t outputChannel) { bool res = false; @@ -1321,7 +1370,7 @@ bos0614SetSlice(HapticDriver *driver, const SynthSlice *slice, const uint8_t out Context *ctx = container_of(driver, Context, hDriver); res = setMode(ctx, Bos0614Mode_RAM_Synthesis); - res = res && setSlice(ctx, slice, outputChannel); + res = res && setSlice(ctx, slice, shape, outputChannel); } return res; @@ -2163,7 +2212,6 @@ static uint8_t regAddrToReadRevC[] = { ADDRESS_BOS0614_REG46_REG, ADDRESS_BOS0614_REG47_REG }; - #if 0 static BOS0614_REGS bOS0614Regs = { @@ -2337,54 +2385,16 @@ static bool setDefaultConfig(Context *ctx) { memcpy(&ctx->reg, &bos0614RegsRevC, sizeof(bos0614RegsRevC)); } -#if 0 - //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.common.senseConfig0614.reg); - res = res && ctx->reg.common.senseConfig0614.reg.generic.value == regToRead[ADDRESS_BOS0614_SENSECONFIG_REG].value; - - res = readAllRegister(ctx); -#endif - ctx->reg.common.senseConfig0614.bit.ch0 = BOS0614_DISABLE; ctx->reg.common.senseConfig0614.bit.ch1 = BOS0614_DISABLE; ctx->reg.common.senseConfig0614.bit.ch2 = BOS0614_DISABLE; ctx->reg.common.senseConfig0614.bit.ch3 = BOS0614_DISABLE; ctx->reg.common.senseConfig0614.bit.same = BOS0614_DISABLE; -#if 0 - res = ctx->hDriver.setRegister(&ctx->hDriver, - ctx->reg.common.senseConfig0614.generic.addr, - ctx->reg.common.senseConfig0614.generic.value); - - res = ctx->hDriver.setRegister(&ctx->hDriver, - ctx->reg.common.senseConfig0614.reg.generic.addr, - ctx->reg.common.senseConfig0614.reg.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); - } - } -#endif return res; } diff --git a/drivers/input/misc/bos0614_mmi/libs/dk-core/src/bsp/drivers/haptic/bosDriver.h b/drivers/input/misc/bos0614_mmi/libs/dk-core/src/bsp/drivers/haptic/bosDriver.h index 796b6beec4a4..ed347e455d39 100644 --- a/drivers/input/misc/bos0614_mmi/libs/dk-core/src/bsp/drivers/haptic/bosDriver.h +++ b/drivers/input/misc/bos0614_mmi/libs/dk-core/src/bsp/drivers/haptic/bosDriver.h @@ -143,6 +143,15 @@ typedef enum BOS_EVENT_NO_EVENT } BOSEvent; +typedef enum +{ + SHAPE_NO_SHAPE, + SHAPE_SAW, + SHAPE_TRIANGLE, + SHAPE_SLOW_RISE, + SHAPE_SLOW_DROP +} SliceShape; + typedef uint8_t ChannelId; typedef struct _HapticDriver HapticDriver; @@ -268,7 +277,7 @@ typedef size_t (* BosGetNumberOfRegister)(void); * * @return True if the operation succeed, otherwise false */ -typedef bool (* BosSynthesizerSetSlice)(HapticDriver* driver, const SynthSlice* slice, const uint8_t outputChannel); +typedef bool (* BosSynthesizerSetSlice)(HapticDriver* driver, const SynthSlice* slice, SliceShape shape, const uint8_t outputChannel); /** * @brief Set the synthesizer mode @@ -278,6 +287,7 @@ typedef bool (* BosSynthesizerSetSlice)(HapticDriver* driver, const SynthSlice* * @param[in] frequency The frequency of the specified waveform * @param[in] amplitude The amplitude of the specified waveform * @param[in] cycle The amount of waveform period to play + * @param[in] shape Shape In/Out arrangement * @param[in] outputChannel The output channel to play the waveform * * @return True if the operation succeed, otherwise false