+static void tas5086_reset(struct tas5086_private *priv)
+{
+ if (gpio_is_valid(priv->gpio_nreset)) {
+ /* Reset codec - minimum assertion time is 400ns */
+ gpio_direction_output(priv->gpio_nreset, 0);
+ udelay(1);
+ gpio_set_value(priv->gpio_nreset, 1);
+
+ /* Codec needs ~15ms to wake up */
+ msleep(15);
+ }
+}
+
+/* charge period values in microseconds */
+static const int tas5086_charge_period[] = {
+ 13000, 16900, 23400, 31200, 41600, 54600, 72800, 96200,
+ 130000, 156000, 234000, 312000, 416000, 546000, 728000, 962000,
+ 1300000, 169000, 2340000, 3120000, 4160000, 5460000, 7280000, 9620000,
+};
+
+static int tas5086_init(struct device *dev, struct tas5086_private *priv)
+{
+ int ret, i;
+
+ /*
+ * If any of the channels is configured to start in Mid-Z mode,
+ * configure 'part 1' of the PWM starts to use Mid-Z, and tell
+ * all configured mid-z channels to start start under 'part 1'.
+ */
+ if (priv->pwm_start_mid_z)
+ regmap_write(priv->regmap, TAS5086_PWM_START,
+ TAS5086_PWM_START_MIDZ_FOR_START_1 |
+ priv->pwm_start_mid_z);
+
+ /* lookup and set split-capacitor charge period */
+ if (priv->charge_period == 0) {
+ regmap_write(priv->regmap, TAS5086_SPLIT_CAP_CHARGE, 0);
+ } else {
+ i = index_in_array(tas5086_charge_period,
+ ARRAY_SIZE(tas5086_charge_period),
+ priv->charge_period);
+ if (i >= 0)
+ regmap_write(priv->regmap, TAS5086_SPLIT_CAP_CHARGE,
+ i + 0x08);
+ else
+ dev_warn(dev,
+ "Invalid split-cap charge period of %d ns.\n",
+ priv->charge_period);
+ }
+
+ /* enable factory trim */
+ ret = regmap_write(priv->regmap, TAS5086_OSC_TRIM, 0x00);
+ if (ret < 0)
+ return ret;
+
+ /* start all channels */
+ ret = regmap_write(priv->regmap, TAS5086_SYS_CONTROL_2, 0x20);
+ if (ret < 0)
+ return ret;
+
+ /* mute all channels for now */
+ ret = regmap_write(priv->regmap, TAS5086_SOFT_MUTE,
+ TAS5086_SOFT_MUTE_ALL);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+