1 /* 2 * Driver for AT91/AT32 MULTI LAYER LCD Controller 3 * 4 * Copyright (C) 2012 Atmel Corporation 5 * 6 * SPDX-License-Identifier: GPL-2.0+ 7 */ 8 9 #include <common.h> 10 #include <asm/io.h> 11 #include <asm/arch/gpio.h> 12 #include <asm/arch/clk.h> 13 #include <clk.h> 14 #include <dm.h> 15 #include <fdtdec.h> 16 #include <lcd.h> 17 #include <video.h> 18 #include <wait_bit.h> 19 #include <atmel_hlcdc.h> 20 21 #if defined(CONFIG_LCD_LOGO) 22 #include <bmp_logo.h> 23 #endif 24 25 DECLARE_GLOBAL_DATA_PTR; 26 27 #ifndef CONFIG_DM_VIDEO 28 29 /* configurable parameters */ 30 #define ATMEL_LCDC_CVAL_DEFAULT 0xc8 31 #define ATMEL_LCDC_DMA_BURST_LEN 8 32 #ifndef ATMEL_LCDC_GUARD_TIME 33 #define ATMEL_LCDC_GUARD_TIME 1 34 #endif 35 36 #define ATMEL_LCDC_FIFO_SIZE 512 37 38 /* 39 * the CLUT register map as following 40 * RCLUT(24 ~ 16), GCLUT(15 ~ 8), BCLUT(7 ~ 0) 41 */ 42 void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue) 43 { 44 writel(panel_info.mmio + ATMEL_LCDC_LUT(regno), 45 ((red << LCDC_BASECLUT_RCLUT_Pos) & LCDC_BASECLUT_RCLUT_Msk) 46 | ((green << LCDC_BASECLUT_GCLUT_Pos) & LCDC_BASECLUT_GCLUT_Msk) 47 | ((blue << LCDC_BASECLUT_BCLUT_Pos) & LCDC_BASECLUT_BCLUT_Msk)); 48 } 49 50 ushort *configuration_get_cmap(void) 51 { 52 #if defined(CONFIG_LCD_LOGO) 53 return bmp_logo_palette; 54 #else 55 return NULL; 56 #endif 57 } 58 59 void lcd_ctrl_init(void *lcdbase) 60 { 61 unsigned long value; 62 struct lcd_dma_desc *desc; 63 struct atmel_hlcd_regs *regs; 64 int ret; 65 66 if (!has_lcdc()) 67 return; /* No lcdc */ 68 69 regs = (struct atmel_hlcd_regs *)panel_info.mmio; 70 71 /* Disable DISP signal */ 72 writel(LCDC_LCDDIS_DISPDIS, ®s->lcdc_lcddis); 73 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS, 74 false, 1000, false); 75 if (ret) 76 printf("%s: %d: Timeout!\n", __func__, __LINE__); 77 /* Disable synchronization */ 78 writel(LCDC_LCDDIS_SYNCDIS, ®s->lcdc_lcddis); 79 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS, 80 false, 1000, false); 81 if (ret) 82 printf("%s: %d: Timeout!\n", __func__, __LINE__); 83 /* Disable pixel clock */ 84 writel(LCDC_LCDDIS_CLKDIS, ®s->lcdc_lcddis); 85 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS, 86 false, 1000, false); 87 if (ret) 88 printf("%s: %d: Timeout!\n", __func__, __LINE__); 89 /* Disable PWM */ 90 writel(LCDC_LCDDIS_PWMDIS, ®s->lcdc_lcddis); 91 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS, 92 false, 1000, false); 93 if (ret) 94 printf("%s: %d: Timeout!\n", __func__, __LINE__); 95 96 /* Set pixel clock */ 97 value = get_lcdc_clk_rate(0) / panel_info.vl_clk; 98 if (get_lcdc_clk_rate(0) % panel_info.vl_clk) 99 value++; 100 101 if (value < 1) { 102 /* Using system clock as pixel clock */ 103 writel(LCDC_LCDCFG0_CLKDIV(0) 104 | LCDC_LCDCFG0_CGDISHCR 105 | LCDC_LCDCFG0_CGDISHEO 106 | LCDC_LCDCFG0_CGDISOVR1 107 | LCDC_LCDCFG0_CGDISBASE 108 | panel_info.vl_clk_pol 109 | LCDC_LCDCFG0_CLKSEL, 110 ®s->lcdc_lcdcfg0); 111 112 } else { 113 writel(LCDC_LCDCFG0_CLKDIV(value - 2) 114 | LCDC_LCDCFG0_CGDISHCR 115 | LCDC_LCDCFG0_CGDISHEO 116 | LCDC_LCDCFG0_CGDISOVR1 117 | LCDC_LCDCFG0_CGDISBASE 118 | panel_info.vl_clk_pol, 119 ®s->lcdc_lcdcfg0); 120 } 121 122 /* Initialize control register 5 */ 123 value = 0; 124 125 value |= panel_info.vl_sync; 126 127 #ifndef LCD_OUTPUT_BPP 128 /* Output is 24bpp */ 129 value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP; 130 #else 131 switch (LCD_OUTPUT_BPP) { 132 case 12: 133 value |= LCDC_LCDCFG5_MODE_OUTPUT_12BPP; 134 break; 135 case 16: 136 value |= LCDC_LCDCFG5_MODE_OUTPUT_16BPP; 137 break; 138 case 18: 139 value |= LCDC_LCDCFG5_MODE_OUTPUT_18BPP; 140 break; 141 case 24: 142 value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP; 143 break; 144 default: 145 BUG(); 146 break; 147 } 148 #endif 149 150 value |= LCDC_LCDCFG5_GUARDTIME(ATMEL_LCDC_GUARD_TIME); 151 value |= (LCDC_LCDCFG5_DISPDLY | LCDC_LCDCFG5_VSPDLYS); 152 writel(value, ®s->lcdc_lcdcfg5); 153 154 /* Vertical & Horizontal Timing */ 155 value = LCDC_LCDCFG1_VSPW(panel_info.vl_vsync_len - 1); 156 value |= LCDC_LCDCFG1_HSPW(panel_info.vl_hsync_len - 1); 157 writel(value, ®s->lcdc_lcdcfg1); 158 159 value = LCDC_LCDCFG2_VBPW(panel_info.vl_upper_margin); 160 value |= LCDC_LCDCFG2_VFPW(panel_info.vl_lower_margin - 1); 161 writel(value, ®s->lcdc_lcdcfg2); 162 163 value = LCDC_LCDCFG3_HBPW(panel_info.vl_left_margin - 1); 164 value |= LCDC_LCDCFG3_HFPW(panel_info.vl_right_margin - 1); 165 writel(value, ®s->lcdc_lcdcfg3); 166 167 /* Display size */ 168 value = LCDC_LCDCFG4_RPF(panel_info.vl_row - 1); 169 value |= LCDC_LCDCFG4_PPL(panel_info.vl_col - 1); 170 writel(value, ®s->lcdc_lcdcfg4); 171 172 writel(LCDC_BASECFG0_BLEN_AHB_INCR4 | LCDC_BASECFG0_DLBO, 173 ®s->lcdc_basecfg0); 174 175 switch (NBITS(panel_info.vl_bpix)) { 176 case 16: 177 writel(LCDC_BASECFG1_RGBMODE_16BPP_RGB_565, 178 ®s->lcdc_basecfg1); 179 break; 180 case 32: 181 writel(LCDC_BASECFG1_RGBMODE_24BPP_RGB_888, 182 ®s->lcdc_basecfg1); 183 break; 184 default: 185 BUG(); 186 break; 187 } 188 189 writel(LCDC_BASECFG2_XSTRIDE(0), ®s->lcdc_basecfg2); 190 writel(0, ®s->lcdc_basecfg3); 191 writel(LCDC_BASECFG4_DMA, ®s->lcdc_basecfg4); 192 193 /* Disable all interrupts */ 194 writel(~0UL, ®s->lcdc_lcdidr); 195 writel(~0UL, ®s->lcdc_baseidr); 196 197 /* Setup the DMA descriptor, this descriptor will loop to itself */ 198 desc = (struct lcd_dma_desc *)(lcdbase - 16); 199 200 desc->address = (u32)lcdbase; 201 /* Disable DMA transfer interrupt & descriptor loaded interrupt. */ 202 desc->control = LCDC_BASECTRL_ADDIEN | LCDC_BASECTRL_DSCRIEN 203 | LCDC_BASECTRL_DMAIEN | LCDC_BASECTRL_DFETCH; 204 desc->next = (u32)desc; 205 206 /* Flush the DMA descriptor if we enabled dcache */ 207 flush_dcache_range((u32)desc, (u32)desc + sizeof(*desc)); 208 209 writel(desc->address, ®s->lcdc_baseaddr); 210 writel(desc->control, ®s->lcdc_basectrl); 211 writel(desc->next, ®s->lcdc_basenext); 212 writel(LCDC_BASECHER_CHEN | LCDC_BASECHER_UPDATEEN, 213 ®s->lcdc_basecher); 214 215 /* Enable LCD */ 216 value = readl(®s->lcdc_lcden); 217 writel(value | LCDC_LCDEN_CLKEN, ®s->lcdc_lcden); 218 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS, 219 true, 1000, false); 220 if (ret) 221 printf("%s: %d: Timeout!\n", __func__, __LINE__); 222 value = readl(®s->lcdc_lcden); 223 writel(value | LCDC_LCDEN_SYNCEN, ®s->lcdc_lcden); 224 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS, 225 true, 1000, false); 226 if (ret) 227 printf("%s: %d: Timeout!\n", __func__, __LINE__); 228 value = readl(®s->lcdc_lcden); 229 writel(value | LCDC_LCDEN_DISPEN, ®s->lcdc_lcden); 230 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS, 231 true, 1000, false); 232 if (ret) 233 printf("%s: %d: Timeout!\n", __func__, __LINE__); 234 value = readl(®s->lcdc_lcden); 235 writel(value | LCDC_LCDEN_PWMEN, ®s->lcdc_lcden); 236 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS, 237 true, 1000, false); 238 if (ret) 239 printf("%s: %d: Timeout!\n", __func__, __LINE__); 240 241 /* Enable flushing if we enabled dcache */ 242 lcd_set_flush_dcache(1); 243 } 244 245 #else 246 247 enum { 248 LCD_MAX_WIDTH = 1024, 249 LCD_MAX_HEIGHT = 768, 250 LCD_MAX_LOG2_BPP = VIDEO_BPP16, 251 }; 252 253 struct atmel_hlcdc_priv { 254 struct atmel_hlcd_regs *regs; 255 struct display_timing timing; 256 unsigned int vl_bpix; 257 unsigned int output_mode; 258 unsigned int guard_time; 259 ulong clk_rate; 260 }; 261 262 static int at91_hlcdc_enable_clk(struct udevice *dev) 263 { 264 struct atmel_hlcdc_priv *priv = dev_get_priv(dev); 265 struct clk clk; 266 ulong clk_rate; 267 int ret; 268 269 ret = clk_get_by_index(dev, 0, &clk); 270 if (ret) 271 return -EINVAL; 272 273 ret = clk_enable(&clk); 274 if (ret) 275 return ret; 276 277 clk_rate = clk_get_rate(&clk); 278 if (!clk_rate) { 279 clk_disable(&clk); 280 return -ENODEV; 281 } 282 283 priv->clk_rate = clk_rate; 284 285 clk_free(&clk); 286 287 return 0; 288 } 289 290 static void atmel_hlcdc_init(struct udevice *dev) 291 { 292 struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev); 293 struct atmel_hlcdc_priv *priv = dev_get_priv(dev); 294 struct atmel_hlcd_regs *regs = priv->regs; 295 struct display_timing *timing = &priv->timing; 296 struct lcd_dma_desc *desc; 297 unsigned long value, vl_clk_pol; 298 int ret; 299 300 /* Disable DISP signal */ 301 writel(LCDC_LCDDIS_DISPDIS, ®s->lcdc_lcddis); 302 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS, 303 false, 1000, false); 304 if (ret) 305 printf("%s: %d: Timeout!\n", __func__, __LINE__); 306 /* Disable synchronization */ 307 writel(LCDC_LCDDIS_SYNCDIS, ®s->lcdc_lcddis); 308 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS, 309 false, 1000, false); 310 if (ret) 311 printf("%s: %d: Timeout!\n", __func__, __LINE__); 312 /* Disable pixel clock */ 313 writel(LCDC_LCDDIS_CLKDIS, ®s->lcdc_lcddis); 314 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS, 315 false, 1000, false); 316 if (ret) 317 printf("%s: %d: Timeout!\n", __func__, __LINE__); 318 /* Disable PWM */ 319 writel(LCDC_LCDDIS_PWMDIS, ®s->lcdc_lcddis); 320 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS, 321 false, 1000, false); 322 if (ret) 323 printf("%s: %d: Timeout!\n", __func__, __LINE__); 324 325 /* Set pixel clock */ 326 value = priv->clk_rate / timing->pixelclock.typ; 327 if (priv->clk_rate % timing->pixelclock.typ) 328 value++; 329 330 vl_clk_pol = 0; 331 if (timing->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) 332 vl_clk_pol = LCDC_LCDCFG0_CLKPOL; 333 334 if (value < 1) { 335 /* Using system clock as pixel clock */ 336 writel(LCDC_LCDCFG0_CLKDIV(0) 337 | LCDC_LCDCFG0_CGDISHCR 338 | LCDC_LCDCFG0_CGDISHEO 339 | LCDC_LCDCFG0_CGDISOVR1 340 | LCDC_LCDCFG0_CGDISBASE 341 | vl_clk_pol 342 | LCDC_LCDCFG0_CLKSEL, 343 ®s->lcdc_lcdcfg0); 344 345 } else { 346 writel(LCDC_LCDCFG0_CLKDIV(value - 2) 347 | LCDC_LCDCFG0_CGDISHCR 348 | LCDC_LCDCFG0_CGDISHEO 349 | LCDC_LCDCFG0_CGDISOVR1 350 | LCDC_LCDCFG0_CGDISBASE 351 | vl_clk_pol, 352 ®s->lcdc_lcdcfg0); 353 } 354 355 /* Initialize control register 5 */ 356 value = 0; 357 358 if (!(timing->flags & DISPLAY_FLAGS_HSYNC_HIGH)) 359 value |= LCDC_LCDCFG5_HSPOL; 360 if (!(timing->flags & DISPLAY_FLAGS_VSYNC_HIGH)) 361 value |= LCDC_LCDCFG5_VSPOL; 362 363 switch (priv->output_mode) { 364 case 12: 365 value |= LCDC_LCDCFG5_MODE_OUTPUT_12BPP; 366 break; 367 case 16: 368 value |= LCDC_LCDCFG5_MODE_OUTPUT_16BPP; 369 break; 370 case 18: 371 value |= LCDC_LCDCFG5_MODE_OUTPUT_18BPP; 372 break; 373 case 24: 374 value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP; 375 break; 376 default: 377 BUG(); 378 break; 379 } 380 381 value |= LCDC_LCDCFG5_GUARDTIME(priv->guard_time); 382 value |= (LCDC_LCDCFG5_DISPDLY | LCDC_LCDCFG5_VSPDLYS); 383 writel(value, ®s->lcdc_lcdcfg5); 384 385 /* Vertical & Horizontal Timing */ 386 value = LCDC_LCDCFG1_VSPW(timing->vsync_len.typ - 1); 387 value |= LCDC_LCDCFG1_HSPW(timing->hsync_len.typ - 1); 388 writel(value, ®s->lcdc_lcdcfg1); 389 390 value = LCDC_LCDCFG2_VBPW(timing->vback_porch.typ); 391 value |= LCDC_LCDCFG2_VFPW(timing->vfront_porch.typ - 1); 392 writel(value, ®s->lcdc_lcdcfg2); 393 394 value = LCDC_LCDCFG3_HBPW(timing->hback_porch.typ - 1); 395 value |= LCDC_LCDCFG3_HFPW(timing->hfront_porch.typ - 1); 396 writel(value, ®s->lcdc_lcdcfg3); 397 398 /* Display size */ 399 value = LCDC_LCDCFG4_RPF(timing->vactive.typ - 1); 400 value |= LCDC_LCDCFG4_PPL(timing->hactive.typ - 1); 401 writel(value, ®s->lcdc_lcdcfg4); 402 403 writel(LCDC_BASECFG0_BLEN_AHB_INCR4 | LCDC_BASECFG0_DLBO, 404 ®s->lcdc_basecfg0); 405 406 switch (VNBITS(priv->vl_bpix)) { 407 case 16: 408 writel(LCDC_BASECFG1_RGBMODE_16BPP_RGB_565, 409 ®s->lcdc_basecfg1); 410 break; 411 case 32: 412 writel(LCDC_BASECFG1_RGBMODE_24BPP_RGB_888, 413 ®s->lcdc_basecfg1); 414 break; 415 default: 416 BUG(); 417 break; 418 } 419 420 writel(LCDC_BASECFG2_XSTRIDE(0), ®s->lcdc_basecfg2); 421 writel(0, ®s->lcdc_basecfg3); 422 writel(LCDC_BASECFG4_DMA, ®s->lcdc_basecfg4); 423 424 /* Disable all interrupts */ 425 writel(~0UL, ®s->lcdc_lcdidr); 426 writel(~0UL, ®s->lcdc_baseidr); 427 428 /* Setup the DMA descriptor, this descriptor will loop to itself */ 429 desc = (struct lcd_dma_desc *)(uc_plat->base - 16); 430 431 desc->address = (u32)uc_plat->base; 432 433 /* Disable DMA transfer interrupt & descriptor loaded interrupt. */ 434 desc->control = LCDC_BASECTRL_ADDIEN | LCDC_BASECTRL_DSCRIEN 435 | LCDC_BASECTRL_DMAIEN | LCDC_BASECTRL_DFETCH; 436 desc->next = (u32)desc; 437 438 /* Flush the DMA descriptor if we enabled dcache */ 439 flush_dcache_range((u32)desc, (u32)desc + sizeof(*desc)); 440 441 writel(desc->address, ®s->lcdc_baseaddr); 442 writel(desc->control, ®s->lcdc_basectrl); 443 writel(desc->next, ®s->lcdc_basenext); 444 writel(LCDC_BASECHER_CHEN | LCDC_BASECHER_UPDATEEN, 445 ®s->lcdc_basecher); 446 447 /* Enable LCD */ 448 value = readl(®s->lcdc_lcden); 449 writel(value | LCDC_LCDEN_CLKEN, ®s->lcdc_lcden); 450 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS, 451 true, 1000, false); 452 if (ret) 453 printf("%s: %d: Timeout!\n", __func__, __LINE__); 454 value = readl(®s->lcdc_lcden); 455 writel(value | LCDC_LCDEN_SYNCEN, ®s->lcdc_lcden); 456 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS, 457 true, 1000, false); 458 if (ret) 459 printf("%s: %d: Timeout!\n", __func__, __LINE__); 460 value = readl(®s->lcdc_lcden); 461 writel(value | LCDC_LCDEN_DISPEN, ®s->lcdc_lcden); 462 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS, 463 true, 1000, false); 464 if (ret) 465 printf("%s: %d: Timeout!\n", __func__, __LINE__); 466 value = readl(®s->lcdc_lcden); 467 writel(value | LCDC_LCDEN_PWMEN, ®s->lcdc_lcden); 468 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS, 469 true, 1000, false); 470 if (ret) 471 printf("%s: %d: Timeout!\n", __func__, __LINE__); 472 } 473 474 static int atmel_hlcdc_probe(struct udevice *dev) 475 { 476 struct video_priv *uc_priv = dev_get_uclass_priv(dev); 477 struct atmel_hlcdc_priv *priv = dev_get_priv(dev); 478 int ret; 479 480 ret = at91_hlcdc_enable_clk(dev); 481 if (ret) 482 return ret; 483 484 atmel_hlcdc_init(dev); 485 486 uc_priv->xsize = priv->timing.hactive.typ; 487 uc_priv->ysize = priv->timing.vactive.typ; 488 uc_priv->bpix = priv->vl_bpix; 489 490 /* Enable flushing if we enabled dcache */ 491 video_set_flush_dcache(dev, true); 492 493 return 0; 494 } 495 496 static int atmel_hlcdc_ofdata_to_platdata(struct udevice *dev) 497 { 498 struct atmel_hlcdc_priv *priv = dev_get_priv(dev); 499 const void *blob = gd->fdt_blob; 500 int node = dev->of_offset; 501 502 priv->regs = (struct atmel_hlcd_regs *)dev_get_addr(dev); 503 if (!priv->regs) { 504 debug("%s: No display controller address\n", __func__); 505 return -EINVAL; 506 } 507 508 if (fdtdec_decode_display_timing(blob, dev->of_offset, 509 0, &priv->timing)) { 510 debug("%s: Failed to decode display timing\n", __func__); 511 return -EINVAL; 512 } 513 514 if (priv->timing.hactive.typ > LCD_MAX_WIDTH) 515 priv->timing.hactive.typ = LCD_MAX_WIDTH; 516 517 if (priv->timing.vactive.typ > LCD_MAX_HEIGHT) 518 priv->timing.vactive.typ = LCD_MAX_HEIGHT; 519 520 priv->vl_bpix = fdtdec_get_int(blob, node, "atmel,vl-bpix", 0); 521 if (!priv->vl_bpix) { 522 debug("%s: Failed to get bits per pixel\n", __func__); 523 return -EINVAL; 524 } 525 526 priv->output_mode = fdtdec_get_int(blob, node, "atmel,output-mode", 24); 527 priv->guard_time = fdtdec_get_int(blob, node, "atmel,guard-time", 1); 528 529 return 0; 530 } 531 532 static int atmel_hlcdc_bind(struct udevice *dev) 533 { 534 struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev); 535 536 uc_plat->size = LCD_MAX_WIDTH * LCD_MAX_HEIGHT * 537 (1 << LCD_MAX_LOG2_BPP) / 8; 538 539 debug("%s: Frame buffer size %x\n", __func__, uc_plat->size); 540 541 return 0; 542 } 543 544 static const struct udevice_id atmel_hlcdc_ids[] = { 545 { .compatible = "atmel,sama5d2-hlcdc" }, 546 { .compatible = "atmel,at91sam9x5-hlcdc" }, 547 { } 548 }; 549 550 U_BOOT_DRIVER(atmel_hlcdfb) = { 551 .name = "atmel_hlcdfb", 552 .id = UCLASS_VIDEO, 553 .of_match = atmel_hlcdc_ids, 554 .bind = atmel_hlcdc_bind, 555 .probe = atmel_hlcdc_probe, 556 .ofdata_to_platdata = atmel_hlcdc_ofdata_to_platdata, 557 .priv_auto_alloc_size = sizeof(struct atmel_hlcdc_priv), 558 }; 559 560 #endif 561