linux/drivers/hwmon/mr75203.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (C) 2020 MaxLinear, Inc.
   4 *
   5 * This driver is a hardware monitoring driver for PVT controller
   6 * (MR75203) which is used to configure & control Moortec embedded
   7 * analog IP to enable multiple embedded temperature sensor(TS),
   8 * voltage monitor(VM) & process detector(PD) modules.
   9 */
  10#include <linux/bits.h>
  11#include <linux/clk.h>
  12#include <linux/hwmon.h>
  13#include <linux/module.h>
  14#include <linux/mod_devicetable.h>
  15#include <linux/mutex.h>
  16#include <linux/platform_device.h>
  17#include <linux/property.h>
  18#include <linux/regmap.h>
  19#include <linux/reset.h>
  20
  21/* PVT Common register */
  22#define PVT_IP_CONFIG   0x04
  23#define TS_NUM_MSK      GENMASK(4, 0)
  24#define TS_NUM_SFT      0
  25#define PD_NUM_MSK      GENMASK(12, 8)
  26#define PD_NUM_SFT      8
  27#define VM_NUM_MSK      GENMASK(20, 16)
  28#define VM_NUM_SFT      16
  29#define CH_NUM_MSK      GENMASK(31, 24)
  30#define CH_NUM_SFT      24
  31
  32/* Macro Common Register */
  33#define CLK_SYNTH               0x00
  34#define CLK_SYNTH_LO_SFT        0
  35#define CLK_SYNTH_HI_SFT        8
  36#define CLK_SYNTH_HOLD_SFT      16
  37#define CLK_SYNTH_EN            BIT(24)
  38#define CLK_SYS_CYCLES_MAX      514
  39#define CLK_SYS_CYCLES_MIN      2
  40#define HZ_PER_MHZ              1000000L
  41
  42#define SDIF_DISABLE    0x04
  43
  44#define SDIF_STAT       0x08
  45#define SDIF_BUSY       BIT(0)
  46#define SDIF_LOCK       BIT(1)
  47
  48#define SDIF_W          0x0c
  49#define SDIF_PROG       BIT(31)
  50#define SDIF_WRN_W      BIT(27)
  51#define SDIF_WRN_R      0x00
  52#define SDIF_ADDR_SFT   24
  53
  54#define SDIF_HALT       0x10
  55#define SDIF_CTRL       0x14
  56#define SDIF_SMPL_CTRL  0x20
  57
  58/* TS & PD Individual Macro Register */
  59#define COM_REG_SIZE    0x40
  60
  61#define SDIF_DONE(n)    (COM_REG_SIZE + 0x14 + 0x40 * (n))
  62#define SDIF_SMPL_DONE  BIT(0)
  63
  64#define SDIF_DATA(n)    (COM_REG_SIZE + 0x18 + 0x40 * (n))
  65#define SAMPLE_DATA_MSK GENMASK(15, 0)
  66
  67#define HILO_RESET(n)   (COM_REG_SIZE + 0x2c + 0x40 * (n))
  68
  69/* VM Individual Macro Register */
  70#define VM_COM_REG_SIZE 0x200
  71#define VM_SDIF_DONE(n) (VM_COM_REG_SIZE + 0x34 + 0x200 * (n))
  72#define VM_SDIF_DATA(n) (VM_COM_REG_SIZE + 0x40 + 0x200 * (n))
  73
  74/* SDA Slave Register */
  75#define IP_CTRL                 0x00
  76#define IP_RST_REL              BIT(1)
  77#define IP_RUN_CONT             BIT(3)
  78#define IP_AUTO                 BIT(8)
  79#define IP_VM_MODE              BIT(10)
  80
  81#define IP_CFG                  0x01
  82#define CFG0_MODE_2             BIT(0)
  83#define CFG0_PARALLEL_OUT       0
  84#define CFG0_12_BIT             0
  85#define CFG1_VOL_MEAS_MODE      0
  86#define CFG1_PARALLEL_OUT       0
  87#define CFG1_14_BIT             0
  88
  89#define IP_DATA         0x03
  90
  91#define IP_POLL         0x04
  92#define VM_CH_INIT      BIT(20)
  93#define VM_CH_REQ       BIT(21)
  94
  95#define IP_TMR                  0x05
  96#define POWER_DELAY_CYCLE_256   0x80
  97#define POWER_DELAY_CYCLE_64    0x40
  98
  99#define PVT_POLL_DELAY_US       20
 100#define PVT_POLL_TIMEOUT_US     20000
 101#define PVT_H_CONST             100000
 102#define PVT_CAL5_CONST          2047
 103#define PVT_G_CONST             40000
 104#define PVT_CONV_BITS           10
 105#define PVT_N_CONST             90
 106#define PVT_R_CONST             245805
 107
 108struct pvt_device {
 109        struct regmap           *c_map;
 110        struct regmap           *t_map;
 111        struct regmap           *p_map;
 112        struct regmap           *v_map;
 113        struct clk              *clk;
 114        struct reset_control    *rst;
 115        u32                     t_num;
 116        u32                     p_num;
 117        u32                     v_num;
 118        u32                     ip_freq;
 119        u8                      *vm_idx;
 120};
 121
 122static umode_t pvt_is_visible(const void *data, enum hwmon_sensor_types type,
 123                              u32 attr, int channel)
 124{
 125        switch (type) {
 126        case hwmon_temp:
 127                if (attr == hwmon_temp_input)
 128                        return 0444;
 129                break;
 130        case hwmon_in:
 131                if (attr == hwmon_in_input)
 132                        return 0444;
 133                break;
 134        default:
 135                break;
 136        }
 137        return 0;
 138}
 139
 140static int pvt_read_temp(struct device *dev, u32 attr, int channel, long *val)
 141{
 142        struct pvt_device *pvt = dev_get_drvdata(dev);
 143        struct regmap *t_map = pvt->t_map;
 144        u32 stat, nbs;
 145        int ret;
 146        u64 tmp;
 147
 148        switch (attr) {
 149        case hwmon_temp_input:
 150                ret = regmap_read_poll_timeout(t_map, SDIF_DONE(channel),
 151                                               stat, stat & SDIF_SMPL_DONE,
 152                                               PVT_POLL_DELAY_US,
 153                                               PVT_POLL_TIMEOUT_US);
 154                if (ret)
 155                        return ret;
 156
 157                ret = regmap_read(t_map, SDIF_DATA(channel), &nbs);
 158                if(ret < 0)
 159                        return ret;
 160
 161                nbs &= SAMPLE_DATA_MSK;
 162
 163                /*
 164                 * Convert the register value to
 165                 * degrees centigrade temperature
 166                 */
 167                tmp = nbs * PVT_H_CONST;
 168                do_div(tmp, PVT_CAL5_CONST);
 169                *val = tmp - PVT_G_CONST - pvt->ip_freq;
 170
 171                return 0;
 172        default:
 173                return -EOPNOTSUPP;
 174        }
 175}
 176
 177static int pvt_read_in(struct device *dev, u32 attr, int channel, long *val)
 178{
 179        struct pvt_device *pvt = dev_get_drvdata(dev);
 180        struct regmap *v_map = pvt->v_map;
 181        u32 n, stat;
 182        u8 vm_idx;
 183        int ret;
 184
 185        if (channel >= pvt->v_num)
 186                return -EINVAL;
 187
 188        vm_idx = pvt->vm_idx[channel];
 189
 190        switch (attr) {
 191        case hwmon_in_input:
 192                ret = regmap_read_poll_timeout(v_map, VM_SDIF_DONE(vm_idx),
 193                                               stat, stat & SDIF_SMPL_DONE,
 194                                               PVT_POLL_DELAY_US,
 195                                               PVT_POLL_TIMEOUT_US);
 196                if (ret)
 197                        return ret;
 198
 199                ret = regmap_read(v_map, VM_SDIF_DATA(vm_idx), &n);
 200                if(ret < 0)
 201                        return ret;
 202
 203                n &= SAMPLE_DATA_MSK;
 204                /* Convert the N bitstream count into voltage */
 205                *val = (PVT_N_CONST * n - PVT_R_CONST) >> PVT_CONV_BITS;
 206
 207                return 0;
 208        default:
 209                return -EOPNOTSUPP;
 210        }
 211}
 212
 213static int pvt_read(struct device *dev, enum hwmon_sensor_types type,
 214                    u32 attr, int channel, long *val)
 215{
 216        switch (type) {
 217        case hwmon_temp:
 218                return pvt_read_temp(dev, attr, channel, val);
 219        case hwmon_in:
 220                return pvt_read_in(dev, attr, channel, val);
 221        default:
 222                return -EOPNOTSUPP;
 223        }
 224}
 225
 226static const u32 pvt_chip_config[] = {
 227        HWMON_C_REGISTER_TZ,
 228        0
 229};
 230
 231static const struct hwmon_channel_info pvt_chip = {
 232        .type = hwmon_chip,
 233        .config = pvt_chip_config,
 234};
 235
 236static struct hwmon_channel_info pvt_temp = {
 237        .type = hwmon_temp,
 238};
 239
 240static struct hwmon_channel_info pvt_in = {
 241        .type = hwmon_in,
 242};
 243
 244static const struct hwmon_ops pvt_hwmon_ops = {
 245        .is_visible = pvt_is_visible,
 246        .read = pvt_read,
 247};
 248
 249static struct hwmon_chip_info pvt_chip_info = {
 250        .ops = &pvt_hwmon_ops,
 251};
 252
 253static int pvt_init(struct pvt_device *pvt)
 254{
 255        u16 sys_freq, key, middle, low = 4, high = 8;
 256        struct regmap *t_map = pvt->t_map;
 257        struct regmap *p_map = pvt->p_map;
 258        struct regmap *v_map = pvt->v_map;
 259        u32 t_num = pvt->t_num;
 260        u32 p_num = pvt->p_num;
 261        u32 v_num = pvt->v_num;
 262        u32 clk_synth, val;
 263        int ret;
 264
 265        sys_freq = clk_get_rate(pvt->clk) / HZ_PER_MHZ;
 266        while (high >= low) {
 267                middle = (low + high + 1) / 2;
 268                key = DIV_ROUND_CLOSEST(sys_freq, middle);
 269                if (key > CLK_SYS_CYCLES_MAX) {
 270                        low = middle + 1;
 271                        continue;
 272                } else if (key < CLK_SYS_CYCLES_MIN) {
 273                        high = middle - 1;
 274                        continue;
 275                } else {
 276                        break;
 277                }
 278        }
 279
 280        /*
 281         * The system supports 'clk_sys' to 'clk_ip' frequency ratios
 282         * from 2:1 to 512:1
 283         */
 284        key = clamp_val(key, CLK_SYS_CYCLES_MIN, CLK_SYS_CYCLES_MAX) - 2;
 285
 286        clk_synth = ((key + 1) >> 1) << CLK_SYNTH_LO_SFT |
 287                    (key >> 1) << CLK_SYNTH_HI_SFT |
 288                    (key >> 1) << CLK_SYNTH_HOLD_SFT | CLK_SYNTH_EN;
 289
 290        pvt->ip_freq = sys_freq * 100 / (key + 2);
 291
 292        if (t_num) {
 293                ret = regmap_write(t_map, SDIF_SMPL_CTRL, 0x0);
 294                if(ret < 0)
 295                        return ret;
 296
 297                ret = regmap_write(t_map, SDIF_HALT, 0x0);
 298                if(ret < 0)
 299                        return ret;
 300
 301                ret = regmap_write(t_map, CLK_SYNTH, clk_synth);
 302                if(ret < 0)
 303                        return ret;
 304
 305                ret = regmap_write(t_map, SDIF_DISABLE, 0x0);
 306                if(ret < 0)
 307                        return ret;
 308
 309                ret = regmap_read_poll_timeout(t_map, SDIF_STAT,
 310                                               val, !(val & SDIF_BUSY),
 311                                               PVT_POLL_DELAY_US,
 312                                               PVT_POLL_TIMEOUT_US);
 313                if (ret)
 314                        return ret;
 315
 316                val = CFG0_MODE_2 | CFG0_PARALLEL_OUT | CFG0_12_BIT |
 317                      IP_CFG << SDIF_ADDR_SFT | SDIF_WRN_W | SDIF_PROG;
 318                ret = regmap_write(t_map, SDIF_W, val);
 319                if(ret < 0)
 320                        return ret;
 321
 322                ret = regmap_read_poll_timeout(t_map, SDIF_STAT,
 323                                               val, !(val & SDIF_BUSY),
 324                                               PVT_POLL_DELAY_US,
 325                                               PVT_POLL_TIMEOUT_US);
 326                if (ret)
 327                        return ret;
 328
 329                val = POWER_DELAY_CYCLE_256 | IP_TMR << SDIF_ADDR_SFT |
 330                              SDIF_WRN_W | SDIF_PROG;
 331                ret = regmap_write(t_map, SDIF_W, val);
 332                if(ret < 0)
 333                        return ret;
 334
 335                ret = regmap_read_poll_timeout(t_map, SDIF_STAT,
 336                                               val, !(val & SDIF_BUSY),
 337                                               PVT_POLL_DELAY_US,
 338                                               PVT_POLL_TIMEOUT_US);
 339                if (ret)
 340                        return ret;
 341
 342                val = IP_RST_REL | IP_RUN_CONT | IP_AUTO |
 343                      IP_CTRL << SDIF_ADDR_SFT |
 344                      SDIF_WRN_W | SDIF_PROG;
 345                ret = regmap_write(t_map, SDIF_W, val);
 346                if(ret < 0)
 347                        return ret;
 348        }
 349
 350        if (p_num) {
 351                ret = regmap_write(p_map, SDIF_HALT, 0x0);
 352                if(ret < 0)
 353                        return ret;
 354
 355                ret = regmap_write(p_map, SDIF_DISABLE, BIT(p_num) - 1);
 356                if(ret < 0)
 357                        return ret;
 358
 359                ret = regmap_write(p_map, CLK_SYNTH, clk_synth);
 360                if(ret < 0)
 361                        return ret;
 362        }
 363
 364        if (v_num) {
 365                ret = regmap_write(v_map, SDIF_SMPL_CTRL, 0x0);
 366                if(ret < 0)
 367                        return ret;
 368
 369                ret = regmap_write(v_map, SDIF_HALT, 0x0);
 370                if(ret < 0)
 371                        return ret;
 372
 373                ret = regmap_write(v_map, CLK_SYNTH, clk_synth);
 374                if(ret < 0)
 375                        return ret;
 376
 377                ret = regmap_write(v_map, SDIF_DISABLE, 0x0);
 378                if(ret < 0)
 379                        return ret;
 380
 381                ret = regmap_read_poll_timeout(v_map, SDIF_STAT,
 382                                               val, !(val & SDIF_BUSY),
 383                                               PVT_POLL_DELAY_US,
 384                                               PVT_POLL_TIMEOUT_US);
 385                if (ret)
 386                        return ret;
 387
 388                val = CFG1_VOL_MEAS_MODE | CFG1_PARALLEL_OUT |
 389                      CFG1_14_BIT | IP_CFG << SDIF_ADDR_SFT |
 390                      SDIF_WRN_W | SDIF_PROG;
 391                ret = regmap_write(v_map, SDIF_W, val);
 392                if(ret < 0)
 393                        return ret;
 394
 395                ret = regmap_read_poll_timeout(v_map, SDIF_STAT,
 396                                               val, !(val & SDIF_BUSY),
 397                                               PVT_POLL_DELAY_US,
 398                                               PVT_POLL_TIMEOUT_US);
 399                if (ret)
 400                        return ret;
 401
 402                val = POWER_DELAY_CYCLE_64 | IP_TMR << SDIF_ADDR_SFT |
 403                      SDIF_WRN_W | SDIF_PROG;
 404                ret = regmap_write(v_map, SDIF_W, val);
 405                if(ret < 0)
 406                        return ret;
 407
 408                ret = regmap_read_poll_timeout(v_map, SDIF_STAT,
 409                                               val, !(val & SDIF_BUSY),
 410                                               PVT_POLL_DELAY_US,
 411                                               PVT_POLL_TIMEOUT_US);
 412                if (ret)
 413                        return ret;
 414
 415                val = IP_RST_REL | IP_RUN_CONT | IP_AUTO | IP_VM_MODE |
 416                      IP_CTRL << SDIF_ADDR_SFT |
 417                      SDIF_WRN_W | SDIF_PROG;
 418                ret = regmap_write(v_map, SDIF_W, val);
 419                if(ret < 0)
 420                        return ret;
 421        }
 422
 423        return 0;
 424}
 425
 426static struct regmap_config pvt_regmap_config = {
 427        .reg_bits = 32,
 428        .reg_stride = 4,
 429        .val_bits = 32,
 430};
 431
 432static int pvt_get_regmap(struct platform_device *pdev, char *reg_name,
 433                          struct pvt_device *pvt)
 434{
 435        struct device *dev = &pdev->dev;
 436        struct regmap **reg_map;
 437        void __iomem *io_base;
 438
 439        if (!strcmp(reg_name, "common"))
 440                reg_map = &pvt->c_map;
 441        else if (!strcmp(reg_name, "ts"))
 442                reg_map = &pvt->t_map;
 443        else if (!strcmp(reg_name, "pd"))
 444                reg_map = &pvt->p_map;
 445        else if (!strcmp(reg_name, "vm"))
 446                reg_map = &pvt->v_map;
 447        else
 448                return -EINVAL;
 449
 450        io_base = devm_platform_ioremap_resource_byname(pdev, reg_name);
 451        if (IS_ERR(io_base))
 452                return PTR_ERR(io_base);
 453
 454        pvt_regmap_config.name = reg_name;
 455        *reg_map = devm_regmap_init_mmio(dev, io_base, &pvt_regmap_config);
 456        if (IS_ERR(*reg_map)) {
 457                dev_err(dev, "failed to init register map\n");
 458                return PTR_ERR(*reg_map);
 459        }
 460
 461        return 0;
 462}
 463
 464static void pvt_clk_disable(void *data)
 465{
 466        struct pvt_device *pvt = data;
 467
 468        clk_disable_unprepare(pvt->clk);
 469}
 470
 471static int pvt_clk_enable(struct device *dev, struct pvt_device *pvt)
 472{
 473        int ret;
 474
 475        ret = clk_prepare_enable(pvt->clk);
 476        if (ret)
 477                return ret;
 478
 479        return devm_add_action_or_reset(dev, pvt_clk_disable, pvt);
 480}
 481
 482static void pvt_reset_control_assert(void *data)
 483{
 484        struct pvt_device *pvt = data;
 485
 486        reset_control_assert(pvt->rst);
 487}
 488
 489static int pvt_reset_control_deassert(struct device *dev, struct pvt_device *pvt)
 490{
 491        int ret;
 492
 493        ret = reset_control_deassert(pvt->rst);
 494        if (ret)
 495                return ret;
 496
 497        return devm_add_action_or_reset(dev, pvt_reset_control_assert, pvt);
 498}
 499
 500static int mr75203_probe(struct platform_device *pdev)
 501{
 502        const struct hwmon_channel_info **pvt_info;
 503        u32 ts_num, vm_num, pd_num, val, index, i;
 504        struct device *dev = &pdev->dev;
 505        u32 *temp_config, *in_config;
 506        struct device *hwmon_dev;
 507        struct pvt_device *pvt;
 508        int ret;
 509
 510        pvt = devm_kzalloc(dev, sizeof(*pvt), GFP_KERNEL);
 511        if (!pvt)
 512                return -ENOMEM;
 513
 514        ret = pvt_get_regmap(pdev, "common", pvt);
 515        if (ret)
 516                return ret;
 517
 518        pvt->clk = devm_clk_get(dev, NULL);
 519        if (IS_ERR(pvt->clk))
 520                return dev_err_probe(dev, PTR_ERR(pvt->clk), "failed to get clock\n");
 521
 522        ret = pvt_clk_enable(dev, pvt);
 523        if (ret) {
 524                dev_err(dev, "failed to enable clock\n");
 525                return ret;
 526        }
 527
 528        pvt->rst = devm_reset_control_get_exclusive(dev, NULL);
 529        if (IS_ERR(pvt->rst))
 530                return dev_err_probe(dev, PTR_ERR(pvt->rst),
 531                                     "failed to get reset control\n");
 532
 533        ret = pvt_reset_control_deassert(dev, pvt);
 534        if (ret)
 535                return dev_err_probe(dev, ret, "cannot deassert reset control\n");
 536
 537        ret = regmap_read(pvt->c_map, PVT_IP_CONFIG, &val);
 538        if(ret < 0)
 539                return ret;
 540
 541        ts_num = (val & TS_NUM_MSK) >> TS_NUM_SFT;
 542        pd_num = (val & PD_NUM_MSK) >> PD_NUM_SFT;
 543        vm_num = (val & VM_NUM_MSK) >> VM_NUM_SFT;
 544        pvt->t_num = ts_num;
 545        pvt->p_num = pd_num;
 546        pvt->v_num = vm_num;
 547        val = 0;
 548        if (ts_num)
 549                val++;
 550        if (vm_num)
 551                val++;
 552        if (!val)
 553                return -ENODEV;
 554
 555        pvt_info = devm_kcalloc(dev, val + 2, sizeof(*pvt_info), GFP_KERNEL);
 556        if (!pvt_info)
 557                return -ENOMEM;
 558        pvt_info[0] = &pvt_chip;
 559        index = 1;
 560
 561        if (ts_num) {
 562                ret = pvt_get_regmap(pdev, "ts", pvt);
 563                if (ret)
 564                        return ret;
 565
 566                temp_config = devm_kcalloc(dev, ts_num + 1,
 567                                           sizeof(*temp_config), GFP_KERNEL);
 568                if (!temp_config)
 569                        return -ENOMEM;
 570
 571                memset32(temp_config, HWMON_T_INPUT, ts_num);
 572                pvt_temp.config = temp_config;
 573                pvt_info[index++] = &pvt_temp;
 574        }
 575
 576        if (pd_num) {
 577                ret = pvt_get_regmap(pdev, "pd", pvt);
 578                if (ret)
 579                        return ret;
 580        }
 581
 582        if (vm_num) {
 583                u32 num = vm_num;
 584
 585                ret = pvt_get_regmap(pdev, "vm", pvt);
 586                if (ret)
 587                        return ret;
 588
 589                pvt->vm_idx = devm_kcalloc(dev, vm_num, sizeof(*pvt->vm_idx),
 590                                           GFP_KERNEL);
 591                if (!pvt->vm_idx)
 592                        return -ENOMEM;
 593
 594                ret = device_property_read_u8_array(dev, "intel,vm-map",
 595                                                    pvt->vm_idx, vm_num);
 596                if (ret) {
 597                        num = 0;
 598                } else {
 599                        for (i = 0; i < vm_num; i++)
 600                                if (pvt->vm_idx[i] >= vm_num ||
 601                                    pvt->vm_idx[i] == 0xff) {
 602                                        num = i;
 603                                        break;
 604                                }
 605                }
 606
 607                /*
 608                 * Incase intel,vm-map property is not defined, we assume
 609                 * incremental channel numbers.
 610                 */
 611                for (i = num; i < vm_num; i++)
 612                        pvt->vm_idx[i] = i;
 613
 614                in_config = devm_kcalloc(dev, num + 1,
 615                                         sizeof(*in_config), GFP_KERNEL);
 616                if (!in_config)
 617                        return -ENOMEM;
 618
 619                memset32(in_config, HWMON_I_INPUT, num);
 620                in_config[num] = 0;
 621                pvt_in.config = in_config;
 622
 623                pvt_info[index++] = &pvt_in;
 624        }
 625
 626        ret = pvt_init(pvt);
 627        if (ret) {
 628                dev_err(dev, "failed to init pvt: %d\n", ret);
 629                return ret;
 630        }
 631
 632        pvt_chip_info.info = pvt_info;
 633        hwmon_dev = devm_hwmon_device_register_with_info(dev, "pvt",
 634                                                         pvt,
 635                                                         &pvt_chip_info,
 636                                                         NULL);
 637
 638        return PTR_ERR_OR_ZERO(hwmon_dev);
 639}
 640
 641static const struct of_device_id moortec_pvt_of_match[] = {
 642        { .compatible = "moortec,mr75203" },
 643        { }
 644};
 645MODULE_DEVICE_TABLE(of, moortec_pvt_of_match);
 646
 647static struct platform_driver moortec_pvt_driver = {
 648        .driver = {
 649                .name = "moortec-pvt",
 650                .of_match_table = moortec_pvt_of_match,
 651        },
 652        .probe = mr75203_probe,
 653};
 654module_platform_driver(moortec_pvt_driver);
 655
 656MODULE_LICENSE("GPL v2");
 657