0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include <linux/module.h>
0023 #include <linux/kernel.h>
0024 #include <linux/errno.h>
0025 #include <linux/input.h>
0026 #include <linux/interrupt.h>
0027 #include <linux/platform_device.h>
0028 #include <linux/mfd/mc13783.h>
0029 #include <linux/sched.h>
0030 #include <linux/slab.h>
0031
0032 struct mc13783_pwrb {
0033 struct input_dev *pwr;
0034 struct mc13xxx *mc13783;
0035 #define MC13783_PWRB_B1_POL_INVERT (1 << 0)
0036 #define MC13783_PWRB_B2_POL_INVERT (1 << 1)
0037 #define MC13783_PWRB_B3_POL_INVERT (1 << 2)
0038 int flags;
0039 unsigned short keymap[3];
0040 };
0041
0042 #define MC13783_REG_INTERRUPT_SENSE_1 5
0043 #define MC13783_IRQSENSE1_ONOFD1S (1 << 3)
0044 #define MC13783_IRQSENSE1_ONOFD2S (1 << 4)
0045 #define MC13783_IRQSENSE1_ONOFD3S (1 << 5)
0046
0047 #define MC13783_REG_POWER_CONTROL_2 15
0048 #define MC13783_POWER_CONTROL_2_ON1BDBNC 4
0049 #define MC13783_POWER_CONTROL_2_ON2BDBNC 6
0050 #define MC13783_POWER_CONTROL_2_ON3BDBNC 8
0051 #define MC13783_POWER_CONTROL_2_ON1BRSTEN (1 << 1)
0052 #define MC13783_POWER_CONTROL_2_ON2BRSTEN (1 << 2)
0053 #define MC13783_POWER_CONTROL_2_ON3BRSTEN (1 << 3)
0054
0055 static irqreturn_t button_irq(int irq, void *_priv)
0056 {
0057 struct mc13783_pwrb *priv = _priv;
0058 int val;
0059
0060 mc13xxx_irq_ack(priv->mc13783, irq);
0061 mc13xxx_reg_read(priv->mc13783, MC13783_REG_INTERRUPT_SENSE_1, &val);
0062
0063 switch (irq) {
0064 case MC13783_IRQ_ONOFD1:
0065 val = val & MC13783_IRQSENSE1_ONOFD1S ? 1 : 0;
0066 if (priv->flags & MC13783_PWRB_B1_POL_INVERT)
0067 val ^= 1;
0068 input_report_key(priv->pwr, priv->keymap[0], val);
0069 break;
0070
0071 case MC13783_IRQ_ONOFD2:
0072 val = val & MC13783_IRQSENSE1_ONOFD2S ? 1 : 0;
0073 if (priv->flags & MC13783_PWRB_B2_POL_INVERT)
0074 val ^= 1;
0075 input_report_key(priv->pwr, priv->keymap[1], val);
0076 break;
0077
0078 case MC13783_IRQ_ONOFD3:
0079 val = val & MC13783_IRQSENSE1_ONOFD3S ? 1 : 0;
0080 if (priv->flags & MC13783_PWRB_B3_POL_INVERT)
0081 val ^= 1;
0082 input_report_key(priv->pwr, priv->keymap[2], val);
0083 break;
0084 }
0085
0086 input_sync(priv->pwr);
0087
0088 return IRQ_HANDLED;
0089 }
0090
0091 static int mc13783_pwrbutton_probe(struct platform_device *pdev)
0092 {
0093 const struct mc13xxx_buttons_platform_data *pdata;
0094 struct mc13xxx *mc13783 = dev_get_drvdata(pdev->dev.parent);
0095 struct input_dev *pwr;
0096 struct mc13783_pwrb *priv;
0097 int err = 0;
0098 int reg = 0;
0099
0100 pdata = dev_get_platdata(&pdev->dev);
0101 if (!pdata) {
0102 dev_err(&pdev->dev, "missing platform data\n");
0103 return -ENODEV;
0104 }
0105
0106 pwr = input_allocate_device();
0107 if (!pwr) {
0108 dev_dbg(&pdev->dev, "Can't allocate power button\n");
0109 return -ENOMEM;
0110 }
0111
0112 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
0113 if (!priv) {
0114 err = -ENOMEM;
0115 dev_dbg(&pdev->dev, "Can't allocate power button\n");
0116 goto free_input_dev;
0117 }
0118
0119 reg |= (pdata->b1on_flags & 0x3) << MC13783_POWER_CONTROL_2_ON1BDBNC;
0120 reg |= (pdata->b2on_flags & 0x3) << MC13783_POWER_CONTROL_2_ON2BDBNC;
0121 reg |= (pdata->b3on_flags & 0x3) << MC13783_POWER_CONTROL_2_ON3BDBNC;
0122
0123 priv->pwr = pwr;
0124 priv->mc13783 = mc13783;
0125
0126 mc13xxx_lock(mc13783);
0127
0128 if (pdata->b1on_flags & MC13783_BUTTON_ENABLE) {
0129 priv->keymap[0] = pdata->b1on_key;
0130 if (pdata->b1on_key != KEY_RESERVED)
0131 __set_bit(pdata->b1on_key, pwr->keybit);
0132
0133 if (pdata->b1on_flags & MC13783_BUTTON_POL_INVERT)
0134 priv->flags |= MC13783_PWRB_B1_POL_INVERT;
0135
0136 if (pdata->b1on_flags & MC13783_BUTTON_RESET_EN)
0137 reg |= MC13783_POWER_CONTROL_2_ON1BRSTEN;
0138
0139 err = mc13xxx_irq_request(mc13783, MC13783_IRQ_ONOFD1,
0140 button_irq, "b1on", priv);
0141 if (err) {
0142 dev_dbg(&pdev->dev, "Can't request irq\n");
0143 goto free_priv;
0144 }
0145 }
0146
0147 if (pdata->b2on_flags & MC13783_BUTTON_ENABLE) {
0148 priv->keymap[1] = pdata->b2on_key;
0149 if (pdata->b2on_key != KEY_RESERVED)
0150 __set_bit(pdata->b2on_key, pwr->keybit);
0151
0152 if (pdata->b2on_flags & MC13783_BUTTON_POL_INVERT)
0153 priv->flags |= MC13783_PWRB_B2_POL_INVERT;
0154
0155 if (pdata->b2on_flags & MC13783_BUTTON_RESET_EN)
0156 reg |= MC13783_POWER_CONTROL_2_ON2BRSTEN;
0157
0158 err = mc13xxx_irq_request(mc13783, MC13783_IRQ_ONOFD2,
0159 button_irq, "b2on", priv);
0160 if (err) {
0161 dev_dbg(&pdev->dev, "Can't request irq\n");
0162 goto free_irq_b1;
0163 }
0164 }
0165
0166 if (pdata->b3on_flags & MC13783_BUTTON_ENABLE) {
0167 priv->keymap[2] = pdata->b3on_key;
0168 if (pdata->b3on_key != KEY_RESERVED)
0169 __set_bit(pdata->b3on_key, pwr->keybit);
0170
0171 if (pdata->b3on_flags & MC13783_BUTTON_POL_INVERT)
0172 priv->flags |= MC13783_PWRB_B3_POL_INVERT;
0173
0174 if (pdata->b3on_flags & MC13783_BUTTON_RESET_EN)
0175 reg |= MC13783_POWER_CONTROL_2_ON3BRSTEN;
0176
0177 err = mc13xxx_irq_request(mc13783, MC13783_IRQ_ONOFD3,
0178 button_irq, "b3on", priv);
0179 if (err) {
0180 dev_dbg(&pdev->dev, "Can't request irq: %d\n", err);
0181 goto free_irq_b2;
0182 }
0183 }
0184
0185 mc13xxx_reg_rmw(mc13783, MC13783_REG_POWER_CONTROL_2, 0x3FE, reg);
0186
0187 mc13xxx_unlock(mc13783);
0188
0189 pwr->name = "mc13783_pwrbutton";
0190 pwr->phys = "mc13783_pwrbutton/input0";
0191 pwr->dev.parent = &pdev->dev;
0192
0193 pwr->keycode = priv->keymap;
0194 pwr->keycodemax = ARRAY_SIZE(priv->keymap);
0195 pwr->keycodesize = sizeof(priv->keymap[0]);
0196 __set_bit(EV_KEY, pwr->evbit);
0197
0198 err = input_register_device(pwr);
0199 if (err) {
0200 dev_dbg(&pdev->dev, "Can't register power button: %d\n", err);
0201 goto free_irq;
0202 }
0203
0204 platform_set_drvdata(pdev, priv);
0205
0206 return 0;
0207
0208 free_irq:
0209 mc13xxx_lock(mc13783);
0210
0211 if (pdata->b3on_flags & MC13783_BUTTON_ENABLE)
0212 mc13xxx_irq_free(mc13783, MC13783_IRQ_ONOFD3, priv);
0213
0214 free_irq_b2:
0215 if (pdata->b2on_flags & MC13783_BUTTON_ENABLE)
0216 mc13xxx_irq_free(mc13783, MC13783_IRQ_ONOFD2, priv);
0217
0218 free_irq_b1:
0219 if (pdata->b1on_flags & MC13783_BUTTON_ENABLE)
0220 mc13xxx_irq_free(mc13783, MC13783_IRQ_ONOFD1, priv);
0221
0222 free_priv:
0223 mc13xxx_unlock(mc13783);
0224 kfree(priv);
0225
0226 free_input_dev:
0227 input_free_device(pwr);
0228
0229 return err;
0230 }
0231
0232 static int mc13783_pwrbutton_remove(struct platform_device *pdev)
0233 {
0234 struct mc13783_pwrb *priv = platform_get_drvdata(pdev);
0235 const struct mc13xxx_buttons_platform_data *pdata;
0236
0237 pdata = dev_get_platdata(&pdev->dev);
0238
0239 mc13xxx_lock(priv->mc13783);
0240
0241 if (pdata->b3on_flags & MC13783_BUTTON_ENABLE)
0242 mc13xxx_irq_free(priv->mc13783, MC13783_IRQ_ONOFD3, priv);
0243 if (pdata->b2on_flags & MC13783_BUTTON_ENABLE)
0244 mc13xxx_irq_free(priv->mc13783, MC13783_IRQ_ONOFD2, priv);
0245 if (pdata->b1on_flags & MC13783_BUTTON_ENABLE)
0246 mc13xxx_irq_free(priv->mc13783, MC13783_IRQ_ONOFD1, priv);
0247
0248 mc13xxx_unlock(priv->mc13783);
0249
0250 input_unregister_device(priv->pwr);
0251 kfree(priv);
0252
0253 return 0;
0254 }
0255
0256 static struct platform_driver mc13783_pwrbutton_driver = {
0257 .probe = mc13783_pwrbutton_probe,
0258 .remove = mc13783_pwrbutton_remove,
0259 .driver = {
0260 .name = "mc13783-pwrbutton",
0261 },
0262 };
0263
0264 module_platform_driver(mc13783_pwrbutton_driver);
0265
0266 MODULE_ALIAS("platform:mc13783-pwrbutton");
0267 MODULE_DESCRIPTION("MC13783 Power Button");
0268 MODULE_LICENSE("GPL v2");
0269 MODULE_AUTHOR("Philippe Retornaz");