root/drivers/input/touchscreen/imx6ul_tsc.c

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

DEFINITIONS

This source file includes following definitions.
  1. imx6ul_adc_init
  2. imx6ul_tsc_channel_config
  3. imx6ul_tsc_set
  4. imx6ul_tsc_init
  5. imx6ul_tsc_disable
  6. tsc_wait_detect_mode
  7. tsc_irq_fn
  8. adc_irq_fn
  9. imx6ul_tsc_open
  10. imx6ul_tsc_close
  11. imx6ul_tsc_probe
  12. imx6ul_tsc_suspend
  13. imx6ul_tsc_resume

   1 // SPDX-License-Identifier: GPL-2.0
   2 //
   3 // Freescale i.MX6UL touchscreen controller driver
   4 //
   5 // Copyright (C) 2015 Freescale Semiconductor, Inc.
   6 
   7 #include <linux/errno.h>
   8 #include <linux/kernel.h>
   9 #include <linux/module.h>
  10 #include <linux/gpio/consumer.h>
  11 #include <linux/input.h>
  12 #include <linux/slab.h>
  13 #include <linux/completion.h>
  14 #include <linux/delay.h>
  15 #include <linux/of.h>
  16 #include <linux/interrupt.h>
  17 #include <linux/platform_device.h>
  18 #include <linux/clk.h>
  19 #include <linux/io.h>
  20 #include <linux/log2.h>
  21 
  22 /* ADC configuration registers field define */
  23 #define ADC_AIEN                (0x1 << 7)
  24 #define ADC_CONV_DISABLE        0x1F
  25 #define ADC_AVGE                (0x1 << 5)
  26 #define ADC_CAL                 (0x1 << 7)
  27 #define ADC_CALF                0x2
  28 #define ADC_12BIT_MODE          (0x2 << 2)
  29 #define ADC_CONV_MODE_MASK      (0x3 << 2)
  30 #define ADC_IPG_CLK             0x00
  31 #define ADC_INPUT_CLK_MASK      0x3
  32 #define ADC_CLK_DIV_8           (0x03 << 5)
  33 #define ADC_CLK_DIV_MASK        (0x3 << 5)
  34 #define ADC_SHORT_SAMPLE_MODE   (0x0 << 4)
  35 #define ADC_SAMPLE_MODE_MASK    (0x1 << 4)
  36 #define ADC_HARDWARE_TRIGGER    (0x1 << 13)
  37 #define ADC_AVGS_SHIFT          14
  38 #define ADC_AVGS_MASK           (0x3 << 14)
  39 #define SELECT_CHANNEL_4        0x04
  40 #define SELECT_CHANNEL_1        0x01
  41 #define DISABLE_CONVERSION_INT  (0x0 << 7)
  42 
  43 /* ADC registers */
  44 #define REG_ADC_HC0             0x00
  45 #define REG_ADC_HC1             0x04
  46 #define REG_ADC_HC2             0x08
  47 #define REG_ADC_HC3             0x0C
  48 #define REG_ADC_HC4             0x10
  49 #define REG_ADC_HS              0x14
  50 #define REG_ADC_R0              0x18
  51 #define REG_ADC_CFG             0x2C
  52 #define REG_ADC_GC              0x30
  53 #define REG_ADC_GS              0x34
  54 
  55 #define ADC_TIMEOUT             msecs_to_jiffies(100)
  56 
  57 /* TSC registers */
  58 #define REG_TSC_BASIC_SETING    0x00
  59 #define REG_TSC_PRE_CHARGE_TIME 0x10
  60 #define REG_TSC_FLOW_CONTROL    0x20
  61 #define REG_TSC_MEASURE_VALUE   0x30
  62 #define REG_TSC_INT_EN          0x40
  63 #define REG_TSC_INT_SIG_EN      0x50
  64 #define REG_TSC_INT_STATUS      0x60
  65 #define REG_TSC_DEBUG_MODE      0x70
  66 #define REG_TSC_DEBUG_MODE2     0x80
  67 
  68 /* TSC configuration registers field define */
  69 #define DETECT_4_WIRE_MODE      (0x0 << 4)
  70 #define AUTO_MEASURE            0x1
  71 #define MEASURE_SIGNAL          0x1
  72 #define DETECT_SIGNAL           (0x1 << 4)
  73 #define VALID_SIGNAL            (0x1 << 8)
  74 #define MEASURE_INT_EN          0x1
  75 #define MEASURE_SIG_EN          0x1
  76 #define VALID_SIG_EN            (0x1 << 8)
  77 #define DE_GLITCH_2             (0x2 << 29)
  78 #define START_SENSE             (0x1 << 12)
  79 #define TSC_DISABLE             (0x1 << 16)
  80 #define DETECT_MODE             0x2
  81 
  82 struct imx6ul_tsc {
  83         struct device *dev;
  84         struct input_dev *input;
  85         void __iomem *tsc_regs;
  86         void __iomem *adc_regs;
  87         struct clk *tsc_clk;
  88         struct clk *adc_clk;
  89         struct gpio_desc *xnur_gpio;
  90 
  91         u32 measure_delay_time;
  92         u32 pre_charge_time;
  93         bool average_enable;
  94         u32 average_select;
  95 
  96         struct completion completion;
  97 };
  98 
  99 /*
 100  * TSC module need ADC to get the measure value. So
 101  * before config TSC, we should initialize ADC module.
 102  */
 103 static int imx6ul_adc_init(struct imx6ul_tsc *tsc)
 104 {
 105         u32 adc_hc = 0;
 106         u32 adc_gc;
 107         u32 adc_gs;
 108         u32 adc_cfg;
 109         unsigned long timeout;
 110 
 111         reinit_completion(&tsc->completion);
 112 
 113         adc_cfg = readl(tsc->adc_regs + REG_ADC_CFG);
 114         adc_cfg &= ~(ADC_CONV_MODE_MASK | ADC_INPUT_CLK_MASK);
 115         adc_cfg |= ADC_12BIT_MODE | ADC_IPG_CLK;
 116         adc_cfg &= ~(ADC_CLK_DIV_MASK | ADC_SAMPLE_MODE_MASK);
 117         adc_cfg |= ADC_CLK_DIV_8 | ADC_SHORT_SAMPLE_MODE;
 118         if (tsc->average_enable) {
 119                 adc_cfg &= ~ADC_AVGS_MASK;
 120                 adc_cfg |= (tsc->average_select) << ADC_AVGS_SHIFT;
 121         }
 122         adc_cfg &= ~ADC_HARDWARE_TRIGGER;
 123         writel(adc_cfg, tsc->adc_regs + REG_ADC_CFG);
 124 
 125         /* enable calibration interrupt */
 126         adc_hc |= ADC_AIEN;
 127         adc_hc |= ADC_CONV_DISABLE;
 128         writel(adc_hc, tsc->adc_regs + REG_ADC_HC0);
 129 
 130         /* start ADC calibration */
 131         adc_gc = readl(tsc->adc_regs + REG_ADC_GC);
 132         adc_gc |= ADC_CAL;
 133         if (tsc->average_enable)
 134                 adc_gc |= ADC_AVGE;
 135         writel(adc_gc, tsc->adc_regs + REG_ADC_GC);
 136 
 137         timeout = wait_for_completion_timeout
 138                         (&tsc->completion, ADC_TIMEOUT);
 139         if (timeout == 0) {
 140                 dev_err(tsc->dev, "Timeout for adc calibration\n");
 141                 return -ETIMEDOUT;
 142         }
 143 
 144         adc_gs = readl(tsc->adc_regs + REG_ADC_GS);
 145         if (adc_gs & ADC_CALF) {
 146                 dev_err(tsc->dev, "ADC calibration failed\n");
 147                 return -EINVAL;
 148         }
 149 
 150         /* TSC need the ADC work in hardware trigger */
 151         adc_cfg = readl(tsc->adc_regs + REG_ADC_CFG);
 152         adc_cfg |= ADC_HARDWARE_TRIGGER;
 153         writel(adc_cfg, tsc->adc_regs + REG_ADC_CFG);
 154 
 155         return 0;
 156 }
 157 
 158 /*
 159  * This is a TSC workaround. Currently TSC misconnect two
 160  * ADC channels, this function remap channel configure for
 161  * hardware trigger.
 162  */
 163 static void imx6ul_tsc_channel_config(struct imx6ul_tsc *tsc)
 164 {
 165         u32 adc_hc0, adc_hc1, adc_hc2, adc_hc3, adc_hc4;
 166 
 167         adc_hc0 = DISABLE_CONVERSION_INT;
 168         writel(adc_hc0, tsc->adc_regs + REG_ADC_HC0);
 169 
 170         adc_hc1 = DISABLE_CONVERSION_INT | SELECT_CHANNEL_4;
 171         writel(adc_hc1, tsc->adc_regs + REG_ADC_HC1);
 172 
 173         adc_hc2 = DISABLE_CONVERSION_INT;
 174         writel(adc_hc2, tsc->adc_regs + REG_ADC_HC2);
 175 
 176         adc_hc3 = DISABLE_CONVERSION_INT | SELECT_CHANNEL_1;
 177         writel(adc_hc3, tsc->adc_regs + REG_ADC_HC3);
 178 
 179         adc_hc4 = DISABLE_CONVERSION_INT;
 180         writel(adc_hc4, tsc->adc_regs + REG_ADC_HC4);
 181 }
 182 
 183 /*
 184  * TSC setting, confige the pre-charge time and measure delay time.
 185  * different touch screen may need different pre-charge time and
 186  * measure delay time.
 187  */
 188 static void imx6ul_tsc_set(struct imx6ul_tsc *tsc)
 189 {
 190         u32 basic_setting = 0;
 191         u32 start;
 192 
 193         basic_setting |= tsc->measure_delay_time << 8;
 194         basic_setting |= DETECT_4_WIRE_MODE | AUTO_MEASURE;
 195         writel(basic_setting, tsc->tsc_regs + REG_TSC_BASIC_SETING);
 196 
 197         writel(DE_GLITCH_2, tsc->tsc_regs + REG_TSC_DEBUG_MODE2);
 198 
 199         writel(tsc->pre_charge_time, tsc->tsc_regs + REG_TSC_PRE_CHARGE_TIME);
 200         writel(MEASURE_INT_EN, tsc->tsc_regs + REG_TSC_INT_EN);
 201         writel(MEASURE_SIG_EN | VALID_SIG_EN,
 202                 tsc->tsc_regs + REG_TSC_INT_SIG_EN);
 203 
 204         /* start sense detection */
 205         start = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
 206         start |= START_SENSE;
 207         start &= ~TSC_DISABLE;
 208         writel(start, tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
 209 }
 210 
 211 static int imx6ul_tsc_init(struct imx6ul_tsc *tsc)
 212 {
 213         int err;
 214 
 215         err = imx6ul_adc_init(tsc);
 216         if (err)
 217                 return err;
 218         imx6ul_tsc_channel_config(tsc);
 219         imx6ul_tsc_set(tsc);
 220 
 221         return 0;
 222 }
 223 
 224 static void imx6ul_tsc_disable(struct imx6ul_tsc *tsc)
 225 {
 226         u32 tsc_flow;
 227         u32 adc_cfg;
 228 
 229         /* TSC controller enters to idle status */
 230         tsc_flow = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
 231         tsc_flow |= TSC_DISABLE;
 232         writel(tsc_flow, tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
 233 
 234         /* ADC controller enters to stop mode */
 235         adc_cfg = readl(tsc->adc_regs + REG_ADC_HC0);
 236         adc_cfg |= ADC_CONV_DISABLE;
 237         writel(adc_cfg, tsc->adc_regs + REG_ADC_HC0);
 238 }
 239 
 240 /* Delay some time (max 2ms), wait the pre-charge done. */
 241 static bool tsc_wait_detect_mode(struct imx6ul_tsc *tsc)
 242 {
 243         unsigned long timeout = jiffies + msecs_to_jiffies(2);
 244         u32 state_machine;
 245         u32 debug_mode2;
 246 
 247         do {
 248                 if (time_after(jiffies, timeout))
 249                         return false;
 250 
 251                 usleep_range(200, 400);
 252                 debug_mode2 = readl(tsc->tsc_regs + REG_TSC_DEBUG_MODE2);
 253                 state_machine = (debug_mode2 >> 20) & 0x7;
 254         } while (state_machine != DETECT_MODE);
 255 
 256         usleep_range(200, 400);
 257         return true;
 258 }
 259 
 260 static irqreturn_t tsc_irq_fn(int irq, void *dev_id)
 261 {
 262         struct imx6ul_tsc *tsc = dev_id;
 263         u32 status;
 264         u32 value;
 265         u32 x, y;
 266         u32 start;
 267 
 268         status = readl(tsc->tsc_regs + REG_TSC_INT_STATUS);
 269 
 270         /* write 1 to clear the bit measure-signal */
 271         writel(MEASURE_SIGNAL | DETECT_SIGNAL,
 272                 tsc->tsc_regs + REG_TSC_INT_STATUS);
 273 
 274         /* It's a HW self-clean bit. Set this bit and start sense detection */
 275         start = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
 276         start |= START_SENSE;
 277         writel(start, tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
 278 
 279         if (status & MEASURE_SIGNAL) {
 280                 value = readl(tsc->tsc_regs + REG_TSC_MEASURE_VALUE);
 281                 x = (value >> 16) & 0x0fff;
 282                 y = value & 0x0fff;
 283 
 284                 /*
 285                  * In detect mode, we can get the xnur gpio value,
 286                  * otherwise assume contact is stiull active.
 287                  */
 288                 if (!tsc_wait_detect_mode(tsc) ||
 289                     gpiod_get_value_cansleep(tsc->xnur_gpio)) {
 290                         input_report_key(tsc->input, BTN_TOUCH, 1);
 291                         input_report_abs(tsc->input, ABS_X, x);
 292                         input_report_abs(tsc->input, ABS_Y, y);
 293                 } else {
 294                         input_report_key(tsc->input, BTN_TOUCH, 0);
 295                 }
 296 
 297                 input_sync(tsc->input);
 298         }
 299 
 300         return IRQ_HANDLED;
 301 }
 302 
 303 static irqreturn_t adc_irq_fn(int irq, void *dev_id)
 304 {
 305         struct imx6ul_tsc *tsc = dev_id;
 306         u32 coco;
 307         u32 value;
 308 
 309         coco = readl(tsc->adc_regs + REG_ADC_HS);
 310         if (coco & 0x01) {
 311                 value = readl(tsc->adc_regs + REG_ADC_R0);
 312                 complete(&tsc->completion);
 313         }
 314 
 315         return IRQ_HANDLED;
 316 }
 317 
 318 static int imx6ul_tsc_open(struct input_dev *input_dev)
 319 {
 320         struct imx6ul_tsc *tsc = input_get_drvdata(input_dev);
 321         int err;
 322 
 323         err = clk_prepare_enable(tsc->adc_clk);
 324         if (err) {
 325                 dev_err(tsc->dev,
 326                         "Could not prepare or enable the adc clock: %d\n",
 327                         err);
 328                 return err;
 329         }
 330 
 331         err = clk_prepare_enable(tsc->tsc_clk);
 332         if (err) {
 333                 dev_err(tsc->dev,
 334                         "Could not prepare or enable the tsc clock: %d\n",
 335                         err);
 336                 goto disable_adc_clk;
 337         }
 338 
 339         err = imx6ul_tsc_init(tsc);
 340         if (err)
 341                 goto disable_tsc_clk;
 342 
 343         return 0;
 344 
 345 disable_tsc_clk:
 346         clk_disable_unprepare(tsc->tsc_clk);
 347 disable_adc_clk:
 348         clk_disable_unprepare(tsc->adc_clk);
 349         return err;
 350 }
 351 
 352 static void imx6ul_tsc_close(struct input_dev *input_dev)
 353 {
 354         struct imx6ul_tsc *tsc = input_get_drvdata(input_dev);
 355 
 356         imx6ul_tsc_disable(tsc);
 357 
 358         clk_disable_unprepare(tsc->tsc_clk);
 359         clk_disable_unprepare(tsc->adc_clk);
 360 }
 361 
 362 static int imx6ul_tsc_probe(struct platform_device *pdev)
 363 {
 364         struct device_node *np = pdev->dev.of_node;
 365         struct imx6ul_tsc *tsc;
 366         struct input_dev *input_dev;
 367         int err;
 368         int tsc_irq;
 369         int adc_irq;
 370         u32 average_samples;
 371 
 372         tsc = devm_kzalloc(&pdev->dev, sizeof(*tsc), GFP_KERNEL);
 373         if (!tsc)
 374                 return -ENOMEM;
 375 
 376         input_dev = devm_input_allocate_device(&pdev->dev);
 377         if (!input_dev)
 378                 return -ENOMEM;
 379 
 380         input_dev->name = "iMX6UL Touchscreen Controller";
 381         input_dev->id.bustype = BUS_HOST;
 382 
 383         input_dev->open = imx6ul_tsc_open;
 384         input_dev->close = imx6ul_tsc_close;
 385 
 386         input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
 387         input_set_abs_params(input_dev, ABS_X, 0, 0xFFF, 0, 0);
 388         input_set_abs_params(input_dev, ABS_Y, 0, 0xFFF, 0, 0);
 389 
 390         input_set_drvdata(input_dev, tsc);
 391 
 392         tsc->dev = &pdev->dev;
 393         tsc->input = input_dev;
 394         init_completion(&tsc->completion);
 395 
 396         tsc->xnur_gpio = devm_gpiod_get(&pdev->dev, "xnur", GPIOD_IN);
 397         if (IS_ERR(tsc->xnur_gpio)) {
 398                 err = PTR_ERR(tsc->xnur_gpio);
 399                 dev_err(&pdev->dev,
 400                         "failed to request GPIO tsc_X- (xnur): %d\n", err);
 401                 return err;
 402         }
 403 
 404         tsc->tsc_regs = devm_platform_ioremap_resource(pdev, 0);
 405         if (IS_ERR(tsc->tsc_regs)) {
 406                 err = PTR_ERR(tsc->tsc_regs);
 407                 dev_err(&pdev->dev, "failed to remap tsc memory: %d\n", err);
 408                 return err;
 409         }
 410 
 411         tsc->adc_regs = devm_platform_ioremap_resource(pdev, 1);
 412         if (IS_ERR(tsc->adc_regs)) {
 413                 err = PTR_ERR(tsc->adc_regs);
 414                 dev_err(&pdev->dev, "failed to remap adc memory: %d\n", err);
 415                 return err;
 416         }
 417 
 418         tsc->tsc_clk = devm_clk_get(&pdev->dev, "tsc");
 419         if (IS_ERR(tsc->tsc_clk)) {
 420                 err = PTR_ERR(tsc->tsc_clk);
 421                 dev_err(&pdev->dev, "failed getting tsc clock: %d\n", err);
 422                 return err;
 423         }
 424 
 425         tsc->adc_clk = devm_clk_get(&pdev->dev, "adc");
 426         if (IS_ERR(tsc->adc_clk)) {
 427                 err = PTR_ERR(tsc->adc_clk);
 428                 dev_err(&pdev->dev, "failed getting adc clock: %d\n", err);
 429                 return err;
 430         }
 431 
 432         tsc_irq = platform_get_irq(pdev, 0);
 433         if (tsc_irq < 0)
 434                 return tsc_irq;
 435 
 436         adc_irq = platform_get_irq(pdev, 1);
 437         if (adc_irq < 0)
 438                 return adc_irq;
 439 
 440         err = devm_request_threaded_irq(tsc->dev, tsc_irq,
 441                                         NULL, tsc_irq_fn, IRQF_ONESHOT,
 442                                         dev_name(&pdev->dev), tsc);
 443         if (err) {
 444                 dev_err(&pdev->dev,
 445                         "failed requesting tsc irq %d: %d\n",
 446                         tsc_irq, err);
 447                 return err;
 448         }
 449 
 450         err = devm_request_irq(tsc->dev, adc_irq, adc_irq_fn, 0,
 451                                 dev_name(&pdev->dev), tsc);
 452         if (err) {
 453                 dev_err(&pdev->dev,
 454                         "failed requesting adc irq %d: %d\n",
 455                         adc_irq, err);
 456                 return err;
 457         }
 458 
 459         err = of_property_read_u32(np, "measure-delay-time",
 460                                    &tsc->measure_delay_time);
 461         if (err)
 462                 tsc->measure_delay_time = 0xffff;
 463 
 464         err = of_property_read_u32(np, "pre-charge-time",
 465                                    &tsc->pre_charge_time);
 466         if (err)
 467                 tsc->pre_charge_time = 0xfff;
 468 
 469         err = of_property_read_u32(np, "touchscreen-average-samples",
 470                                    &average_samples);
 471         if (err)
 472                 average_samples = 1;
 473 
 474         switch (average_samples) {
 475         case 1:
 476                 tsc->average_enable = false;
 477                 tsc->average_select = 0; /* value unused; initialize anyway */
 478                 break;
 479         case 4:
 480         case 8:
 481         case 16:
 482         case 32:
 483                 tsc->average_enable = true;
 484                 tsc->average_select = ilog2(average_samples) - 2;
 485                 break;
 486         default:
 487                 dev_err(&pdev->dev,
 488                         "touchscreen-average-samples (%u) must be 1, 4, 8, 16 or 32\n",
 489                         average_samples);
 490                 return -EINVAL;
 491         }
 492 
 493         err = input_register_device(tsc->input);
 494         if (err) {
 495                 dev_err(&pdev->dev,
 496                         "failed to register input device: %d\n", err);
 497                 return err;
 498         }
 499 
 500         platform_set_drvdata(pdev, tsc);
 501         return 0;
 502 }
 503 
 504 static int __maybe_unused imx6ul_tsc_suspend(struct device *dev)
 505 {
 506         struct platform_device *pdev = to_platform_device(dev);
 507         struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
 508         struct input_dev *input_dev = tsc->input;
 509 
 510         mutex_lock(&input_dev->mutex);
 511 
 512         if (input_dev->users) {
 513                 imx6ul_tsc_disable(tsc);
 514 
 515                 clk_disable_unprepare(tsc->tsc_clk);
 516                 clk_disable_unprepare(tsc->adc_clk);
 517         }
 518 
 519         mutex_unlock(&input_dev->mutex);
 520 
 521         return 0;
 522 }
 523 
 524 static int __maybe_unused imx6ul_tsc_resume(struct device *dev)
 525 {
 526         struct platform_device *pdev = to_platform_device(dev);
 527         struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
 528         struct input_dev *input_dev = tsc->input;
 529         int retval = 0;
 530 
 531         mutex_lock(&input_dev->mutex);
 532 
 533         if (input_dev->users) {
 534                 retval = clk_prepare_enable(tsc->adc_clk);
 535                 if (retval)
 536                         goto out;
 537 
 538                 retval = clk_prepare_enable(tsc->tsc_clk);
 539                 if (retval) {
 540                         clk_disable_unprepare(tsc->adc_clk);
 541                         goto out;
 542                 }
 543 
 544                 retval = imx6ul_tsc_init(tsc);
 545         }
 546 
 547 out:
 548         mutex_unlock(&input_dev->mutex);
 549         return retval;
 550 }
 551 
 552 static SIMPLE_DEV_PM_OPS(imx6ul_tsc_pm_ops,
 553                          imx6ul_tsc_suspend, imx6ul_tsc_resume);
 554 
 555 static const struct of_device_id imx6ul_tsc_match[] = {
 556         { .compatible = "fsl,imx6ul-tsc", },
 557         { /* sentinel */ }
 558 };
 559 MODULE_DEVICE_TABLE(of, imx6ul_tsc_match);
 560 
 561 static struct platform_driver imx6ul_tsc_driver = {
 562         .driver         = {
 563                 .name   = "imx6ul-tsc",
 564                 .of_match_table = imx6ul_tsc_match,
 565                 .pm     = &imx6ul_tsc_pm_ops,
 566         },
 567         .probe          = imx6ul_tsc_probe,
 568 };
 569 module_platform_driver(imx6ul_tsc_driver);
 570 
 571 MODULE_AUTHOR("Haibo Chen <haibo.chen@freescale.com>");
 572 MODULE_DESCRIPTION("Freescale i.MX6UL Touchscreen controller driver");
 573 MODULE_LICENSE("GPL v2");

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