0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/completion.h>
0013 #include <linux/ctype.h>
0014 #include <linux/delay.h>
0015 #include <linux/gpio/consumer.h>
0016 #include <linux/input.h>
0017 #include <linux/kfifo.h>
0018 #include <linux/module.h>
0019 #include <linux/olpc-ec.h>
0020 #include <linux/platform_device.h>
0021 #include <linux/power_supply.h>
0022 #include <linux/reboot.h>
0023 #include <linux/slab.h>
0024 #include <linux/spinlock.h>
0025 #include <linux/spi/spi.h>
0026
0027 struct ec_cmd_t {
0028 u8 cmd;
0029 u8 bytes_returned;
0030 };
0031
0032 enum ec_chan_t {
0033 CHAN_NONE = 0,
0034 CHAN_SWITCH,
0035 CHAN_CMD_RESP,
0036 CHAN_KEYBOARD,
0037 CHAN_TOUCHPAD,
0038 CHAN_EVENT,
0039 CHAN_DEBUG,
0040 CHAN_CMD_ERROR,
0041 };
0042
0043
0044
0045
0046 #define EVENT_AC_CHANGE 1
0047 #define EVENT_BATTERY_STATUS 2
0048 #define EVENT_BATTERY_CRITICAL 3
0049 #define EVENT_BATTERY_SOC_CHANGE 4
0050 #define EVENT_BATTERY_ERROR 5
0051 #define EVENT_POWER_PRESSED 6
0052 #define EVENT_POWER_PRESS_WAKE 7
0053 #define EVENT_TIMED_HOST_WAKE 8
0054 #define EVENT_OLS_HIGH_LIMIT 9
0055 #define EVENT_OLS_LOW_LIMIT 10
0056
0057
0058
0059
0060
0061 #define CMD_GET_API_VERSION 0x08
0062 #define CMD_READ_VOLTAGE 0x10
0063 #define CMD_READ_CURRENT 0x11
0064 #define CMD_READ_ACR 0x12
0065 #define CMD_READ_BATT_TEMPERATURE 0x13
0066 #define CMD_READ_AMBIENT_TEMPERATURE 0x14
0067 #define CMD_READ_BATTERY_STATUS 0x15
0068 #define CMD_READ_SOC 0x16
0069 #define CMD_READ_GAUGE_ID 0x17
0070 #define CMD_READ_GAUGE_DATA 0x18
0071 #define CMD_READ_BOARD_ID 0x19
0072 #define CMD_READ_BATT_ERR_CODE 0x1f
0073 #define CMD_SET_DCON_POWER 0x26
0074 #define CMD_RESET_EC 0x28
0075 #define CMD_READ_BATTERY_TYPE 0x2c
0076 #define CMD_SET_AUTOWAK 0x33
0077 #define CMD_SET_EC_WAKEUP_TIMER 0x36
0078 #define CMD_READ_EXT_SCI_MASK 0x37
0079 #define CMD_WRITE_EXT_SCI_MASK 0x38
0080 #define CMD_CLEAR_EC_WAKEUP_TIMER 0x39
0081 #define CMD_ENABLE_RUNIN_DISCHARGE 0x3B
0082 #define CMD_DISABLE_RUNIN_DISCHARGE 0x3C
0083 #define CMD_READ_MPPT_ACTIVE 0x3d
0084 #define CMD_READ_MPPT_LIMIT 0x3e
0085 #define CMD_SET_MPPT_LIMIT 0x3f
0086 #define CMD_DISABLE_MPPT 0x40
0087 #define CMD_ENABLE_MPPT 0x41
0088 #define CMD_READ_VIN 0x42
0089 #define CMD_EXT_SCI_QUERY 0x43
0090 #define RSP_KEYBOARD_DATA 0x48
0091 #define RSP_TOUCHPAD_DATA 0x49
0092 #define CMD_GET_FW_VERSION 0x4a
0093 #define CMD_POWER_CYCLE 0x4b
0094 #define CMD_POWER_OFF 0x4c
0095 #define CMD_RESET_EC_SOFT 0x4d
0096 #define CMD_READ_GAUGE_U16 0x4e
0097 #define CMD_ENABLE_MOUSE 0x4f
0098 #define CMD_ECHO 0x52
0099 #define CMD_GET_FW_DATE 0x53
0100 #define CMD_GET_FW_USER 0x54
0101 #define CMD_TURN_OFF_POWER 0x55
0102 #define CMD_READ_OLS 0x56
0103 #define CMD_OLS_SMT_LEDON 0x57
0104 #define CMD_OLS_SMT_LEDOFF 0x58
0105 #define CMD_START_OLS_ASSY 0x59
0106 #define CMD_STOP_OLS_ASSY 0x5a
0107 #define CMD_OLS_SMTTEST_STOP 0x5b
0108 #define CMD_READ_VIN_SCALED 0x5c
0109 #define CMD_READ_BAT_MIN_W 0x5d
0110 #define CMD_READ_BAR_MAX_W 0x5e
0111 #define CMD_RESET_BAT_MINMAX_W 0x5f
0112 #define CMD_READ_LOCATION 0x60
0113 #define CMD_WRITE_LOCATION 0x61
0114 #define CMD_KEYBOARD_CMD 0x62
0115 #define CMD_TOUCHPAD_CMD 0x63
0116 #define CMD_GET_FW_HASH 0x64
0117 #define CMD_SUSPEND_HINT 0x65
0118 #define CMD_ENABLE_WAKE_TIMER 0x66
0119 #define CMD_SET_WAKE_TIMER 0x67
0120 #define CMD_ENABLE_WAKE_AUTORESET 0x68
0121 #define CMD_OLS_SET_LIMITS 0x69
0122 #define CMD_OLS_GET_LIMITS 0x6a
0123 #define CMD_OLS_SET_CEILING 0x6b
0124 #define CMD_OLS_GET_CEILING 0x6c
0125
0126
0127
0128
0129
0130
0131 static const struct ec_cmd_t olpc_xo175_ec_cmds[] = {
0132 { CMD_GET_API_VERSION, 1 },
0133 { CMD_READ_VOLTAGE, 2 },
0134 { CMD_READ_CURRENT, 2 },
0135 { CMD_READ_ACR, 2 },
0136 { CMD_READ_BATT_TEMPERATURE, 2 },
0137 { CMD_READ_BATTERY_STATUS, 1 },
0138 { CMD_READ_SOC, 1 },
0139 { CMD_READ_GAUGE_ID, 8 },
0140 { CMD_READ_GAUGE_DATA, 1 },
0141 { CMD_READ_BOARD_ID, 2 },
0142 { CMD_READ_BATT_ERR_CODE, 1 },
0143 { CMD_SET_DCON_POWER, 0 },
0144 { CMD_RESET_EC, 0 },
0145 { CMD_READ_BATTERY_TYPE, 1 },
0146 { CMD_ENABLE_RUNIN_DISCHARGE, 0 },
0147 { CMD_DISABLE_RUNIN_DISCHARGE, 0 },
0148 { CMD_READ_MPPT_ACTIVE, 1 },
0149 { CMD_READ_MPPT_LIMIT, 1 },
0150 { CMD_SET_MPPT_LIMIT, 0 },
0151 { CMD_DISABLE_MPPT, 0 },
0152 { CMD_ENABLE_MPPT, 0 },
0153 { CMD_READ_VIN, 2 },
0154 { CMD_GET_FW_VERSION, 16 },
0155 { CMD_POWER_CYCLE, 0 },
0156 { CMD_POWER_OFF, 0 },
0157 { CMD_RESET_EC_SOFT, 0 },
0158 { CMD_ECHO, 5 },
0159 { CMD_GET_FW_DATE, 16 },
0160 { CMD_GET_FW_USER, 16 },
0161 { CMD_TURN_OFF_POWER, 0 },
0162 { CMD_READ_OLS, 2 },
0163 { CMD_OLS_SMT_LEDON, 0 },
0164 { CMD_OLS_SMT_LEDOFF, 0 },
0165 { CMD_START_OLS_ASSY, 0 },
0166 { CMD_STOP_OLS_ASSY, 0 },
0167 { CMD_OLS_SMTTEST_STOP, 0 },
0168 { CMD_READ_VIN_SCALED, 2 },
0169 { CMD_READ_BAT_MIN_W, 2 },
0170 { CMD_READ_BAR_MAX_W, 2 },
0171 { CMD_RESET_BAT_MINMAX_W, 0 },
0172 { CMD_READ_LOCATION, 1 },
0173 { CMD_WRITE_LOCATION, 0 },
0174 { CMD_GET_FW_HASH, 16 },
0175 { CMD_SUSPEND_HINT, 0 },
0176 { CMD_ENABLE_WAKE_TIMER, 0 },
0177 { CMD_SET_WAKE_TIMER, 0 },
0178 { CMD_ENABLE_WAKE_AUTORESET, 0 },
0179 { CMD_OLS_SET_LIMITS, 0 },
0180 { CMD_OLS_GET_LIMITS, 4 },
0181 { CMD_OLS_SET_CEILING, 0 },
0182 { CMD_OLS_GET_CEILING, 2 },
0183 { CMD_READ_EXT_SCI_MASK, 2 },
0184 { CMD_WRITE_EXT_SCI_MASK, 0 },
0185
0186 { }
0187 };
0188
0189 #define EC_MAX_CMD_DATA_LEN 5
0190 #define EC_MAX_RESP_LEN 16
0191
0192 #define LOG_BUF_SIZE 128
0193
0194 #define PM_WAKEUP_TIME 1000
0195
0196 #define EC_ALL_EVENTS GENMASK(15, 0)
0197
0198 enum ec_state_t {
0199 CMD_STATE_IDLE = 0,
0200 CMD_STATE_WAITING_FOR_SWITCH,
0201 CMD_STATE_CMD_IN_TX_FIFO,
0202 CMD_STATE_CMD_SENT,
0203 CMD_STATE_RESP_RECEIVED,
0204 CMD_STATE_ERROR_RECEIVED,
0205 };
0206
0207 struct olpc_xo175_ec_cmd {
0208 u8 command;
0209 u8 nr_args;
0210 u8 data_len;
0211 u8 args[EC_MAX_CMD_DATA_LEN];
0212 };
0213
0214 struct olpc_xo175_ec_resp {
0215 u8 channel;
0216 u8 byte;
0217 };
0218
0219 struct olpc_xo175_ec {
0220 bool suspended;
0221
0222
0223 struct spi_device *spi;
0224 struct spi_transfer xfer;
0225 struct spi_message msg;
0226 union {
0227 struct olpc_xo175_ec_cmd cmd;
0228 struct olpc_xo175_ec_resp resp;
0229 } tx_buf, rx_buf;
0230
0231
0232 struct gpio_desc *gpio_cmd;
0233
0234
0235 spinlock_t cmd_state_lock;
0236 int cmd_state;
0237 bool cmd_running;
0238 struct completion cmd_done;
0239 struct olpc_xo175_ec_cmd cmd;
0240 u8 resp_data[EC_MAX_RESP_LEN];
0241 int expected_resp_len;
0242 int resp_len;
0243
0244
0245 struct input_dev *pwrbtn;
0246
0247
0248 char logbuf[LOG_BUF_SIZE];
0249 int logbuf_len;
0250 };
0251
0252 static struct platform_device *olpc_ec;
0253
0254 static int olpc_xo175_ec_resp_len(u8 cmd)
0255 {
0256 const struct ec_cmd_t *p;
0257
0258 for (p = olpc_xo175_ec_cmds; p->cmd; p++) {
0259 if (p->cmd == cmd)
0260 return p->bytes_returned;
0261 }
0262
0263 return -EINVAL;
0264 }
0265
0266 static void olpc_xo175_ec_flush_logbuf(struct olpc_xo175_ec *priv)
0267 {
0268 dev_dbg(&priv->spi->dev, "got debug string [%*pE]\n",
0269 priv->logbuf_len, priv->logbuf);
0270 priv->logbuf_len = 0;
0271 }
0272
0273 static void olpc_xo175_ec_complete(void *arg);
0274
0275 static void olpc_xo175_ec_send_command(struct olpc_xo175_ec *priv, void *cmd,
0276 size_t cmdlen)
0277 {
0278 int ret;
0279
0280 memcpy(&priv->tx_buf, cmd, cmdlen);
0281 priv->xfer.len = cmdlen;
0282
0283 spi_message_init_with_transfers(&priv->msg, &priv->xfer, 1);
0284
0285 priv->msg.complete = olpc_xo175_ec_complete;
0286 priv->msg.context = priv;
0287
0288 ret = spi_async(priv->spi, &priv->msg);
0289 if (ret)
0290 dev_err(&priv->spi->dev, "spi_async() failed %d\n", ret);
0291 }
0292
0293 static void olpc_xo175_ec_read_packet(struct olpc_xo175_ec *priv)
0294 {
0295 u8 nonce[] = {0xA5, 0x5A};
0296
0297 olpc_xo175_ec_send_command(priv, nonce, sizeof(nonce));
0298 }
0299
0300 static void olpc_xo175_ec_complete(void *arg)
0301 {
0302 struct olpc_xo175_ec *priv = arg;
0303 struct device *dev = &priv->spi->dev;
0304 struct power_supply *psy;
0305 unsigned long flags;
0306 u8 channel;
0307 u8 byte;
0308 int ret;
0309
0310 ret = priv->msg.status;
0311 if (ret) {
0312 dev_err(dev, "SPI transfer failed: %d\n", ret);
0313
0314 spin_lock_irqsave(&priv->cmd_state_lock, flags);
0315 if (priv->cmd_running) {
0316 priv->resp_len = 0;
0317 priv->cmd_state = CMD_STATE_ERROR_RECEIVED;
0318 complete(&priv->cmd_done);
0319 }
0320 spin_unlock_irqrestore(&priv->cmd_state_lock, flags);
0321
0322 if (ret != -EINTR)
0323 olpc_xo175_ec_read_packet(priv);
0324
0325 return;
0326 }
0327
0328 channel = priv->rx_buf.resp.channel;
0329 byte = priv->rx_buf.resp.byte;
0330
0331 switch (channel) {
0332 case CHAN_NONE:
0333 spin_lock_irqsave(&priv->cmd_state_lock, flags);
0334
0335 if (!priv->cmd_running) {
0336
0337 dev_err(dev, "spurious FIFO read packet\n");
0338 spin_unlock_irqrestore(&priv->cmd_state_lock, flags);
0339 return;
0340 }
0341
0342 priv->cmd_state = CMD_STATE_CMD_SENT;
0343 if (!priv->expected_resp_len)
0344 complete(&priv->cmd_done);
0345 olpc_xo175_ec_read_packet(priv);
0346
0347 spin_unlock_irqrestore(&priv->cmd_state_lock, flags);
0348 return;
0349
0350 case CHAN_SWITCH:
0351 spin_lock_irqsave(&priv->cmd_state_lock, flags);
0352
0353 if (!priv->cmd_running) {
0354
0355 dev_err(dev, "spurious SWITCH packet\n");
0356 memset(&priv->cmd, 0, sizeof(priv->cmd));
0357 priv->cmd.command = CMD_ECHO;
0358 }
0359
0360 priv->cmd_state = CMD_STATE_CMD_IN_TX_FIFO;
0361
0362
0363 gpiod_set_value_cansleep(priv->gpio_cmd, 0);
0364 olpc_xo175_ec_send_command(priv, &priv->cmd, sizeof(priv->cmd));
0365
0366 spin_unlock_irqrestore(&priv->cmd_state_lock, flags);
0367 return;
0368
0369 case CHAN_CMD_RESP:
0370 spin_lock_irqsave(&priv->cmd_state_lock, flags);
0371
0372 if (!priv->cmd_running) {
0373 dev_err(dev, "spurious response packet\n");
0374 } else if (priv->resp_len >= priv->expected_resp_len) {
0375 dev_err(dev, "too many response packets\n");
0376 } else {
0377 priv->resp_data[priv->resp_len++] = byte;
0378 if (priv->resp_len == priv->expected_resp_len) {
0379 priv->cmd_state = CMD_STATE_RESP_RECEIVED;
0380 complete(&priv->cmd_done);
0381 }
0382 }
0383
0384 spin_unlock_irqrestore(&priv->cmd_state_lock, flags);
0385 break;
0386
0387 case CHAN_CMD_ERROR:
0388 spin_lock_irqsave(&priv->cmd_state_lock, flags);
0389
0390 if (!priv->cmd_running) {
0391 dev_err(dev, "spurious cmd error packet\n");
0392 } else {
0393 priv->resp_data[0] = byte;
0394 priv->resp_len = 1;
0395 priv->cmd_state = CMD_STATE_ERROR_RECEIVED;
0396 complete(&priv->cmd_done);
0397 }
0398 spin_unlock_irqrestore(&priv->cmd_state_lock, flags);
0399 break;
0400
0401 case CHAN_KEYBOARD:
0402 dev_warn(dev, "keyboard is not supported\n");
0403 break;
0404
0405 case CHAN_TOUCHPAD:
0406 dev_warn(dev, "touchpad is not supported\n");
0407 break;
0408
0409 case CHAN_EVENT:
0410 dev_dbg(dev, "got event %.2x\n", byte);
0411 switch (byte) {
0412 case EVENT_AC_CHANGE:
0413 psy = power_supply_get_by_name("olpc_ac");
0414 if (psy) {
0415 power_supply_changed(psy);
0416 power_supply_put(psy);
0417 }
0418 break;
0419 case EVENT_BATTERY_STATUS:
0420 case EVENT_BATTERY_CRITICAL:
0421 case EVENT_BATTERY_SOC_CHANGE:
0422 case EVENT_BATTERY_ERROR:
0423 psy = power_supply_get_by_name("olpc_battery");
0424 if (psy) {
0425 power_supply_changed(psy);
0426 power_supply_put(psy);
0427 }
0428 break;
0429 case EVENT_POWER_PRESSED:
0430 input_report_key(priv->pwrbtn, KEY_POWER, 1);
0431 input_sync(priv->pwrbtn);
0432 input_report_key(priv->pwrbtn, KEY_POWER, 0);
0433 input_sync(priv->pwrbtn);
0434 fallthrough;
0435 case EVENT_POWER_PRESS_WAKE:
0436 case EVENT_TIMED_HOST_WAKE:
0437 pm_wakeup_event(priv->pwrbtn->dev.parent,
0438 PM_WAKEUP_TIME);
0439 break;
0440 default:
0441 dev_dbg(dev, "ignored unknown event %.2x\n", byte);
0442 break;
0443 }
0444 break;
0445
0446 case CHAN_DEBUG:
0447 if (byte == '\n') {
0448 olpc_xo175_ec_flush_logbuf(priv);
0449 } else if (isprint(byte)) {
0450 priv->logbuf[priv->logbuf_len++] = byte;
0451 if (priv->logbuf_len == LOG_BUF_SIZE)
0452 olpc_xo175_ec_flush_logbuf(priv);
0453 }
0454 break;
0455
0456 default:
0457 dev_warn(dev, "unknown channel: %d, %.2x\n", channel, byte);
0458 break;
0459 }
0460
0461
0462 olpc_xo175_ec_read_packet(priv);
0463 }
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473 static int olpc_xo175_ec_cmd(u8 cmd, u8 *inbuf, size_t inlen, u8 *resp,
0474 size_t resp_len, void *ec_cb_arg)
0475 {
0476 struct olpc_xo175_ec *priv = ec_cb_arg;
0477 struct device *dev = &priv->spi->dev;
0478 unsigned long flags;
0479 size_t nr_bytes;
0480 int ret = 0;
0481
0482 dev_dbg(dev, "CMD %x, %zd bytes expected\n", cmd, resp_len);
0483
0484 if (inlen > 5) {
0485 dev_err(dev, "command len %zd too big!\n", resp_len);
0486 return -EOVERFLOW;
0487 }
0488
0489
0490 if (WARN_ON(priv->suspended))
0491 return -EBUSY;
0492
0493
0494 ret = olpc_xo175_ec_resp_len(cmd);
0495 if (ret < 0) {
0496 dev_err_ratelimited(dev, "unknown command 0x%x\n", cmd);
0497
0498
0499
0500
0501
0502
0503 if (resp_len > sizeof(priv->resp_data)) {
0504 dev_err(dev, "response too big: %zd!\n", resp_len);
0505 return -EOVERFLOW;
0506 }
0507 nr_bytes = resp_len;
0508 } else {
0509 nr_bytes = (size_t)ret;
0510 ret = 0;
0511 }
0512 resp_len = min(resp_len, nr_bytes);
0513
0514 spin_lock_irqsave(&priv->cmd_state_lock, flags);
0515
0516
0517 init_completion(&priv->cmd_done);
0518 priv->cmd_running = true;
0519 priv->cmd_state = CMD_STATE_WAITING_FOR_SWITCH;
0520 memset(&priv->cmd, 0, sizeof(priv->cmd));
0521 priv->cmd.command = cmd;
0522 priv->cmd.nr_args = inlen;
0523 priv->cmd.data_len = 0;
0524 memcpy(priv->cmd.args, inbuf, inlen);
0525 priv->expected_resp_len = nr_bytes;
0526 priv->resp_len = 0;
0527
0528
0529 gpiod_set_value_cansleep(priv->gpio_cmd, 1);
0530
0531 spin_unlock_irqrestore(&priv->cmd_state_lock, flags);
0532
0533
0534 if (!wait_for_completion_timeout(&priv->cmd_done,
0535 msecs_to_jiffies(4000))) {
0536 dev_err(dev, "EC cmd error: timeout in STATE %d\n",
0537 priv->cmd_state);
0538 gpiod_set_value_cansleep(priv->gpio_cmd, 0);
0539 spi_slave_abort(priv->spi);
0540 olpc_xo175_ec_read_packet(priv);
0541 return -ETIMEDOUT;
0542 }
0543
0544 spin_lock_irqsave(&priv->cmd_state_lock, flags);
0545
0546
0547 if (priv->cmd_state == CMD_STATE_ERROR_RECEIVED) {
0548
0549 dev_err(dev, "command 0x%x returned error 0x%x\n",
0550 cmd, priv->resp_data[0]);
0551 ret = -EREMOTEIO;
0552 } else if (priv->resp_len != nr_bytes) {
0553 dev_err(dev, "command 0x%x returned %d bytes, expected %zd bytes\n",
0554 cmd, priv->resp_len, nr_bytes);
0555 ret = -EREMOTEIO;
0556 } else {
0557
0558
0559
0560
0561
0562
0563 memcpy(resp, priv->resp_data, resp_len);
0564 }
0565
0566
0567 gpiod_set_value_cansleep(priv->gpio_cmd, 0);
0568 priv->cmd_running = false;
0569
0570 spin_unlock_irqrestore(&priv->cmd_state_lock, flags);
0571
0572 return ret;
0573 }
0574
0575 static int olpc_xo175_ec_set_event_mask(unsigned int mask)
0576 {
0577 u8 args[2];
0578
0579 args[0] = mask >> 0;
0580 args[1] = mask >> 8;
0581 return olpc_ec_cmd(CMD_WRITE_EXT_SCI_MASK, args, 2, NULL, 0);
0582 }
0583
0584 static void olpc_xo175_ec_power_off(void)
0585 {
0586 while (1) {
0587 olpc_ec_cmd(CMD_POWER_OFF, NULL, 0, NULL, 0);
0588 mdelay(1000);
0589 }
0590 }
0591
0592 static int __maybe_unused olpc_xo175_ec_suspend(struct device *dev)
0593 {
0594 struct olpc_xo175_ec *priv = dev_get_drvdata(dev);
0595 static struct {
0596 u8 suspend;
0597 u32 suspend_count;
0598 } __packed hintargs;
0599 static unsigned int suspend_count;
0600
0601
0602
0603
0604
0605
0606 hintargs.suspend = 1;
0607 hintargs.suspend_count = suspend_count++;
0608 olpc_ec_cmd(CMD_SUSPEND_HINT, (void *)&hintargs, sizeof(hintargs),
0609 NULL, 0);
0610
0611
0612
0613
0614
0615
0616 priv->suspended = true;
0617
0618 return 0;
0619 }
0620
0621 static int __maybe_unused olpc_xo175_ec_resume_noirq(struct device *dev)
0622 {
0623 struct olpc_xo175_ec *priv = dev_get_drvdata(dev);
0624
0625 priv->suspended = false;
0626
0627 return 0;
0628 }
0629
0630 static int __maybe_unused olpc_xo175_ec_resume(struct device *dev)
0631 {
0632 u8 x = 0;
0633
0634
0635
0636
0637
0638
0639 olpc_ec_cmd(CMD_SUSPEND_HINT, &x, 1, NULL, 0);
0640
0641
0642 olpc_xo175_ec_set_event_mask(EC_ALL_EVENTS);
0643
0644 return 0;
0645 }
0646
0647 static struct olpc_ec_driver olpc_xo175_ec_driver = {
0648 .ec_cmd = olpc_xo175_ec_cmd,
0649 };
0650
0651 static void olpc_xo175_ec_remove(struct spi_device *spi)
0652 {
0653 if (pm_power_off == olpc_xo175_ec_power_off)
0654 pm_power_off = NULL;
0655
0656 spi_slave_abort(spi);
0657
0658 platform_device_unregister(olpc_ec);
0659 olpc_ec = NULL;
0660 }
0661
0662 static int olpc_xo175_ec_probe(struct spi_device *spi)
0663 {
0664 struct olpc_xo175_ec *priv;
0665 int ret;
0666
0667 if (olpc_ec) {
0668 dev_err(&spi->dev, "OLPC EC already registered.\n");
0669 return -EBUSY;
0670 }
0671
0672 priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL);
0673 if (!priv)
0674 return -ENOMEM;
0675
0676 priv->gpio_cmd = devm_gpiod_get(&spi->dev, "cmd", GPIOD_OUT_LOW);
0677 if (IS_ERR(priv->gpio_cmd)) {
0678 dev_err(&spi->dev, "failed to get cmd gpio: %ld\n",
0679 PTR_ERR(priv->gpio_cmd));
0680 return PTR_ERR(priv->gpio_cmd);
0681 }
0682
0683 priv->spi = spi;
0684
0685 spin_lock_init(&priv->cmd_state_lock);
0686 priv->cmd_state = CMD_STATE_IDLE;
0687 init_completion(&priv->cmd_done);
0688
0689 priv->logbuf_len = 0;
0690
0691
0692 priv->pwrbtn = devm_input_allocate_device(&spi->dev);
0693 if (!priv->pwrbtn)
0694 return -ENOMEM;
0695 priv->pwrbtn->name = "Power Button";
0696 priv->pwrbtn->dev.parent = &spi->dev;
0697 input_set_capability(priv->pwrbtn, EV_KEY, KEY_POWER);
0698 ret = input_register_device(priv->pwrbtn);
0699 if (ret) {
0700 dev_err(&spi->dev, "error registering input device: %d\n", ret);
0701 return ret;
0702 }
0703
0704 spi_set_drvdata(spi, priv);
0705
0706 priv->xfer.rx_buf = &priv->rx_buf;
0707 priv->xfer.tx_buf = &priv->tx_buf;
0708
0709 olpc_xo175_ec_read_packet(priv);
0710
0711 olpc_ec_driver_register(&olpc_xo175_ec_driver, priv);
0712 olpc_ec = platform_device_register_resndata(&spi->dev, "olpc-ec", -1,
0713 NULL, 0, NULL, 0);
0714
0715
0716 olpc_xo175_ec_set_event_mask(EC_ALL_EVENTS);
0717
0718 if (pm_power_off == NULL)
0719 pm_power_off = olpc_xo175_ec_power_off;
0720
0721 dev_info(&spi->dev, "OLPC XO-1.75 Embedded Controller driver\n");
0722
0723 return 0;
0724 }
0725
0726 static const struct dev_pm_ops olpc_xo175_ec_pm_ops = {
0727 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(NULL, olpc_xo175_ec_resume_noirq)
0728 SET_RUNTIME_PM_OPS(olpc_xo175_ec_suspend, olpc_xo175_ec_resume, NULL)
0729 };
0730
0731 static const struct of_device_id olpc_xo175_ec_of_match[] = {
0732 { .compatible = "olpc,xo1.75-ec" },
0733 { }
0734 };
0735 MODULE_DEVICE_TABLE(of, olpc_xo175_ec_of_match);
0736
0737 static const struct spi_device_id olpc_xo175_ec_id_table[] = {
0738 { "xo1.75-ec", 0 },
0739 {}
0740 };
0741 MODULE_DEVICE_TABLE(spi, olpc_xo175_ec_id_table);
0742
0743 static struct spi_driver olpc_xo175_ec_spi_driver = {
0744 .driver = {
0745 .name = "olpc-xo175-ec",
0746 .of_match_table = olpc_xo175_ec_of_match,
0747 .pm = &olpc_xo175_ec_pm_ops,
0748 },
0749 .probe = olpc_xo175_ec_probe,
0750 .remove = olpc_xo175_ec_remove,
0751 };
0752 module_spi_driver(olpc_xo175_ec_spi_driver);
0753
0754 MODULE_DESCRIPTION("OLPC XO-1.75 Embedded Controller driver");
0755 MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
0756 MODULE_AUTHOR("Lubomir Rintel <lkundrak@v3.sk>");
0757 MODULE_LICENSE("GPL");