root/drivers/hwmon/ltq-cputemp.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ltq_cputemp_enable
  2. ltq_cputemp_disable
  3. ltq_read
  4. ltq_is_visible
  5. ltq_cputemp_probe

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /* Lantiq cpu temperature sensor driver
   3  *
   4  * Copyright (C) 2017 Florian Eckert <fe@dev.tdt.de>
   5  */
   6 
   7 #include <linux/bitops.h>
   8 #include <linux/delay.h>
   9 #include <linux/hwmon.h>
  10 #include <linux/hwmon-sysfs.h>
  11 #include <linux/init.h>
  12 #include <linux/module.h>
  13 #include <linux/of_device.h>
  14 
  15 #include <lantiq_soc.h>
  16 
  17 /* gphy1 configuration register contains cpu temperature */
  18 #define CGU_GPHY1_CR   0x0040
  19 #define CGU_TEMP_PD    BIT(19)
  20 
  21 static void ltq_cputemp_enable(void)
  22 {
  23         ltq_cgu_w32(ltq_cgu_r32(CGU_GPHY1_CR) | CGU_TEMP_PD, CGU_GPHY1_CR);
  24 }
  25 
  26 static void ltq_cputemp_disable(void *data)
  27 {
  28         ltq_cgu_w32(ltq_cgu_r32(CGU_GPHY1_CR) & ~CGU_TEMP_PD, CGU_GPHY1_CR);
  29 }
  30 
  31 static int ltq_read(struct device *dev, enum hwmon_sensor_types type,
  32                     u32 attr, int channel, long *temp)
  33 {
  34         int value;
  35 
  36         switch (attr) {
  37         case hwmon_temp_input:
  38                 /* get the temperature including one decimal place */
  39                 value = (ltq_cgu_r32(CGU_GPHY1_CR) >> 9) & 0x01FF;
  40                 value = value * 5;
  41                 /* range -38 to +154 °C, register value zero is -38.0 °C */
  42                 value -= 380;
  43                 /* scale temp to millidegree */
  44                 value = value * 100;
  45                 break;
  46         default:
  47                 return -EOPNOTSUPP;
  48         }
  49 
  50         *temp = value;
  51         return 0;
  52 }
  53 
  54 static umode_t ltq_is_visible(const void *_data, enum hwmon_sensor_types type,
  55                               u32 attr, int channel)
  56 {
  57         if (type != hwmon_temp)
  58                 return 0;
  59 
  60         switch (attr) {
  61         case hwmon_temp_input:
  62                 return 0444;
  63         default:
  64                 return 0;
  65         }
  66 }
  67 
  68 static const struct hwmon_channel_info *ltq_info[] = {
  69         HWMON_CHANNEL_INFO(chip,
  70                            HWMON_C_REGISTER_TZ),
  71         HWMON_CHANNEL_INFO(temp,
  72                            HWMON_T_INPUT),
  73         NULL
  74 };
  75 
  76 static const struct hwmon_ops ltq_hwmon_ops = {
  77         .is_visible = ltq_is_visible,
  78         .read = ltq_read,
  79 };
  80 
  81 static const struct hwmon_chip_info ltq_chip_info = {
  82         .ops = &ltq_hwmon_ops,
  83         .info = ltq_info,
  84 };
  85 
  86 static int ltq_cputemp_probe(struct platform_device *pdev)
  87 {
  88         struct device *hwmon_dev;
  89         int err = 0;
  90 
  91         /* available on vr9 v1.2 SoCs only */
  92         if (ltq_soc_type() != SOC_TYPE_VR9_2)
  93                 return -ENODEV;
  94 
  95         err = devm_add_action(&pdev->dev, ltq_cputemp_disable, NULL);
  96         if (err)
  97                 return err;
  98 
  99         ltq_cputemp_enable();
 100 
 101         hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev,
 102                                                          "ltq_cputemp",
 103                                                          NULL,
 104                                                          &ltq_chip_info,
 105                                                          NULL);
 106 
 107         if (IS_ERR(hwmon_dev)) {
 108                 dev_err(&pdev->dev, "Failed to register as hwmon device");
 109                 return PTR_ERR(hwmon_dev);
 110         }
 111 
 112         return 0;
 113 }
 114 
 115 const struct of_device_id ltq_cputemp_match[] = {
 116         { .compatible = "lantiq,cputemp" },
 117         {},
 118 };
 119 MODULE_DEVICE_TABLE(of, ltq_cputemp_match);
 120 
 121 static struct platform_driver ltq_cputemp_driver = {
 122         .probe = ltq_cputemp_probe,
 123         .driver = {
 124                 .name = "ltq-cputemp",
 125                 .of_match_table = ltq_cputemp_match,
 126         },
 127 };
 128 
 129 module_platform_driver(ltq_cputemp_driver);
 130 
 131 MODULE_AUTHOR("Florian Eckert <fe@dev.tdt.de>");
 132 MODULE_DESCRIPTION("Lantiq cpu temperature sensor driver");
 133 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */