linux/sound/soc/codecs/rt711-sdca-sdw.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2//
   3// rt711-sdw-sdca.c -- rt711 SDCA ALSA SoC audio driver
   4//
   5// Copyright(c) 2021 Realtek Semiconductor Corp.
   6//
   7//
   8
   9#include <linux/delay.h>
  10#include <linux/device.h>
  11#include <linux/mod_devicetable.h>
  12#include <linux/soundwire/sdw_registers.h>
  13#include <linux/module.h>
  14
  15#include "rt711-sdca.h"
  16#include "rt711-sdca-sdw.h"
  17
  18static bool rt711_sdca_readable_register(struct device *dev, unsigned int reg)
  19{
  20        switch (reg) {
  21        case 0x201a ... 0x2027:
  22        case 0x2029 ... 0x202a:
  23        case 0x202d ... 0x2034:
  24        case 0x2200 ... 0x2204:
  25        case 0x2206 ... 0x2212:
  26        case 0x2220 ... 0x2223:
  27        case 0x2230 ... 0x2239:
  28        case 0x2f01 ... 0x2f0f:
  29        case 0x2f30 ... 0x2f36:
  30        case 0x2f50 ... 0x2f5a:
  31        case 0x2f60:
  32        case 0x3200 ... 0x3212:
  33        case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_GE49, RT711_SDCA_CTL_SELECTED_MODE, 0):
  34        case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_GE49, RT711_SDCA_CTL_DETECTED_MODE, 0):
  35        case SDW_SDCA_CTL(FUNC_NUM_HID, RT711_SDCA_ENT_HID01, RT711_SDCA_CTL_HIDTX_CURRENT_OWNER, 0) ...
  36                SDW_SDCA_CTL(FUNC_NUM_HID, RT711_SDCA_ENT_HID01, RT711_SDCA_CTL_HIDTX_MESSAGE_LENGTH, 0):
  37        case RT711_BUF_ADDR_HID1 ... RT711_BUF_ADDR_HID2:
  38                return true;
  39        default:
  40                return false;
  41        }
  42}
  43
  44static bool rt711_sdca_volatile_register(struct device *dev, unsigned int reg)
  45{
  46        switch (reg) {
  47        case 0x201b:
  48        case 0x201c:
  49        case 0x201d:
  50        case 0x201f:
  51        case 0x2021:
  52        case 0x2023:
  53        case 0x2230:
  54        case 0x202d ... 0x202f: /* BRA */
  55        case 0x2200 ... 0x2212: /* i2c debug */
  56        case RT711_RC_CAL_STATUS:
  57        case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_GE49, RT711_SDCA_CTL_DETECTED_MODE, 0):
  58        case SDW_SDCA_CTL(FUNC_NUM_HID, RT711_SDCA_ENT_HID01, RT711_SDCA_CTL_HIDTX_CURRENT_OWNER, 0) ...
  59                SDW_SDCA_CTL(FUNC_NUM_HID, RT711_SDCA_ENT_HID01, RT711_SDCA_CTL_HIDTX_MESSAGE_LENGTH, 0):
  60        case RT711_BUF_ADDR_HID1 ... RT711_BUF_ADDR_HID2:
  61                return true;
  62        default:
  63                return false;
  64        }
  65}
  66
  67static bool rt711_sdca_mbq_readable_register(struct device *dev, unsigned int reg)
  68{
  69        switch (reg) {
  70        case 0x2000000 ... 0x20000ff:
  71        case 0x5600000 ... 0x56000ff:
  72        case 0x5700000 ... 0x57000ff:
  73        case 0x5800000 ... 0x58000ff:
  74        case 0x5900000 ... 0x59000ff:
  75        case 0x5b00000 ... 0x5b000ff:
  76        case 0x5f00000 ... 0x5f000ff:
  77        case 0x6100000 ... 0x61000ff:
  78        case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU05, RT711_SDCA_CTL_FU_VOLUME, CH_L):
  79        case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU05, RT711_SDCA_CTL_FU_VOLUME, CH_R):
  80        case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT711_SDCA_ENT_USER_FU1E, RT711_SDCA_CTL_FU_VOLUME, CH_L):
  81        case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT711_SDCA_ENT_USER_FU1E, RT711_SDCA_CTL_FU_VOLUME, CH_R):
  82        case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU0F, RT711_SDCA_CTL_FU_VOLUME, CH_L):
  83        case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU0F, RT711_SDCA_CTL_FU_VOLUME, CH_R):
  84        case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_PLATFORM_FU44, RT711_SDCA_CTL_FU_CH_GAIN, CH_L):
  85        case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_PLATFORM_FU44, RT711_SDCA_CTL_FU_CH_GAIN, CH_R):
  86        case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT711_SDCA_ENT_PLATFORM_FU15, RT711_SDCA_CTL_FU_CH_GAIN, CH_L):
  87        case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT711_SDCA_ENT_PLATFORM_FU15, RT711_SDCA_CTL_FU_CH_GAIN, CH_R):
  88                return true;
  89        default:
  90                return false;
  91        }
  92}
  93
  94static bool rt711_sdca_mbq_volatile_register(struct device *dev, unsigned int reg)
  95{
  96        switch (reg) {
  97        case 0x2000000:
  98        case 0x200001a:
  99        case 0x2000046:
 100        case 0x2000080:
 101        case 0x2000081:
 102        case 0x2000083:
 103        case 0x5800000:
 104        case 0x5800001:
 105        case 0x5f00001:
 106        case 0x6100008:
 107                return true;
 108        default:
 109                return false;
 110        }
 111}
 112
 113static const struct regmap_config rt711_sdca_regmap = {
 114        .reg_bits = 32,
 115        .val_bits = 8,
 116        .readable_reg = rt711_sdca_readable_register,
 117        .volatile_reg = rt711_sdca_volatile_register,
 118        .max_register = 0x44ffffff,
 119        .reg_defaults = rt711_sdca_reg_defaults,
 120        .num_reg_defaults = ARRAY_SIZE(rt711_sdca_reg_defaults),
 121        .cache_type = REGCACHE_RBTREE,
 122        .use_single_read = true,
 123        .use_single_write = true,
 124};
 125
 126static const struct regmap_config rt711_sdca_mbq_regmap = {
 127        .name = "sdw-mbq",
 128        .reg_bits = 32,
 129        .val_bits = 16,
 130        .readable_reg = rt711_sdca_mbq_readable_register,
 131        .volatile_reg = rt711_sdca_mbq_volatile_register,
 132        .max_register = 0x40800f12,
 133        .reg_defaults = rt711_sdca_mbq_defaults,
 134        .num_reg_defaults = ARRAY_SIZE(rt711_sdca_mbq_defaults),
 135        .cache_type = REGCACHE_RBTREE,
 136        .use_single_read = true,
 137        .use_single_write = true,
 138};
 139
 140static int rt711_sdca_update_status(struct sdw_slave *slave,
 141                                enum sdw_slave_status status)
 142{
 143        struct rt711_sdca_priv *rt711 = dev_get_drvdata(&slave->dev);
 144
 145        /* Update the status */
 146        rt711->status = status;
 147
 148        if (status == SDW_SLAVE_UNATTACHED)
 149                rt711->hw_init = false;
 150
 151        if (status == SDW_SLAVE_ATTACHED) {
 152                if (rt711->hs_jack) {
 153                        /*
 154                         * Due to the SCP_SDCA_INTMASK will be cleared by any reset, and then
 155                         * if the device attached again, we will need to set the setting back.
 156                         * It could avoid losing the jack detection interrupt.
 157                         * This also could sync with the cache value as the rt711_sdca_jack_init set.
 158                         */
 159                        sdw_write_no_pm(rt711->slave, SDW_SCP_SDCA_INTMASK1,
 160                                SDW_SCP_SDCA_INTMASK_SDCA_0);
 161                        sdw_write_no_pm(rt711->slave, SDW_SCP_SDCA_INTMASK2,
 162                                SDW_SCP_SDCA_INTMASK_SDCA_8);
 163                }
 164        }
 165
 166        /*
 167         * Perform initialization only if slave status is present and
 168         * hw_init flag is false
 169         */
 170        if (rt711->hw_init || rt711->status != SDW_SLAVE_ATTACHED)
 171                return 0;
 172
 173        /* perform I/O transfers required for Slave initialization */
 174        return rt711_sdca_io_init(&slave->dev, slave);
 175}
 176
 177static int rt711_sdca_read_prop(struct sdw_slave *slave)
 178{
 179        struct sdw_slave_prop *prop = &slave->prop;
 180        int nval;
 181        int i, j;
 182        u32 bit;
 183        unsigned long addr;
 184        struct sdw_dpn_prop *dpn;
 185
 186        prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY;
 187        prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY;
 188        prop->is_sdca = true;
 189
 190        prop->paging_support = true;
 191
 192        /* first we need to allocate memory for set bits in port lists */
 193        prop->source_ports = 0x14; /* BITMAP: 00010100 */
 194        prop->sink_ports = 0x8; /* BITMAP:  00001000 */
 195
 196        nval = hweight32(prop->source_ports);
 197        prop->src_dpn_prop = devm_kcalloc(&slave->dev, nval,
 198                sizeof(*prop->src_dpn_prop), GFP_KERNEL);
 199        if (!prop->src_dpn_prop)
 200                return -ENOMEM;
 201
 202        i = 0;
 203        dpn = prop->src_dpn_prop;
 204        addr = prop->source_ports;
 205        for_each_set_bit(bit, &addr, 32) {
 206                dpn[i].num = bit;
 207                dpn[i].type = SDW_DPN_FULL;
 208                dpn[i].simple_ch_prep_sm = true;
 209                dpn[i].ch_prep_timeout = 10;
 210                i++;
 211        }
 212
 213        /* do this again for sink now */
 214        nval = hweight32(prop->sink_ports);
 215        prop->sink_dpn_prop = devm_kcalloc(&slave->dev, nval,
 216                sizeof(*prop->sink_dpn_prop), GFP_KERNEL);
 217        if (!prop->sink_dpn_prop)
 218                return -ENOMEM;
 219
 220        j = 0;
 221        dpn = prop->sink_dpn_prop;
 222        addr = prop->sink_ports;
 223        for_each_set_bit(bit, &addr, 32) {
 224                dpn[j].num = bit;
 225                dpn[j].type = SDW_DPN_FULL;
 226                dpn[j].simple_ch_prep_sm = true;
 227                dpn[j].ch_prep_timeout = 10;
 228                j++;
 229        }
 230
 231        /* set the timeout values */
 232        prop->clk_stop_timeout = 20;
 233
 234        /* wake-up event */
 235        prop->wake_capable = 1;
 236
 237        return 0;
 238}
 239
 240static int rt711_sdca_interrupt_callback(struct sdw_slave *slave,
 241                                        struct sdw_slave_intr_status *status)
 242{
 243        struct rt711_sdca_priv *rt711 = dev_get_drvdata(&slave->dev);
 244        int ret, stat;
 245        int count = 0, retry = 3;
 246        unsigned int sdca_cascade, scp_sdca_stat1, scp_sdca_stat2 = 0;
 247
 248        dev_dbg(&slave->dev,
 249                "%s control_port_stat=%x, sdca_cascade=%x", __func__,
 250                status->control_port, status->sdca_cascade);
 251
 252        if (cancel_delayed_work_sync(&rt711->jack_detect_work)) {
 253                dev_warn(&slave->dev, "%s the pending delayed_work was cancelled", __func__);
 254                /* avoid the HID owner doesn't change to device */
 255                if (rt711->scp_sdca_stat2)
 256                        scp_sdca_stat2 = rt711->scp_sdca_stat2;
 257        }
 258
 259        /*
 260         * The critical section below intentionally protects a rather large piece of code.
 261         * We don't want to allow the system suspend to disable an interrupt while we are
 262         * processing it, which could be problematic given the quirky SoundWire interrupt
 263         * scheme. We do want however to prevent new workqueues from being scheduled if
 264         * the disable_irq flag was set during system suspend.
 265         */
 266        mutex_lock(&rt711->disable_irq_lock);
 267
 268        ret = sdw_read_no_pm(rt711->slave, SDW_SCP_SDCA_INT1);
 269        if (ret < 0)
 270                goto io_error;
 271        rt711->scp_sdca_stat1 = ret;
 272        ret = sdw_read_no_pm(rt711->slave, SDW_SCP_SDCA_INT2);
 273        if (ret < 0)
 274                goto io_error;
 275        rt711->scp_sdca_stat2 = ret;
 276        if (scp_sdca_stat2)
 277                rt711->scp_sdca_stat2 |= scp_sdca_stat2;
 278
 279        do {
 280                /* clear flag */
 281                ret = sdw_read_no_pm(rt711->slave, SDW_SCP_SDCA_INT1);
 282                if (ret < 0)
 283                        goto io_error;
 284                if (ret & SDW_SCP_SDCA_INTMASK_SDCA_0) {
 285                        ret = sdw_write_no_pm(rt711->slave, SDW_SCP_SDCA_INT1,
 286                                                SDW_SCP_SDCA_INTMASK_SDCA_0);
 287                        if (ret < 0)
 288                                goto io_error;
 289                }
 290                ret = sdw_read_no_pm(rt711->slave, SDW_SCP_SDCA_INT2);
 291                if (ret < 0)
 292                        goto io_error;
 293                if (ret & SDW_SCP_SDCA_INTMASK_SDCA_8) {
 294                        ret = sdw_write_no_pm(rt711->slave, SDW_SCP_SDCA_INT2,
 295                                                SDW_SCP_SDCA_INTMASK_SDCA_8);
 296                        if (ret < 0)
 297                                goto io_error;
 298                }
 299
 300                /* check if flag clear or not */
 301                ret = sdw_read_no_pm(rt711->slave, SDW_DP0_INT);
 302                if (ret < 0)
 303                        goto io_error;
 304                sdca_cascade = ret & SDW_DP0_SDCA_CASCADE;
 305
 306                ret = sdw_read_no_pm(rt711->slave, SDW_SCP_SDCA_INT1);
 307                if (ret < 0)
 308                        goto io_error;
 309                scp_sdca_stat1 = ret & SDW_SCP_SDCA_INTMASK_SDCA_0;
 310
 311                ret = sdw_read_no_pm(rt711->slave, SDW_SCP_SDCA_INT2);
 312                if (ret < 0)
 313                        goto io_error;
 314                scp_sdca_stat2 = ret & SDW_SCP_SDCA_INTMASK_SDCA_8;
 315
 316                stat = scp_sdca_stat1 || scp_sdca_stat2 || sdca_cascade;
 317
 318                count++;
 319        } while (stat != 0 && count < retry);
 320
 321        if (stat)
 322                dev_warn(&slave->dev,
 323                        "%s scp_sdca_stat1=0x%x, scp_sdca_stat2=0x%x\n", __func__,
 324                        rt711->scp_sdca_stat1, rt711->scp_sdca_stat2);
 325
 326        if (status->sdca_cascade && !rt711->disable_irq)
 327                mod_delayed_work(system_power_efficient_wq,
 328                        &rt711->jack_detect_work, msecs_to_jiffies(30));
 329
 330        mutex_unlock(&rt711->disable_irq_lock);
 331
 332        return 0;
 333
 334io_error:
 335        mutex_unlock(&rt711->disable_irq_lock);
 336        pr_err_ratelimited("IO error in %s, ret %d\n", __func__, ret);
 337        return ret;
 338}
 339
 340static struct sdw_slave_ops rt711_sdca_slave_ops = {
 341        .read_prop = rt711_sdca_read_prop,
 342        .interrupt_callback = rt711_sdca_interrupt_callback,
 343        .update_status = rt711_sdca_update_status,
 344};
 345
 346static int rt711_sdca_sdw_probe(struct sdw_slave *slave,
 347                                const struct sdw_device_id *id)
 348{
 349        struct regmap *regmap, *mbq_regmap;
 350
 351        /* Regmap Initialization */
 352        mbq_regmap = devm_regmap_init_sdw_mbq(slave, &rt711_sdca_mbq_regmap);
 353        if (IS_ERR(mbq_regmap))
 354                return PTR_ERR(mbq_regmap);
 355
 356        regmap = devm_regmap_init_sdw(slave, &rt711_sdca_regmap);
 357        if (IS_ERR(regmap))
 358                return PTR_ERR(regmap);
 359
 360        return rt711_sdca_init(&slave->dev, regmap, mbq_regmap, slave);
 361}
 362
 363static int rt711_sdca_sdw_remove(struct sdw_slave *slave)
 364{
 365        struct rt711_sdca_priv *rt711 = dev_get_drvdata(&slave->dev);
 366
 367        if (rt711 && rt711->hw_init) {
 368                cancel_delayed_work_sync(&rt711->jack_detect_work);
 369                cancel_delayed_work_sync(&rt711->jack_btn_check_work);
 370        }
 371
 372        return 0;
 373}
 374
 375static const struct sdw_device_id rt711_sdca_id[] = {
 376        SDW_SLAVE_ENTRY_EXT(0x025d, 0x711, 0x3, 0x1, 0),
 377        {},
 378};
 379MODULE_DEVICE_TABLE(sdw, rt711_sdca_id);
 380
 381static int __maybe_unused rt711_sdca_dev_suspend(struct device *dev)
 382{
 383        struct rt711_sdca_priv *rt711 = dev_get_drvdata(dev);
 384
 385        if (!rt711->hw_init)
 386                return 0;
 387
 388        cancel_delayed_work_sync(&rt711->jack_detect_work);
 389        cancel_delayed_work_sync(&rt711->jack_btn_check_work);
 390
 391        regcache_cache_only(rt711->regmap, true);
 392        regcache_cache_only(rt711->mbq_regmap, true);
 393
 394        return 0;
 395}
 396
 397static int __maybe_unused rt711_sdca_dev_system_suspend(struct device *dev)
 398{
 399        struct rt711_sdca_priv *rt711_sdca = dev_get_drvdata(dev);
 400        struct sdw_slave *slave = dev_to_sdw_dev(dev);
 401        int ret1, ret2;
 402
 403        if (!rt711_sdca->hw_init)
 404                return 0;
 405
 406        /*
 407         * prevent new interrupts from being handled after the
 408         * deferred work completes and before the parent disables
 409         * interrupts on the link
 410         */
 411        mutex_lock(&rt711_sdca->disable_irq_lock);
 412        rt711_sdca->disable_irq = true;
 413        ret1 = sdw_update_no_pm(slave, SDW_SCP_SDCA_INTMASK1,
 414                                SDW_SCP_SDCA_INTMASK_SDCA_0, 0);
 415        ret2 = sdw_update_no_pm(slave, SDW_SCP_SDCA_INTMASK2,
 416                                SDW_SCP_SDCA_INTMASK_SDCA_8, 0);
 417        mutex_unlock(&rt711_sdca->disable_irq_lock);
 418
 419        if (ret1 < 0 || ret2 < 0) {
 420                /* log but don't prevent suspend from happening */
 421                dev_dbg(&slave->dev, "%s: could not disable SDCA interrupts\n:", __func__);
 422        }
 423
 424        return rt711_sdca_dev_suspend(dev);
 425}
 426
 427#define RT711_PROBE_TIMEOUT 5000
 428
 429static int __maybe_unused rt711_sdca_dev_resume(struct device *dev)
 430{
 431        struct sdw_slave *slave = dev_to_sdw_dev(dev);
 432        struct rt711_sdca_priv *rt711 = dev_get_drvdata(dev);
 433        unsigned long time;
 434
 435        if (!rt711->first_hw_init)
 436                return 0;
 437
 438        if (!slave->unattach_request)
 439                goto regmap_sync;
 440
 441        time = wait_for_completion_timeout(&slave->initialization_complete,
 442                                msecs_to_jiffies(RT711_PROBE_TIMEOUT));
 443        if (!time) {
 444                dev_err(&slave->dev, "Initialization not complete, timed out\n");
 445                return -ETIMEDOUT;
 446        }
 447
 448regmap_sync:
 449        slave->unattach_request = 0;
 450        regcache_cache_only(rt711->regmap, false);
 451        regcache_sync(rt711->regmap);
 452        regcache_cache_only(rt711->mbq_regmap, false);
 453        regcache_sync(rt711->mbq_regmap);
 454        return 0;
 455}
 456
 457static const struct dev_pm_ops rt711_sdca_pm = {
 458        SET_SYSTEM_SLEEP_PM_OPS(rt711_sdca_dev_system_suspend, rt711_sdca_dev_resume)
 459        SET_RUNTIME_PM_OPS(rt711_sdca_dev_suspend, rt711_sdca_dev_resume, NULL)
 460};
 461
 462static struct sdw_driver rt711_sdca_sdw_driver = {
 463        .driver = {
 464                .name = "rt711-sdca",
 465                .owner = THIS_MODULE,
 466                .pm = &rt711_sdca_pm,
 467        },
 468        .probe = rt711_sdca_sdw_probe,
 469        .remove = rt711_sdca_sdw_remove,
 470        .ops = &rt711_sdca_slave_ops,
 471        .id_table = rt711_sdca_id,
 472};
 473module_sdw_driver(rt711_sdca_sdw_driver);
 474
 475MODULE_DESCRIPTION("ASoC RT711 SDCA SDW driver");
 476MODULE_AUTHOR("Shuming Fan <shumingf@realtek.com>");
 477MODULE_LICENSE("GPL");
 478
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.