Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _SMU_H
0003 #define _SMU_H
0004 
0005 /*
0006  * Definitions for talking to the SMU chip in newer G5 PowerMacs
0007  */
0008 #ifdef __KERNEL__
0009 #include <linux/list.h>
0010 #endif
0011 #include <linux/types.h>
0012 
0013 /*
0014  * Known SMU commands
0015  *
0016  * Most of what is below comes from looking at the Open Firmware driver,
0017  * though this is still incomplete and could use better documentation here
0018  * or there...
0019  */
0020 
0021 
0022 /*
0023  * Partition info commands
0024  *
0025  * These commands are used to retrieve the sdb-partition-XX datas from
0026  * the SMU. The length is always 2. First byte is the subcommand code
0027  * and second byte is the partition ID.
0028  *
0029  * The reply is 6 bytes:
0030  *
0031  *  - 0..1 : partition address
0032  *  - 2    : a byte containing the partition ID
0033  *  - 3    : length (maybe other bits are rest of header ?)
0034  *
0035  * The data must then be obtained with calls to another command:
0036  * SMU_CMD_MISC_ee_GET_DATABLOCK_REC (described below).
0037  */
0038 #define SMU_CMD_PARTITION_COMMAND       0x3e
0039 #define   SMU_CMD_PARTITION_LATEST      0x01
0040 #define   SMU_CMD_PARTITION_BASE        0x02
0041 #define   SMU_CMD_PARTITION_UPDATE      0x03
0042 
0043 
0044 /*
0045  * Fan control
0046  *
0047  * This is a "mux" for fan control commands. The command seem to
0048  * act differently based on the number of arguments. With 1 byte
0049  * of argument, this seem to be queries for fans status, setpoint,
0050  * etc..., while with 0xe arguments, we will set the fans speeds.
0051  *
0052  * Queries (1 byte arg):
0053  * ---------------------
0054  *
0055  * arg=0x01: read RPM fans status
0056  * arg=0x02: read RPM fans setpoint
0057  * arg=0x11: read PWM fans status
0058  * arg=0x12: read PWM fans setpoint
0059  *
0060  * the "status" queries return the current speed while the "setpoint" ones
0061  * return the programmed/target speed. It _seems_ that the result is a bit
0062  * mask in the first byte of active/available fans, followed by 6 words (16
0063  * bits) containing the requested speed.
0064  *
0065  * Setpoint (14 bytes arg):
0066  * ------------------------
0067  *
0068  * first arg byte is 0 for RPM fans and 0x10 for PWM. Second arg byte is the
0069  * mask of fans affected by the command. Followed by 6 words containing the
0070  * setpoint value for selected fans in the mask (or 0 if mask value is 0)
0071  */
0072 #define SMU_CMD_FAN_COMMAND         0x4a
0073 
0074 
0075 /*
0076  * Battery access
0077  *
0078  * Same command number as the PMU, could it be same syntax ?
0079  */
0080 #define SMU_CMD_BATTERY_COMMAND         0x6f
0081 #define   SMU_CMD_GET_BATTERY_INFO      0x00
0082 
0083 /*
0084  * Real time clock control
0085  *
0086  * This is a "mux", first data byte contains the "sub" command.
0087  * The "RTC" part of the SMU controls the date, time, powerup
0088  * timer, but also a PRAM
0089  *
0090  * Dates are in BCD format on 7 bytes:
0091  * [sec] [min] [hour] [weekday] [month day] [month] [year]
0092  * with month being 1 based and year minus 100
0093  */
0094 #define SMU_CMD_RTC_COMMAND         0x8e
0095 #define   SMU_CMD_RTC_SET_PWRUP_TIMER       0x00 /* i: 7 bytes date */
0096 #define   SMU_CMD_RTC_GET_PWRUP_TIMER       0x01 /* o: 7 bytes date */
0097 #define   SMU_CMD_RTC_STOP_PWRUP_TIMER      0x02
0098 #define   SMU_CMD_RTC_SET_PRAM_BYTE_ACC     0x20 /* i: 1 byte (address?) */
0099 #define   SMU_CMD_RTC_SET_PRAM_AUTOINC      0x21 /* i: 1 byte (data?) */
0100 #define   SMU_CMD_RTC_SET_PRAM_LO_BYTES     0x22 /* i: 10 bytes */
0101 #define   SMU_CMD_RTC_SET_PRAM_HI_BYTES     0x23 /* i: 10 bytes */
0102 #define   SMU_CMD_RTC_GET_PRAM_BYTE     0x28 /* i: 1 bytes (address?) */
0103 #define   SMU_CMD_RTC_GET_PRAM_LO_BYTES     0x29 /* o: 10 bytes */
0104 #define   SMU_CMD_RTC_GET_PRAM_HI_BYTES     0x2a /* o: 10 bytes */
0105 #define   SMU_CMD_RTC_SET_DATETIME      0x80 /* i: 7 bytes date */
0106 #define   SMU_CMD_RTC_GET_DATETIME      0x81 /* o: 7 bytes date */
0107 
0108  /*
0109   * i2c commands
0110   *
0111   * To issue an i2c command, first is to send a parameter block to
0112   * the SMU. This is a command of type 0x9a with 9 bytes of header
0113   * eventually followed by data for a write:
0114   *
0115   * 0: bus number (from device-tree usually, SMU has lots of busses !)
0116   * 1: transfer type/format (see below)
0117   * 2: device address. For combined and combined4 type transfers, this
0118   *    is the "write" version of the address (bit 0x01 cleared)
0119   * 3: subaddress length (0..3)
0120   * 4: subaddress byte 0 (or only byte for subaddress length 1)
0121   * 5: subaddress byte 1
0122   * 6: subaddress byte 2
0123   * 7: combined address (device address for combined mode data phase)
0124   * 8: data length
0125   *
0126   * The transfer types are the same good old Apple ones it seems,
0127   * that is:
0128   *   - 0x00: Simple transfer
0129   *   - 0x01: Subaddress transfer (addr write + data tx, no restart)
0130   *   - 0x02: Combined transfer (addr write + restart + data tx)
0131   *
0132   * This is then followed by actual data for a write.
0133   *
0134   * At this point, the OF driver seems to have a limitation on transfer
0135   * sizes of 0xd bytes on reads and 0x5 bytes on writes. I do not know
0136   * whether this is just an OF limit due to some temporary buffer size
0137   * or if this is an SMU imposed limit. This driver has the same limitation
0138   * for now as I use a 0x10 bytes temporary buffer as well
0139   *
0140   * Once that is completed, a response is expected from the SMU. This is
0141   * obtained via a command of type 0x9a with a length of 1 byte containing
0142   * 0 as the data byte. OF also fills the rest of the data buffer with 0xff's
0143   * though I can't tell yet if this is actually necessary. Once this command
0144   * is complete, at this point, all I can tell is what OF does. OF tests
0145   * byte 0 of the reply:
0146   *   - on read, 0xfe or 0xfc : bus is busy, wait (see below) or nak ?
0147   *   - on read, 0x00 or 0x01 : reply is in buffer (after the byte 0)
0148   *   - on write, < 0 -> failure (immediate exit)
0149   *   - else, OF just exists (without error, weird)
0150   *
0151   * So on read, there is this wait-for-busy thing when getting a 0xfc or
0152   * 0xfe result. OF does a loop of up to 64 retries, waiting 20ms and
0153   * doing the above again until either the retries expire or the result
0154   * is no longer 0xfe or 0xfc
0155   *
0156   * The Darwin I2C driver is less subtle though. On any non-success status
0157   * from the response command, it waits 5ms and tries again up to 20 times,
0158   * it doesn't differentiate between fatal errors or "busy" status.
0159   *
0160   * This driver provides an asynchronous paramblock based i2c command
0161   * interface to be used either directly by low level code or by a higher
0162   * level driver interfacing to the linux i2c layer. The current
0163   * implementation of this relies on working timers & timer interrupts
0164   * though, so be careful of calling context for now. This may be "fixed"
0165   * in the future by adding a polling facility.
0166   */
0167 #define SMU_CMD_I2C_COMMAND         0x9a
0168           /* transfer types */
0169 #define   SMU_I2C_TRANSFER_SIMPLE   0x00
0170 #define   SMU_I2C_TRANSFER_STDSUB   0x01
0171 #define   SMU_I2C_TRANSFER_COMBINED 0x02
0172 
0173 /*
0174  * Power supply control
0175  *
0176  * The "sub" command is an ASCII string in the data, the
0177  * data length is that of the string.
0178  *
0179  * The VSLEW command can be used to get or set the voltage slewing.
0180  *  - length 5 (only "VSLEW") : it returns "DONE" and 3 bytes of
0181  *    reply at data offset 6, 7 and 8.
0182  *  - length 8 ("VSLEWxyz") has 3 additional bytes appended, and is
0183  *    used to set the voltage slewing point. The SMU replies with "DONE"
0184  * I yet have to figure out their exact meaning of those 3 bytes in
0185  * both cases. They seem to be:
0186  *  x = processor mask
0187  *  y = op. point index
0188  *  z = processor freq. step index
0189  * I haven't yet deciphered result codes
0190  *
0191  */
0192 #define SMU_CMD_POWER_COMMAND           0xaa
0193 #define   SMU_CMD_POWER_RESTART             "RESTART"
0194 #define   SMU_CMD_POWER_SHUTDOWN        "SHUTDOWN"
0195 #define   SMU_CMD_POWER_VOLTAGE_SLEW        "VSLEW"
0196 
0197 /*
0198  * Read ADC sensors
0199  *
0200  * This command takes one byte of parameter: the sensor ID (or "reg"
0201  * value in the device-tree) and returns a 16 bits value
0202  */
0203 #define SMU_CMD_READ_ADC            0xd8
0204 
0205 
0206 /* Misc commands
0207  *
0208  * This command seem to be a grab bag of various things
0209  *
0210  * Parameters:
0211  *   1: subcommand
0212  */
0213 #define SMU_CMD_MISC_df_COMMAND         0xdf
0214 
0215 /*
0216  * Sets "system ready" status
0217  *
0218  * I did not yet understand how it exactly works or what it does.
0219  *
0220  * Guessing from OF code, 0x02 activates the display backlight. Apple uses/used
0221  * the same codebase for all OF versions. On PowerBooks, this command would
0222  * enable the backlight. For the G5s, it only activates the front LED. However,
0223  * don't take this for granted.
0224  *
0225  * Parameters:
0226  *   2: status [0x00, 0x01 or 0x02]
0227  */
0228 #define   SMU_CMD_MISC_df_SET_DISPLAY_LIT   0x02
0229 
0230 /*
0231  * Sets mode of power switch.
0232  *
0233  * What this actually does is not yet known. Maybe it enables some interrupt.
0234  *
0235  * Parameters:
0236  *   2: enable power switch? [0x00 or 0x01]
0237  *   3 (optional): enable nmi? [0x00 or 0x01]
0238  *
0239  * Returns:
0240  *   If parameter 2 is 0x00 and parameter 3 is not specified, returns whether
0241  *   NMI is enabled. Otherwise unknown.
0242  */
0243 #define   SMU_CMD_MISC_df_NMI_OPTION        0x04
0244 
0245 /* Sets LED dimm offset.
0246  *
0247  * The front LED dimms itself during sleep. Its brightness (or, well, the PWM
0248  * frequency) depends on current time. Therefore, the SMU needs to know the
0249  * timezone.
0250  *
0251  * Parameters:
0252  *   2-8: unknown (BCD coding)
0253  */
0254 #define   SMU_CMD_MISC_df_DIMM_OFFSET       0x99
0255 
0256 
0257 /*
0258  * Version info commands
0259  *
0260  * Parameters:
0261  *   1 (optional): Specifies version part to retrieve
0262  *
0263  * Returns:
0264  *   Version value
0265  */
0266 #define SMU_CMD_VERSION_COMMAND         0xea
0267 #define   SMU_VERSION_RUNNING           0x00
0268 #define   SMU_VERSION_BASE          0x01
0269 #define   SMU_VERSION_UPDATE            0x02
0270 
0271 
0272 /*
0273  * Switches
0274  *
0275  * These are switches whose status seems to be known to the SMU.
0276  *
0277  * Parameters:
0278  *   none
0279  *
0280  * Result:
0281  *   Switch bits (ORed, see below)
0282  */
0283 #define SMU_CMD_SWITCHES            0xdc
0284 
0285 /* Switches bits */
0286 #define SMU_SWITCH_CASE_CLOSED          0x01
0287 #define SMU_SWITCH_AC_POWER         0x04
0288 #define SMU_SWITCH_POWER_SWITCH         0x08
0289 
0290 
0291 /*
0292  * Misc commands
0293  *
0294  * This command seem to be a grab bag of various things
0295  *
0296  * SMU_CMD_MISC_ee_GET_DATABLOCK_REC is used, among others, to
0297  * transfer blocks of data from the SMU. So far, I've decrypted it's
0298  * usage to retrieve partition data. In order to do that, you have to
0299  * break your transfer in "chunks" since that command cannot transfer
0300  * more than a chunk at a time. The chunk size used by OF is 0xe bytes,
0301  * but it seems that the darwin driver will let you do 0x1e bytes if
0302  * your "PMU" version is >= 0x30. You can get the "PMU" version apparently
0303  * either in the last 16 bits of property "smu-version-pmu" or as the 16
0304  * bytes at offset 1 of "smu-version-info"
0305  *
0306  * For each chunk, the command takes 7 bytes of arguments:
0307  *  byte 0: subcommand code (0x02)
0308  *  byte 1: 0x04 (always, I don't know what it means, maybe the address
0309  *                space to use or some other nicety. It's hard coded in OF)
0310  *  byte 2..5: SMU address of the chunk (big endian 32 bits)
0311  *  byte 6: size to transfer (up to max chunk size)
0312  *
0313  * The data is returned directly
0314  */
0315 #define SMU_CMD_MISC_ee_COMMAND         0xee
0316 #define   SMU_CMD_MISC_ee_GET_DATABLOCK_REC 0x02
0317 
0318 /* Retrieves currently used watts.
0319  *
0320  * Parameters:
0321  *   1: 0x03 (Meaning unknown)
0322  */
0323 #define   SMU_CMD_MISC_ee_GET_WATTS     0x03
0324 
0325 #define   SMU_CMD_MISC_ee_LEDS_CTRL     0x04 /* i: 00 (00,01) [00] */
0326 #define   SMU_CMD_MISC_ee_GET_DATA      0x05 /* i: 00 , o: ?? */
0327 
0328 
0329 /*
0330  * Power related commands
0331  *
0332  * Parameters:
0333  *   1: subcommand
0334  */
0335 #define SMU_CMD_POWER_EVENTS_COMMAND        0x8f
0336 
0337 /* SMU_POWER_EVENTS subcommands */
0338 enum {
0339     SMU_PWR_GET_POWERUP_EVENTS      = 0x00,
0340     SMU_PWR_SET_POWERUP_EVENTS      = 0x01,
0341     SMU_PWR_CLR_POWERUP_EVENTS      = 0x02,
0342     SMU_PWR_GET_WAKEUP_EVENTS       = 0x03,
0343     SMU_PWR_SET_WAKEUP_EVENTS       = 0x04,
0344     SMU_PWR_CLR_WAKEUP_EVENTS       = 0x05,
0345 
0346     /*
0347      * Get last shutdown cause
0348      *
0349      * Returns:
0350      *   1 byte (signed char): Last shutdown cause. Exact meaning unknown.
0351      */
0352     SMU_PWR_LAST_SHUTDOWN_CAUSE = 0x07,
0353 
0354     /*
0355      * Sets or gets server ID. Meaning or use is unknown.
0356      *
0357      * Parameters:
0358      *   2 (optional): Set server ID (1 byte)
0359      *
0360      * Returns:
0361      *   1 byte (server ID?)
0362      */
0363     SMU_PWR_SERVER_ID       = 0x08,
0364 };
0365 
0366 /* Power events wakeup bits */
0367 enum {
0368     SMU_PWR_WAKEUP_KEY              = 0x01, /* Wake on key press */
0369     SMU_PWR_WAKEUP_AC_INSERT        = 0x02, /* Wake on AC adapter plug */
0370     SMU_PWR_WAKEUP_AC_CHANGE        = 0x04,
0371     SMU_PWR_WAKEUP_LID_OPEN         = 0x08,
0372     SMU_PWR_WAKEUP_RING             = 0x10,
0373 };
0374 
0375 
0376 /*
0377  * - Kernel side interface -
0378  */
0379 
0380 #ifdef __KERNEL__
0381 
0382 /*
0383  * Asynchronous SMU commands
0384  *
0385  * Fill up this structure and submit it via smu_queue_command(),
0386  * and get notified by the optional done() callback, or because
0387  * status becomes != 1
0388  */
0389 
0390 struct smu_cmd;
0391 
0392 struct smu_cmd
0393 {
0394     /* public */
0395     u8          cmd;        /* command */
0396     int         data_len;   /* data len */
0397     int         reply_len;  /* reply len */
0398     void            *data_buf;  /* data buffer */
0399     void            *reply_buf; /* reply buffer */
0400     int         status;     /* command status */
0401     void            (*done)(struct smu_cmd *cmd, void *misc);
0402     void            *misc;
0403 
0404     /* private */
0405     struct list_head    link;
0406 };
0407 
0408 /*
0409  * Queues an SMU command, all fields have to be initialized
0410  */
0411 extern int smu_queue_cmd(struct smu_cmd *cmd);
0412 
0413 /*
0414  * Simple command wrapper. This structure embeds a small buffer
0415  * to ease sending simple SMU commands from the stack
0416  */
0417 struct smu_simple_cmd
0418 {
0419     struct smu_cmd  cmd;
0420     u8          buffer[16];
0421 };
0422 
0423 /*
0424  * Queues a simple command. All fields will be initialized by that
0425  * function
0426  */
0427 extern int smu_queue_simple(struct smu_simple_cmd *scmd, u8 command,
0428                 unsigned int data_len,
0429                 void (*done)(struct smu_cmd *cmd, void *misc),
0430                 void *misc,
0431                 ...);
0432 
0433 /*
0434  * Completion helper. Pass it to smu_queue_simple or as 'done'
0435  * member to smu_queue_cmd, it will call complete() on the struct
0436  * completion passed in the "misc" argument
0437  */
0438 extern void smu_done_complete(struct smu_cmd *cmd, void *misc);
0439 
0440 /*
0441  * Synchronous helpers. Will spin-wait for completion of a command
0442  */
0443 extern void smu_spinwait_cmd(struct smu_cmd *cmd);
0444 
0445 static inline void smu_spinwait_simple(struct smu_simple_cmd *scmd)
0446 {
0447     smu_spinwait_cmd(&scmd->cmd);
0448 }
0449 
0450 /*
0451  * Poll routine to call if blocked with irqs off
0452  */
0453 extern void smu_poll(void);
0454 
0455 
0456 /*
0457  * Init routine, presence check....
0458  */
0459 int __init smu_init(void);
0460 extern int smu_present(void);
0461 struct platform_device;
0462 extern struct platform_device *smu_get_ofdev(void);
0463 
0464 
0465 /*
0466  * Common command wrappers
0467  */
0468 extern void smu_shutdown(void);
0469 extern void smu_restart(void);
0470 struct rtc_time;
0471 extern int smu_get_rtc_time(struct rtc_time *time, int spinwait);
0472 extern int smu_set_rtc_time(struct rtc_time *time, int spinwait);
0473 
0474 /*
0475  * Kernel asynchronous i2c interface
0476  */
0477 
0478 #define SMU_I2C_READ_MAX    0x1d
0479 #define SMU_I2C_WRITE_MAX   0x15
0480 
0481 /* SMU i2c header, exactly matches i2c header on wire */
0482 struct smu_i2c_param
0483 {
0484     u8  bus;        /* SMU bus ID (from device tree) */
0485     u8  type;       /* i2c transfer type */
0486     u8  devaddr;    /* device address (includes direction) */
0487     u8  sublen;     /* subaddress length */
0488     u8  subaddr[3]; /* subaddress */
0489     u8  caddr;      /* combined address, filled by SMU driver */
0490     u8  datalen;    /* length of transfer */
0491     u8  data[SMU_I2C_READ_MAX]; /* data */
0492 };
0493 
0494 struct smu_i2c_cmd
0495 {
0496     /* public */
0497     struct smu_i2c_param    info;
0498     void            (*done)(struct smu_i2c_cmd *cmd, void *misc);
0499     void            *misc;
0500     int         status; /* 1 = pending, 0 = ok, <0 = fail */
0501 
0502     /* private */
0503     struct smu_cmd      scmd;
0504     int         read;
0505     int         stage;
0506     int         retries;
0507     u8          pdata[32];
0508     struct list_head    link;
0509 };
0510 
0511 /*
0512  * Call this to queue an i2c command to the SMU. You must fill info,
0513  * including info.data for a write, done and misc.
0514  * For now, no polling interface is provided so you have to use completion
0515  * callback.
0516  */
0517 extern int smu_queue_i2c(struct smu_i2c_cmd *cmd);
0518 
0519 
0520 #endif /* __KERNEL__ */
0521 
0522 
0523 /*
0524  * - SMU "sdb" partitions informations -
0525  */
0526 
0527 
0528 /*
0529  * Partition header format
0530  */
0531 struct smu_sdbp_header {
0532     __u8    id;
0533     __u8    len;
0534     __u8    version;
0535     __u8    flags;
0536 };
0537 
0538 
0539  /*
0540  * demangle 16 and 32 bits integer in some SMU partitions
0541  * (currently, afaik, this concerns only the FVT partition
0542  * (0x12)
0543  */
0544 #define SMU_U16_MIX(x)  le16_to_cpu(x)
0545 #define SMU_U32_MIX(x)  ((((x) & 0xff00ff00u) >> 8)|(((x) & 0x00ff00ffu) << 8))
0546 
0547 
0548 /* This is the definition of the SMU sdb-partition-0x12 table (called
0549  * CPU F/V/T operating points in Darwin). The definition for all those
0550  * SMU tables should be moved to some separate file
0551  */
0552 #define SMU_SDB_FVT_ID          0x12
0553 
0554 struct smu_sdbp_fvt {
0555     __u32   sysclk;         /* Base SysClk frequency in Hz for
0556                      * this operating point. Value need to
0557                      * be unmixed with SMU_U32_MIX()
0558                      */
0559     __u8    pad;
0560     __u8    maxtemp;        /* Max temp. supported by this
0561                      * operating point
0562                      */
0563 
0564     __u16   volts[3];       /* CPU core voltage for the 3
0565                      * PowerTune modes, a mode with
0566                      * 0V = not supported. Value need
0567                      * to be unmixed with SMU_U16_MIX()
0568                      */
0569 };
0570 
0571 /* This partition contains voltage & current sensor calibration
0572  * informations
0573  */
0574 #define SMU_SDB_CPUVCP_ID       0x21
0575 
0576 struct smu_sdbp_cpuvcp {
0577     __u16   volt_scale;     /* u4.12 fixed point */
0578     __s16   volt_offset;        /* s4.12 fixed point */
0579     __u16   curr_scale;     /* u4.12 fixed point */
0580     __s16   curr_offset;        /* s4.12 fixed point */
0581     __s32   power_quads[3];     /* s4.28 fixed point */
0582 };
0583 
0584 /* This partition contains CPU thermal diode calibration
0585  */
0586 #define SMU_SDB_CPUDIODE_ID     0x18
0587 
0588 struct smu_sdbp_cpudiode {
0589     __u16   m_value;        /* u1.15 fixed point */
0590     __s16   b_value;        /* s10.6 fixed point */
0591 
0592 };
0593 
0594 /* This partition contains Slots power calibration
0595  */
0596 #define SMU_SDB_SLOTSPOW_ID     0x78
0597 
0598 struct smu_sdbp_slotspow {
0599     __u16   pow_scale;      /* u4.12 fixed point */
0600     __s16   pow_offset;     /* s4.12 fixed point */
0601 };
0602 
0603 /* This partition contains machine specific version information about
0604  * the sensor/control layout
0605  */
0606 #define SMU_SDB_SENSORTREE_ID       0x25
0607 
0608 struct smu_sdbp_sensortree {
0609     __u8    model_id;
0610     __u8    unknown[3];
0611 };
0612 
0613 /* This partition contains CPU thermal control PID informations. So far
0614  * only single CPU machines have been seen with an SMU, so we assume this
0615  * carries only informations for those
0616  */
0617 #define SMU_SDB_CPUPIDDATA_ID       0x17
0618 
0619 struct smu_sdbp_cpupiddata {
0620     __u8    unknown1;
0621     __u8    target_temp_delta;
0622     __u8    unknown2;
0623     __u8    history_len;
0624     __s16   power_adj;
0625     __u16   max_power;
0626     __s32   gp,gr,gd;
0627 };
0628 
0629 
0630 /* Other partitions without known structures */
0631 #define SMU_SDB_DEBUG_SWITCHES_ID   0x05
0632 
0633 #ifdef __KERNEL__
0634 /*
0635  * This returns the pointer to an SMU "sdb" partition data or NULL
0636  * if not found. The data format is described below
0637  */
0638 extern const struct smu_sdbp_header *smu_get_sdb_partition(int id,
0639                     unsigned int *size);
0640 
0641 /* Get "sdb" partition data from an SMU satellite */
0642 extern struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id,
0643                     int id, unsigned int *size);
0644 
0645 
0646 #endif /* __KERNEL__ */
0647 
0648 
0649 /*
0650  * - Userland interface -
0651  */
0652 
0653 /*
0654  * A given instance of the device can be configured for 2 different
0655  * things at the moment:
0656  *
0657  *  - sending SMU commands (default at open() time)
0658  *  - receiving SMU events (not yet implemented)
0659  *
0660  * Commands are written with write() of a command block. They can be
0661  * "driver" commands (for example to switch to event reception mode)
0662  * or real SMU commands. They are made of a header followed by command
0663  * data if any.
0664  *
0665  * For SMU commands (not for driver commands), you can then read() back
0666  * a reply. The reader will be blocked or not depending on how the device
0667  * file is opened. poll() isn't implemented yet. The reply will consist
0668  * of a header as well, followed by the reply data if any. You should
0669  * always provide a buffer large enough for the maximum reply data, I
0670  * recommand one page.
0671  *
0672  * It is illegal to send SMU commands through a file descriptor configured
0673  * for events reception
0674  *
0675  */
0676 struct smu_user_cmd_hdr
0677 {
0678     __u32       cmdtype;
0679 #define SMU_CMDTYPE_SMU         0   /* SMU command */
0680 #define SMU_CMDTYPE_WANTS_EVENTS    1   /* switch fd to events mode */
0681 #define SMU_CMDTYPE_GET_PARTITION   2   /* retrieve an sdb partition */
0682 
0683     __u8        cmd;            /* SMU command byte */
0684     __u8        pad[3];         /* padding */
0685     __u32       data_len;       /* Length of data following */
0686 };
0687 
0688 struct smu_user_reply_hdr
0689 {
0690     __u32       status;         /* Command status */
0691     __u32       reply_len;      /* Length of data follwing */
0692 };
0693 
0694 #endif /*  _SMU_H */