SMC keys come in many data types, and Intel Macs use a lot
that macsmc-hwmon couldn't read, such as the signed fixed
point types like sp1e.

Add support for the common integer and fixed point types,
and allow writing fan speeds.

Signed-off-by: Atharva Tiwari <[email protected]>
---
 drivers/hwmon/macsmc-hwmon.c | 310 +++++++++++++++++++++++++++++++++++
 1 file changed, 310 insertions(+)

diff --git a/drivers/hwmon/macsmc-hwmon.c b/drivers/hwmon/macsmc-hwmon.c
index 1500ec2cc..2e74dcd66 100644
--- a/drivers/hwmon/macsmc-hwmon.c
+++ b/drivers/hwmon/macsmc-hwmon.c
@@ -221,6 +221,313 @@ static int macsmc_hwmon_read_key(struct apple_smc *smc,
                        *val = (long)ioft;
                break;
        }
+       /* unsigned 8-bit integer */
+       case __SMC_KEY('u', 'i', '8', ' '): {
+               u8 ui8 = 0;
+
+               ret = apple_smc_read_u8(smc, sensor->macsmc_key, &ui8);
+               if (ret)
+                       return ret;
+
+               *val = ui8 * scale;
+               break;
+       }
+       /* signed 8-bit integer */
+       case __SMC_KEY('s', 'i', '8', ' '): {
+               s8 si8 = 0;
+
+               ret = apple_smc_read_s8(smc, sensor->macsmc_key, &si8);
+               if (ret)
+                       return ret;
+
+               *val = si8 * scale;
+               break;
+       }
+       /* unsigned 16-bit integer */
+       case __SMC_KEY('u', 'i', '1', '6'): {
+               u16 ui16 = 0;
+
+               ret = apple_smc_read_u16(smc, sensor->macsmc_key, &ui16);
+               if (ret)
+                       return ret;
+
+               *val = ui16 * scale;
+               break;
+       }
+       /* signed 16-bit integer */
+       case __SMC_KEY('s', 'i', '1', '6'): {
+               s16 si16 = 0;
+
+               ret = apple_smc_read_s16(smc, sensor->macsmc_key, &si16);
+               if (ret)
+                       return ret;
+
+               *val = si16 * scale;
+               break;
+       }
+       /* unsigned 32-bit integer */
+       case __SMC_KEY('u', 'i', '3', '2'): {
+               u32 ui32 = 0;
+
+               ret = apple_smc_read_u32(smc, sensor->macsmc_key, &ui32);
+               if (ret)
+                       return ret;
+
+               *val = ui32 * scale;
+               break;
+       }
+       /* signed 32-bit integer */
+       case __SMC_KEY('s', 'i', '3', '2'): {
+               s32 si32;
+
+               ret = apple_smc_read_s32(smc, sensor->macsmc_key, &si32);
+               if (ret)
+                       return ret;
+
+               *val = si32 * scale;
+               break;
+       }
+       /* 2.14 unsigned fixed point decimal */
+       case __SMC_KEY('f', 'p', '2', 'e'): {
+               u16 fp2e;
+
+               ret = apple_smc_read_u16(smc, sensor->macsmc_key, &fp2e);
+               if (ret)
+                       return ret;
+
+               *val = mult_frac(be16_to_cpu(fp2e), scale, BIT(14));
+               break;
+       }
+
+       /* 3.13 unsigned fixed point decimal */
+       case __SMC_KEY('f', 'p', '3', 'd'): {
+               u16 fp3d;
+
+               ret = apple_smc_read_u16(smc, sensor->macsmc_key, &fp3d);
+               if (ret)
+                       return ret;
+
+               *val = mult_frac(be16_to_cpu(fp3d), scale, BIT(13));
+               break;
+       }
+
+       /* 4.12 unsigned fixed point decimal */
+       case __SMC_KEY('f', 'p', '4', 'c'): {
+               u16 fp4c;
+
+               ret = apple_smc_read_u16(smc, sensor->macsmc_key, &fp4c);
+               if (ret)
+                       return ret;
+
+               *val = mult_frac(be16_to_cpu(fp4c), scale, BIT(12));
+               break;
+       }
+
+       /* 5.11 unsigned fixed point decimal */
+       case __SMC_KEY('f', 'p', '5', 'b'): {
+               u16 fp5b;
+
+               ret = apple_smc_read_u16(smc, sensor->macsmc_key, &fp5b);
+               if (ret)
+                       return ret;
+
+               *val = mult_frac(be16_to_cpu(fp5b), scale, BIT(11));
+               break;
+       }
+
+       /* 6.10 unsigned fixed point decimal */
+       case __SMC_KEY('f', 'p', '6', 'a'): {
+               u16 fp6a;
+
+               ret = apple_smc_read_u16(smc, sensor->macsmc_key, &fp6a);
+               if (ret)
+                       return ret;
+
+               *val = mult_frac(be16_to_cpu(fp6a), scale, BIT(10));
+               break;
+       }
+
+       /* 8.8 unsigned fixed point decimal */
+       case __SMC_KEY('f', 'p', '8', '8'): {
+               u16 fp88;
+
+               ret = apple_smc_read_u16(smc, sensor->macsmc_key, &fp88);
+               if (ret)
+                       return ret;
+
+               *val = mult_frac(be16_to_cpu(fp88), scale, BIT(8));
+               break;
+       }
+       /* 14.2 fixed point decimal */
+       case __SMC_KEY('f', 'p', 'e', '2'): {
+               /*
+                * fpe2 is only used for fan stats and fan control
+                * so precision is not needed
+                */
+               u16 fpe2;
+
+               ret = apple_smc_read_u16(smc, sensor->macsmc_key, &fpe2);
+               if (ret)
+                       return ret;
+
+               *val = (be16_to_cpu(fpe2) >> 2);
+               break;
+       }
+       /* 1.14 signed fixed point decimal */
+       case __SMC_KEY('s', 'p', '1', 'e'): {
+               s16 sp1e;
+
+               ret = apple_smc_read_s16(smc, sensor->macsmc_key, &sp1e);
+               if (ret)
+                       return ret;
+
+               *val = mult_frac((s16)be16_to_cpu(sp1e), scale, BIT(14));
+               break;
+       }
+
+       /* 2.13 signed fixed point decimal */
+       case __SMC_KEY('s', 'p', '2', 'd'): {
+               s16 sp2d;
+
+               ret = apple_smc_read_s16(smc, sensor->macsmc_key, &sp2d);
+               if (ret)
+                       return ret;
+
+               *val = mult_frac((s16)be16_to_cpu(sp2d), scale, BIT(13));
+               break;
+       }
+
+       /* 3.12 signed fixed point decimal */
+       case __SMC_KEY('s', 'p', '3', 'c'): {
+               s16 sp3c;
+
+               ret = apple_smc_read_s16(smc, sensor->macsmc_key, &sp3c);
+               if (ret)
+                       return ret;
+
+               *val = mult_frac((s16)be16_to_cpu(sp3c), scale, BIT(12));
+               break;
+       }
+
+       /* 4.11 signed fixed point decimal */
+       case __SMC_KEY('s', 'p', '4', 'b'): {
+               s16 sp4b;
+
+               ret = apple_smc_read_s16(smc, sensor->macsmc_key, &sp4b);
+               if (ret)
+                       return ret;
+
+               *val = mult_frac((s16)be16_to_cpu(sp4b), scale, BIT(11));
+               break;
+       }
+
+       /* 5.10 signed fixed point decimal */
+       case __SMC_KEY('s', 'p', '5', 'a'): {
+               s16 sp5a;
+
+               ret = apple_smc_read_s16(smc, sensor->macsmc_key, &sp5a);
+               if (ret)
+                       return ret;
+
+               *val = mult_frac((s16)be16_to_cpu(sp5a), scale, BIT(10));
+               break;
+       }
+
+       /* 6.9 signed fixed point decimal */
+       case __SMC_KEY('s', 'p', '6', '9'): {
+               s16 sp69;
+
+               ret = apple_smc_read_s16(smc, sensor->macsmc_key, &sp69);
+               if (ret)
+                       return ret;
+
+               *val = mult_frac((s16)be16_to_cpu(sp69), scale, BIT(9));
+               break;
+       }
+
+       /* 7.8 signed fixed point decimal */
+       case __SMC_KEY('s', 'p', '7', '8'): {
+               s16 sp78;
+
+               ret = apple_smc_read_s16(smc, sensor->macsmc_key, &sp78);
+               if (ret)
+                       return ret;
+
+               *val = mult_frac((s16)be16_to_cpu(sp78), scale, BIT(8));
+               break;
+       }
+
+       /* 8.7 signed fixed point decimal */
+       case __SMC_KEY('s', 'p', '8', '7'): {
+               s16 sp87;
+
+               ret = apple_smc_read_s16(smc, sensor->macsmc_key, &sp87);
+               if (ret)
+                       return ret;
+
+               *val = mult_frac((s16)be16_to_cpu(sp87), scale, BIT(7));
+               break;
+       }
+
+       /* 9.6 signed fixed point decimal */
+       case __SMC_KEY('s', 'p', '9', '6'): {
+               s16 sp96;
+
+               ret = apple_smc_read_s16(smc, sensor->macsmc_key, &sp96);
+               if (ret)
+                       return ret;
+
+               *val = mult_frac((s16)be16_to_cpu(sp96), scale, BIT(6));
+               break;
+       }
+
+       /* 10.5 signed fixed point decimal */
+       case __SMC_KEY('s', 'p', 'a', '5'): {
+               s16 spa5;
+
+               ret = apple_smc_read_s16(smc, sensor->macsmc_key, &spa5);
+               if (ret)
+                       return ret;
+
+               *val = mult_frac((s16)be16_to_cpu(spa5), scale, BIT(5));
+               break;
+       }
+
+       /* 12.3 signed fixed point decimal */
+       case __SMC_KEY('s', 'p', 'c', '3'): {
+               s16 spc3;
+
+               ret = apple_smc_read_s16(smc, sensor->macsmc_key, &spc3);
+               if (ret)
+                       return ret;
+
+               *val = mult_frac((s16)be16_to_cpu(spc3), scale, BIT(3));
+               break;
+       }
+
+       /* 13.2 signed fixed point decimal */
+       case __SMC_KEY('s', 'p', 'd', '2'): {
+               s16 spd2;
+
+               ret = apple_smc_read_s16(smc, sensor->macsmc_key, &spd2);
+               if (ret)
+                       return ret;
+
+               *val = mult_frac((s16)be16_to_cpu(spd2), scale, BIT(2));
+               break;
+       }
+
+       /* 15.0 signed fixed point decimal */
+       case __SMC_KEY('s', 'p', 'f', '0'): {
+               s16 spf0;
+
+               ret = apple_smc_read_s16(smc, sensor->macsmc_key, &spf0);
+               if (ret)
+                       return ret;
+
+               *val = (s16)be16_to_cpu(spf0) * scale;
+               break;
+       }
        default:
                return -EOPNOTSUPP;
        }
@@ -263,6 +570,9 @@ static int macsmc_hwmon_write_key(struct apple_smc *smc,
        /* unsigned 8-bit integer */
        case __SMC_KEY('u', 'i', '8', ' '):
                return apple_smc_write_u8(smc, sensor->macsmc_key, val);
+       /* 14.2 fixed point decimal */
+       case __SMC_KEY('f', 'p', 'e', '2'):
+               return apple_smc_write_u16(smc, sensor->macsmc_key, 
cpu_to_be16(val << 2));
        default:
                return -EOPNOTSUPP;
        }
-- 
2.55.0


Reply via email to