summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorMarcin Mielczarczyk <marcin.mielczarczyk@tieto.com>2010-06-18 10:04:45 +0200
committerUlf Hansson <ulf.hansson@stericsson.com>2011-09-19 15:56:12 +0200
commit7759be585e6774826da8fb0d12daf7164292fdcc (patch)
tree45eff97cf4aadcd72c2e5144dd91dbd92ce819b2 /sound
parent9ab67899804448f2bea4087bb6e9e4d952a79258 (diff)
Vibrator: Timed output vibrator driver
ST-Ericsson vibrator driver which registers in Android specific timed output device class. Signed-off-by: Marcin Mielczarczyk <marcin.mielczarczyk@tieto.com> Signed-off-by: Jerzy Kasenberg <jerzy.kasenberg@tieto.com> Signed-off-by: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com> Timed output vibrator: New functionality. This patch allows to form the vibration characteristic using few parameters defined in the platform data: - boost level and period for start condition - on level as moderate speed - off level and period for brake condition Detailed information can be found here: Documentation\DocBook\ste_timed_vibra.html Signed-off-by: Grzegorz Sygieda <grzegorz.sygieda@tieto.com> Signed-off-by: Krzysztof Antonowicz <krzysztof.antonowicz@tieto.com> Signed-off-by: srinidhi kasagar <srinidhi.kasagar@stericsson.com> vibrator: remove board specific control of vibrator Platform specific control of vibrator should be present in board file (here board-mop500.c). So, for example if GPIO pins are used to control the vibrator, its control function implemenation should be in board file. This patch provides the callback function support in the driver for the same. Signed-off-by: Shreshtha Kumar Sahu <shreshthakumar.sahu@stericsson.com> android: vibrator: dont directly access ktime_t members Use ktime helper functions for converting ktime values Signed-off-by: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com> u8500: vibra: linear vibrators using vibra-pwm Linear vibrators operate on thier required resonance frequency (for COPAL and AAC its ~150Hz). This can be provided using AUDIO DA5 path. This software *workaround* enables linear vibrators using AB8500 vibra-pwm by generating required resonace frequency using software. In addition this patch provides support for separate platform data for Linear and Rotarty vibrators. Signed-off-by: Shreshtha Kumar Sahu <shreshthakumar.sahu@stericsson.com> u8500: vibra: disable vibrator after vibration This patch disables vibrator i.e. configures the PWM duty cycle to zero after vibration duration is over. Signed-off-by: Philippe Langlais <philippe.langlais@linaro.org>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/ab8500_audio.c63
-rw-r--r--sound/soc/codecs/ab8500_audio.h4
-rw-r--r--sound/soc/ux500/ux500_ab8500.c34
3 files changed, 95 insertions, 6 deletions
diff --git a/sound/soc/codecs/ab8500_audio.c b/sound/soc/codecs/ab8500_audio.c
index 7a87890507c..f65ebe5b786 100644
--- a/sound/soc/codecs/ab8500_audio.c
+++ b/sound/soc/codecs/ab8500_audio.c
@@ -46,13 +46,10 @@
#define GPIO27_DIR_OUTPUT 0x04
#define GPIO29_DIR_OUTPUT 0x10
#define GPIO31_DIR_OUTPUT 0x40
-#define GPIO35_DIR_OUTPUT 0x04
/* Macrocell register definitions */
#define AB8500_CTRL3_REG 0x0200
#define AB8500_GPIO_DIR4_REG 0x1013
-#define AB8500_GPIO_DIR5_REG 0x1014
-#define AB8500_GPIO_OUT5_REG 0x1024
/*
* AB8500 register cache & default register settings
@@ -1856,7 +1853,65 @@ void ab8500_audio_power_control(bool power_on)
}
}
-/* Extended interface for codec-driver */
+void ab8500_audio_pwm_vibra(unsigned char speed_left_pos,
+ unsigned char speed_left_neg,
+ unsigned char speed_right_pos,
+ unsigned char speed_right_neg)
+{
+ unsigned int clear_mask, set_mask;
+ bool vibra_on;
+
+ if (ab8500_codec == NULL) {
+ pr_err("%s: ERROR: AB8500 ASoC-driver not yet probed!\n", __func__);
+ return;
+ }
+
+ vibra_on = speed_left_pos | speed_left_neg | speed_right_pos | speed_right_neg;
+ if (!vibra_on) {
+ clear_mask = BMASK(REG_ANACONF4_ENVIB1) | BMASK(REG_ANACONF4_ENVIB2);
+ ab8500_codec_update_reg_audio(ab8500_codec, REG_ANACONF4, clear_mask, 0x00);
+ speed_left_pos = 0;
+ speed_left_neg = 0;
+ speed_right_pos = 0;
+ speed_right_neg = 0;
+ }
+
+ pr_debug("%s: PWM-vibra (%d, %d, %d, %d).\n",
+ __func__,
+ speed_left_pos,
+ speed_left_neg,
+ speed_right_pos,
+ speed_right_neg);
+
+ set_mask = BMASK(REG_PWMGENCONF1_PWMTOVIB1) |
+ BMASK(REG_PWMGENCONF1_PWMTOVIB2) |
+ BMASK(REG_PWMGENCONF1_PWM1CTRL) |
+ BMASK(REG_PWMGENCONF1_PWM2CTRL) |
+ BMASK(REG_PWMGENCONF1_PWM1NCTRL) |
+ BMASK(REG_PWMGENCONF1_PWM1PCTRL) |
+ BMASK(REG_PWMGENCONF1_PWM2NCTRL) |
+ BMASK(REG_PWMGENCONF1_PWM2PCTRL);
+ ab8500_codec_update_reg_audio(ab8500_codec, REG_PWMGENCONF1, 0x00, set_mask);
+
+ if (speed_left_pos > REG_PWMGENCONFX_PWMVIBXDUTCYC_MAX)
+ speed_left_pos = REG_PWMGENCONFX_PWMVIBXDUTCYC_MAX;
+ ab8500_codec_update_reg_audio(ab8500_codec, REG_PWMGENCONF3, REG_MASK_ALL, speed_left_pos);
+
+ if (speed_left_neg > REG_PWMGENCONFX_PWMVIBXDUTCYC_MAX)
+ speed_left_neg = REG_PWMGENCONFX_PWMVIBXDUTCYC_MAX;
+ ab8500_codec_update_reg_audio(ab8500_codec, REG_PWMGENCONF2, REG_MASK_ALL, speed_left_neg);
+
+ if (speed_right_pos > REG_PWMGENCONFX_PWMVIBXDUTCYC_MAX)
+ speed_right_pos = REG_PWMGENCONFX_PWMVIBXDUTCYC_MAX;
+ ab8500_codec_update_reg_audio(ab8500_codec, REG_PWMGENCONF5, REG_MASK_ALL, speed_right_pos);
+
+ if (speed_right_neg > REG_PWMGENCONFX_PWMVIBXDUTCYC_MAX)
+ speed_right_neg = REG_PWMGENCONFX_PWMVIBXDUTCYC_MAX;
+ ab8500_codec_update_reg_audio(ab8500_codec, REG_PWMGENCONF4, REG_MASK_ALL, speed_right_neg);
+
+ set_mask = BMASK(REG_ANACONF4_ENVIB1) | BMASK(REG_ANACONF4_ENVIB2);
+ ab8500_codec_update_reg_audio(ab8500_codec, REG_ANACONF4, 0x00, set_mask);
+}
int ab8500_audio_set_word_length(struct snd_soc_dai *dai, unsigned int wl)
{
diff --git a/sound/soc/codecs/ab8500_audio.h b/sound/soc/codecs/ab8500_audio.h
index 7cfdd1cc13a..c3b24bbc754 100644
--- a/sound/soc/codecs/ab8500_audio.h
+++ b/sound/soc/codecs/ab8500_audio.h
@@ -25,6 +25,10 @@ extern struct snd_soc_codec_driver soc_codec_dev_ab8500;
/* Extended interface for codec-driver */
void ab8500_audio_power_control(bool power_on);
+void ab8500_audio_pwm_vibra(unsigned char speed_left_pos,
+ unsigned char speed_left_neg,
+ unsigned char speed_right_pos,
+ unsigned char speed_right_neg);
int ab8500_audio_set_word_length(struct snd_soc_dai *dai, unsigned int wl);
int ab8500_audio_set_bit_delay(struct snd_soc_dai *dai, unsigned int delay);
int ab8500_audio_setup_if1(struct snd_soc_codec *codec,
diff --git a/sound/soc/ux500/ux500_ab8500.c b/sound/soc/ux500/ux500_ab8500.c
index be647daeeed..805c26448d3 100644
--- a/sound/soc/ux500/ux500_ab8500.c
+++ b/sound/soc/ux500/ux500_ab8500.c
@@ -24,7 +24,6 @@
#include <sound/pcm.h>
#include <sound/jack.h>
#include <sound/pcm_params.h>
-#include <sound/soc-dapm.h>
#include <mach/hardware.h>
#include "ux500_pcm.h"
#include "ux500_msp_dai.h"
@@ -44,6 +43,7 @@
#define DRIVERMODE_CODEC_ONLY 1
static struct snd_soc_jack jack;
+static bool vibra_on;
/* Power-control */
static DEFINE_MUTEX(power_lock);
@@ -58,7 +58,7 @@ static struct clk *clk_ptr_sysclk;
static struct clk *clk_ptr_ulpclk;
/* Regulators */
-static enum regulator_idx {
+enum regulator_idx {
REGULATOR_AUDIO,
REGULATOR_DMIC,
REGULATOR_AMIC1,
@@ -531,6 +531,8 @@ int ux500_ab8500_soc_machine_drv_init(void)
return status;
}
+ vibra_on = false;
+
return 0;
}
@@ -552,6 +554,34 @@ void ux500_ab8500_soc_machine_drv_cleanup(void)
/* Extended interface */
+void ux500_ab8500_audio_pwm_vibra(unsigned char speed_left_pos,
+ unsigned char speed_left_neg,
+ unsigned char speed_right_pos,
+ unsigned char speed_right_neg)
+{
+ bool vibra_on_new;
+
+ vibra_on_new = speed_left_pos | speed_left_neg | speed_right_pos | speed_right_neg;
+ if ((!vibra_on_new) && (vibra_on)) {
+ pr_debug("%s: PWM-vibra off.\n", __func__);
+ vibra_on = false;
+
+ ux500_ab8500_power_control_dec();
+ }
+
+ if ((vibra_on_new) && (!vibra_on)) {
+ pr_debug("%s: PWM-vibra on.\n", __func__);
+ vibra_on = true;
+
+ ux500_ab8500_power_control_inc();
+ }
+
+ ab8500_audio_pwm_vibra(speed_left_pos,
+ speed_left_neg,
+ speed_right_pos,
+ speed_right_neg);
+}
+
void ux500_ab8500_jack_report(int value)
{
if (jack.jack)