aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/cs35l35.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/cs35l35.c')
-rw-r--r--sound/soc/codecs/cs35l35.c94
1 files changed, 92 insertions, 2 deletions
diff --git a/sound/soc/codecs/cs35l35.c b/sound/soc/codecs/cs35l35.c
index f8aef5869b03..f1ee184ecab2 100644
--- a/sound/soc/codecs/cs35l35.c
+++ b/sound/soc/codecs/cs35l35.c
@@ -162,6 +162,14 @@ static bool cs35l35_precious_register(struct device *dev, unsigned int reg)
162 } 162 }
163} 163}
164 164
165static void cs35l35_reset(struct cs35l35_private *cs35l35)
166{
167 gpiod_set_value_cansleep(cs35l35->reset_gpio, 0);
168 usleep_range(2000, 2100);
169 gpiod_set_value_cansleep(cs35l35->reset_gpio, 1);
170 usleep_range(1000, 1100);
171}
172
165static int cs35l35_wait_for_pdn(struct cs35l35_private *cs35l35) 173static int cs35l35_wait_for_pdn(struct cs35l35_private *cs35l35)
166{ 174{
167 int ret; 175 int ret;
@@ -756,6 +764,76 @@ static int cs35l35_codec_set_sysclk(struct snd_soc_codec *codec,
756 return ret; 764 return ret;
757} 765}
758 766
767static int cs35l35_boost_inductor(struct cs35l35_private *cs35l35,
768 int inductor)
769{
770 struct regmap *regmap = cs35l35->regmap;
771 unsigned int bst_ipk = 0;
772
773 /*
774 * Digital Boost Converter Configuration for feedback,
775 * ramping, switching frequency, and estimation block seeding.
776 */
777
778 regmap_update_bits(regmap, CS35L35_BST_CONV_SW_FREQ,
779 CS35L35_BST_CONV_SWFREQ_MASK, 0x00);
780
781 regmap_read(regmap, CS35L35_BST_PEAK_I, &bst_ipk);
782 bst_ipk &= CS35L35_BST_IPK_MASK;
783
784 switch (inductor) {
785 case 1000: /* 1 uH */
786 regmap_write(regmap, CS35L35_BST_CONV_COEF_1, 0x24);
787 regmap_write(regmap, CS35L35_BST_CONV_COEF_2, 0x24);
788 regmap_update_bits(regmap, CS35L35_BST_CONV_SW_FREQ,
789 CS35L35_BST_CONV_LBST_MASK, 0x00);
790
791 if (bst_ipk < 0x04)
792 regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x1B);
793 else
794 regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x4E);
795 break;
796 case 1200: /* 1.2 uH */
797 regmap_write(regmap, CS35L35_BST_CONV_COEF_1, 0x20);
798 regmap_write(regmap, CS35L35_BST_CONV_COEF_2, 0x20);
799 regmap_update_bits(regmap, CS35L35_BST_CONV_SW_FREQ,
800 CS35L35_BST_CONV_LBST_MASK, 0x01);
801
802 if (bst_ipk < 0x04)
803 regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x1B);
804 else
805 regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x47);
806 break;
807 case 1500: /* 1.5uH */
808 regmap_write(regmap, CS35L35_BST_CONV_COEF_1, 0x20);
809 regmap_write(regmap, CS35L35_BST_CONV_COEF_2, 0x20);
810 regmap_update_bits(regmap, CS35L35_BST_CONV_SW_FREQ,
811 CS35L35_BST_CONV_LBST_MASK, 0x02);
812
813 if (bst_ipk < 0x04)
814 regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x1B);
815 else
816 regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x3C);
817 break;
818 case 2200: /* 2.2uH */
819 regmap_write(regmap, CS35L35_BST_CONV_COEF_1, 0x19);
820 regmap_write(regmap, CS35L35_BST_CONV_COEF_2, 0x25);
821 regmap_update_bits(regmap, CS35L35_BST_CONV_SW_FREQ,
822 CS35L35_BST_CONV_LBST_MASK, 0x03);
823
824 if (bst_ipk < 0x04)
825 regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x1B);
826 else
827 regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x23);
828 break;
829 default:
830 dev_err(cs35l35->dev, "Invalid Inductor Value %d uH\n",
831 inductor);
832 return -EINVAL;
833 }
834 return 0;
835}
836
759static int cs35l35_codec_probe(struct snd_soc_codec *codec) 837static int cs35l35_codec_probe(struct snd_soc_codec *codec)
760{ 838{
761 struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec); 839 struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
@@ -775,6 +853,10 @@ static int cs35l35_codec_probe(struct snd_soc_codec *codec)
775 cs35l35->pdata.bst_ipk << 853 cs35l35->pdata.bst_ipk <<
776 CS35L35_BST_IPK_SHIFT); 854 CS35L35_BST_IPK_SHIFT);
777 855
856 ret = cs35l35_boost_inductor(cs35l35, cs35l35->pdata.boost_ind);
857 if (ret)
858 return ret;
859
778 if (cs35l35->pdata.gain_zc) 860 if (cs35l35->pdata.gain_zc)
779 regmap_update_bits(cs35l35->regmap, CS35L35_PROTECT_CTL, 861 regmap_update_bits(cs35l35->regmap, CS35L35_PROTECT_CTL,
780 CS35L35_AMP_GAIN_ZC_MASK, 862 CS35L35_AMP_GAIN_ZC_MASK,
@@ -1195,7 +1277,15 @@ static int cs35l35_handle_of_data(struct i2c_client *i2c_client,
1195 return -EINVAL; 1277 return -EINVAL;
1196 } 1278 }
1197 1279
1198 pdata->bst_ipk = (val32 - 1680) / 110; 1280 pdata->bst_ipk = ((val32 - 1680) / 110) | CS35L35_VALID_PDATA;
1281 }
1282
1283 ret = of_property_read_u32(np, "cirrus,boost-ind-nanohenry", &val32);
1284 if (ret >= 0) {
1285 pdata->boost_ind = val32;
1286 } else {
1287 dev_err(&i2c_client->dev, "Inductor not specified.\n");
1288 return -EINVAL;
1199 } 1289 }
1200 1290
1201 if (of_property_read_u32(np, "cirrus,sp-drv-strength", &val32) >= 0) 1291 if (of_property_read_u32(np, "cirrus,sp-drv-strength", &val32) >= 0)
@@ -1454,7 +1544,7 @@ static int cs35l35_i2c_probe(struct i2c_client *i2c_client,
1454 } 1544 }
1455 } 1545 }
1456 1546
1457 gpiod_set_value_cansleep(cs35l35->reset_gpio, 1); 1547 cs35l35_reset(cs35l35);
1458 1548
1459 init_completion(&cs35l35->pdn_done); 1549 init_completion(&cs35l35->pdn_done);
1460 1550